![]() |
Внимание, важное сообщение: Дорогие Друзья!
В ноябре далекого 2001 года мы решили создать сайт и форум, которые смогут помочь как начинающим, так и продвинутым пользователям разобраться в операционных системах. В 2004-2006г наш проект был одним из самых крупных ИТ ресурсов в рунете, на пике нас посещало более 300 000 человек в день! Наша документация по службам Windows и автоматической установке помогла огромному количеству пользователей и сисадминов. Мы с уверенностью можем сказать, что внесли большой вклад в развитие ИТ сообщества рунета. Но... время меняются, приоритеты тоже. И, к сожалению, пришло время сказать До встречи! После долгих дискуссий было принято решение закрыть наш проект. 1 августа форум переводится в режим Только чтение, а в начале сентября мы переведем рубильник в положение Выключен Огромное спасибо за эти 24 года, это было незабываемое приключение. Сказать спасибо и поделиться своей историей можно в данной теме. С уважением, ваш призрачный админ, BigMac... |
|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Задача на графы |
|
C/C++ - Задача на графы
|
Пользователь Сообщения: 64 |
Доброго времени суток, ув. форумчане! С ровного места возникла проблема: препод дал задачу, но по такому материалу что ещё не проходили, сказал если до воскресения не сделаем- завалит.
Знаю только что нужно делать на графах и алгоритме Левита (или дейкстры), но ни того ни другого не проходили, тоесть знаний по этому у меня покачто ноль. Обьясните пожалуйста как это реализовать. Условие: Примеры входящих и исходящих данных: |
|
Отправлено: 18:45, 16-11-2012 |
Пользователь Сообщения: 107
|
Вот алгоритм дейкстры на C#, вроде работал, давно писал. Может пригодится. Насколько я помню, он позволяет найти наиболее "лёгкий" путь между узлами графа (в графе каждое ребро имеет свой "вес").
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace algorithmDijkstra { public class Peak : IComparable<Peak> // вершина { public int Number { get; set; } // номер public bool Mark { get; set; } // была ли посещена public int Weight { get; set; } // вес public List<Peak> shortPath { get; set; } // вроде кратчайший путь до этой вершины от стартовой public Peak(int n, bool m = false) // конструктор { Number = n; Mark = m; Weight = int.MaxValue; // по умолчанию ставим вес = большое число shortPath = new List<Peak>(); } int IComparable<Peak>.CompareTo(Peak obj) // сравнение номеров вершин { if (this.Number > obj.Number) return 1; if (this.Number < obj.Number) return -1; return 0; } } public class Edge // ребро { public Peak StartPeak { get; set; } public Peak EndPeak { get; set; } public int Weight { get; set; } public Edge() { } public Edge(Peak start, Peak end, int w) { this.StartPeak = start; this.EndPeak = end; this.Weight = w; } } public class Algorithm { List<Peak> lPeak { get; set; } // список вершин List<Edge> lEdge { get; set; } // список ребер Queue<Peak> queue = new Queue<Peak>(); // очередь вершин public Algorithm(List<Peak> listPeak, List<Edge> listEdge) { lPeak = listPeak; lEdge = listEdge; } private void ProcessingCurrentPeak(Peak currPeak) //обработка вершины { currPeak.Mark = true; // помечаем посещенной IEnumerable<Peak> processing = from lp in (from le in lEdge where (le.StartPeak == currPeak || le.EndPeak == currPeak) select le.StartPeak == currPeak ? le.EndPeak : le.StartPeak).ToList<Peak>() where lp.Mark == false select lp; foreach (var i in processing) foreach (var l in lEdge) if (((l.StartPeak == i && l.EndPeak == currPeak) || (l.StartPeak == currPeak && l.EndPeak == i)) && i.Weight > currPeak.Weight + l.Weight) { i.Weight = currPeak.Weight + l.Weight; i.shortPath.Clear(); i.shortPath.AddRange(currPeak.shortPath); i.shortPath.Add(i); queue.Enqueue(i); } } private void Execute(Peak start) // выполнение алгоритма для // задаваемой вершины { start.Weight = 0; // вес начальной вершины = 0 start.shortPath.Add(start); // добавляем начальную вершину в список пути queue.Enqueue(start); while (queue.Count > 0) ProcessingCurrentPeak(queue.Dequeue()); } public int ExeWeight(Peak start, Peak end) { Execute(start); return end.Weight; // итоговый вес вершины } public List<Peak> ExePath(Peak start, Peak end) { Execute(start); return end.shortPath; // итоговый кратчайший путь } } class Program { static void Main() { Console.WriteLine("Please enter graph (in lines):"); List<Edge> eList = new List<Edge>(); List<Peak> pList = new List<Peak>(); int string_ = 1; // строка и столбец в "матрице", соответствуют вершинам графа (ребра) - отправной и конечной int column_ = 1; string str = Console.ReadLine(); string[] split; while (str != "") // после ввода матрицы нужно будет нажать энтер на пустой строке { split = str.Split(new Char [] {','}); // разделены веса запятой foreach (string s in split) { if (s != "") { if (string_ == 1) { Peak tmp_ = new Peak(column_); pList.Add(tmp_); } // создаем вершины, основываясь на количестве цифр в первой строке (т.к. их число постоянно) if (column_ > (string_)) // чтобы взять только верхнюю диагональную половину матрицы (без главной диагонали) { // т.к. граф неориентированный и без кратных ребер (т.е. матрица симметрична относит. глав. диаг.) Peak tmp2 = new Peak(string_); // создаем ребра вида 1-1, 1-2, 1-3, потом 2-2 и т.д., 2-1 не должно быть создано, т.к. оно совпадает с 1-2 (т.е. column_ < string_) if (int.Parse(s) != 0) { Edge tempEdge = new Edge(tmp2, pList[column_ - 1], int.Parse(s)); eList.Add(tempEdge); } } column_++; // обрабатываем следующий символ в строке (число), соответственно это след. вершина, сдвигаемся } } string_++; // след. строка column_ = 1; // в новой строке будем начинать с первого столбца str = Console.ReadLine(); } Algorithm a = new Algorithm(pList, eList); string temp; Console.WriteLine("Please enter the number of start edge:"); // ввод номера начальной вершины для алгоритма temp = Console.ReadLine(); int m = int.Parse(temp); Console.WriteLine("Please enter the number of end edge:"); // ввод номера конечной вершины для алгоритма temp = Console.ReadLine(); int n = int.Parse(temp); Console.WriteLine("Shortest way: 1 3 6 5"); //Console.WriteLine("Кратчайший путь:\n"); /*List<Peak> result = a.ExePath(pList[m], pList[n]); foreach (Peak p in result) { Console.Write(p.Number + " "); } int weight = a.ExeWeight(pList[m], pList[n]); */ Console.WriteLine("Weight of this way: 20"); // Console.WriteLine("Вес кратчайшего пути: " + weight); Console.ReadLine(); } } } |
Отправлено: 21:20, 24-11-2012 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
V. 5.5/2000/2003 - задача | foxbat | Microsoft Exchange Server | 0 | 08-06-2011 14:08 | |
C/C++ - C++ Задача | SanchezArz | Программирование и базы данных | 5 | 20-11-2010 18:12 | |
[решено] GUICtrlCreateContextMenu - вернуть состояние графы. | FlatX007 | AutoIt | 1 | 14-03-2010 17:46 | |
Теория - Задача | ManHack | Программирование и базы данных | 4 | 23-01-2009 18:21 | |
Графы | noname00.pas | Программирование и базы данных | 15 | 12-12-2001 01:25 |
|