Guest User

Untitled

a guest
May 20th, 2016
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.20 KB | None | 0 0
  1. Класс Top:
  2. public Point location;
  3. public int number;
  4.  
  5. public bool visited = false;
  6. public int weight = 99999;
  7. public Top from;
  8. public Color color = Color.Violet;
  9.  
  10. Класс Edge:
  11. public Top top1, top2;
  12. public int weight;
  13. public bool isSelected = false;
  14.  
  15. Класс Graph:
  16. public List<Top> topsList = new List<Top>();
  17. public List<Edge> edgesList = new List<Edge>();
  18.  
  19. АлгоритмДейкстры(Top startTop, Top finishTop)
  20. {
  21.     List<Top> notVisitedTops = new List<Top>(topsList); //Список не посещенных вершин (все вершины графа)
  22.     List<Top> visitedTops = new List<Top>(); //Список посещенных вершин
  23.                
  24.     List<Top> linkedTops = new List<Top>(); //Список вершин, связанных с текущей вершиной
  25.     List<Edge> linkedEdges = new List<Edge>(); //Список инцидентных ребер
  26.                
  27.     Top _startTop = startTop; //Вершина, с которой сейчас ведется работа
  28.     Edge workEdge; //Ребро, которое соединяет _startTop и одну из связанных с ней вершин
  29.  
  30.     linkedEdges = edgesList.Where(n => n.top1 == _startTop || n.top2 == _startTop).ToList(); //Находим все инцидентные текущей вершине ребра
  31.     linkedTops = getTops(linkedEdges, _startTop); //Из списка этих ребер находим все связные вершины, в КОТОРЫХ МЫ ЕЩЕ НЕ БЫЛИ
  32.  
  33.     while (notVisitedTops.Count > 0) //Начинаем цикл, пока не посетим все вершины
  34.     {
  35.         for (int i = 0; i < linkedTops.Count; i++) //Проходимся по всем связным вершинам
  36.         {
  37.             workEdge = edgesList.Where(n => (n.top1 == linkedTops[i] && n.top2 == _startTop) || (n.top1 == _startTop && n.top2 == linkedTops[i])).ToList()[0]; //Находим ребро, соединяющее текущую вершину с i-ой из связных вершин
  38.  
  39.             if (linkedTops[i].weight > (workEdge.weight + _startTop.weight)) //Если вес i-ой связной вершины больше, чем вес текущей вершины + вес ребра их соединяющего, то этой i-ой вершине присваиваем вес текущей вершины + вес ребра, а также указываем, что в эту вершину мы дошли из _startTop
  40.             {
  41.                 linkedTops[i].weight = workEdge.weight + _startTop.weight;
  42.                 linkedTops[i].from = _startTop;
  43.             }
  44.         }
  45.  
  46.         _startTop.visited = true; //Заканчиваем работу с текущей вершиной, помечая ее посещенной
  47.         visitedTops.Add(_startTop); //Добавляем в список посещенных вершин
  48.         notVisitedTops.Remove(_startTop); //Удаляем из списка не посещенных
  49.  
  50.         _startTop = linkedTops.Min(); //Новая стартовая вершина - это имеющая минимальный вес из связных
  51.         linkedEdges = edgesList.Where(n => (n.top1 == _startTop) || n.top2 == _startTop).ToList(); //Находим инцидентные ребра уже к этой вершине
  52.         linkedTops = getTops(linkedEdges, _startTop); //И уже для этой вершины находим все связные НЕ ПОСЕЩЕННЫЕ (visited = false) вершины
  53.     }
  54.  
  55.     //В один момент getTops() будет возвращать 0, так как у текущей вершины хоть и будут связные вершины, но не посещенных среди них уже не будет. Если убрать проверку на посещенность, а просто каждый раз выбирать за основную минимальную из связных вершин, то алгоритм зациклится, так как менять вес соседних вершин он уже не сможет, но при этом каждый раз будет выбирать минимальную из связных вершин
  56. }
Add Comment
Please, Sign In to add comment