Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 18.04.2016
Сообщений: 39

Алгоритм Дейкстры и нахождения кратчайших путей

28.03.2018, 14:22. Показов 4984. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задание:
Построить граф, олицетворяет карту некоторой транспортной сети чего-то среднего между такси и маршруткой. Дороги - ребра, узлы - остановки этих такси.
Рандомно выбирается n остановок на которых будут стоять такси (List <Node> TaxiPos). Пользователь выбирает узел, с которого якобы вызывается такси (Node UserPos).
Нужно выбрать, какое именно такси с List <Node> TaxiPos ближе находится к цели Node UserPos.
Вопрос/Проблема
Длины кратчайших путей находит нормально.
Но понятия не имею как получить именно кратчайшие пути. Список узлов или ребер по которым я дойду от Alpha к любому другому.
Есть какие-то варианты? Прошу объяснять как умственно отсталому, а то я пробовал сам разобраться в десятках примеров, и это что-то не помогло.
Спасибо
Клас Node:
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
enum NodeStatuses : int { Empty, Taxi, Client };
    /// <summary>
    /// Представляє об'єкти графа - вузли
    /// Кожен вузол має наступні поля:
    ///     1. Стан - описує стан цього вузла(зупинки) (вільна зупинка, місце стоянки таксі, локація клієнта)
    ///     2. Номер - ідентифікатор вузла |readonly
    ///     3. Координати розміщення вузла на формі |readonly
    /// </summary>
    public class Node
    {
        //Поля
        public int Status { get; set; }
        public readonly int Number;
        public readonly Point placement;
        //Конструктори
        public Node(int number, Point point)
        {
            Status = (int)NodeStatuses.Empty;
            placement = point;
            Number = number;
        }
        public Node(int number, int left, int top) : this(number, new Point(left, top)) { }
 
        public static bool operator ==(Node A, Node B)
        {
            try
            {
                return (A.Number == B.Number && A.placement == B.placement);
            }
            catch(NullReferenceException)
            { return false; }
            catch
            { throw new Exception(); }
        }
        public static bool operator !=(Node A, Node B) => !(A == B);
 
        public override bool Equals(object obj)
        {
            var node = obj as Node;
            return node != null &&
                   Status == node.Status &&
                   Number == node.Number &&
                   EqualityComparer<Point>.Default.Equals(placement, node.placement);
        }
    }
}

Клас Edge:
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  public class Edge
    {
        //Статичні поля
        /// <summary>
        /// Нескінченність - для алгоритму Дейкстри
        /// </summary>
        public static double Infinity = double.PositiveInfinity;
        /// <summary>
        /// Ребро з довжиною нескінченність(уособлює відсутість ребра між точками) - для алгоритму Дейкстри
        /// </summary>
        public static Edge notExistingEdge = new Edge(-1, -1, -1, -1);
        /// <summary>
        /// Ребро з довжиною нуль(уособлює ребро яке звязує одну ту же точку) - для алгоритму Дейкстри
        /// </summary>
        public static Edge nullLengthEdge = new Edge(0, 0, 0, 0);
        //Поля
        public readonly Point Start;
        public readonly Point Final;
        //Властивості
        /// <summary>
        /// Повертає довжину ребра
        /// </summary>
        public double Length
        {
            get
            {
                if (Start == new Point(-1, -1))
                    return Infinity;
                return Math.Sqrt(Math.Pow((Start.X - Final.X), 2) + Math.Pow((Start.Y - Final.Y), 2));
            }
        }
        //Конструктори
        /// <summary>
        /// Конструктор, що створює ребро за заданими координатами
        /// Є перезаванження для підтримки як 4 int так і 2 об'єктів класу Point та Pair
        /// </summary>
        public Edge(Point S, Point F)
        {
            Start = S;
            Final = F;
        }
        public Edge(Pair<int> S, Pair<int> F)
        {
            Start = new Point(S[0], S[1]);
            Final = new Point(F[0], F[1]);
        }
        public Edge(int startX, int startY, int finalX, int finalY)
        {
            Start = new Point(startX, startY);
            Final = new Point(finalX, finalY);
        }
 
        public static bool operator ==(Edge A, Edge B)
        {
            try
            {
                return (A.Start == B.Start && A.Final == B.Final);
            }
            catch (NullReferenceException)
            { return false; }
            catch
            { throw new Exception(); }
        }
        public static bool operator !=(Edge A, Edge B) => !(A == B);
 
        public override bool Equals(object obj)
        {
            var edge = obj as Edge;
            return edge != null &&
                   EqualityComparer<Point>.Default.Equals(Start, edge.Start) &&
                   EqualityComparer<Point>.Default.Equals(Final, edge.Final);
        }
    }

Сам алгоритм:
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public double[] Dijkstra(Node Alpha)
        {
            //Підготовка
            ////Список відвіданих точок
            ////При чому точка для якої обраховуємо відстані зразу додається у список відвіданих
            List<Node> Visited = new List<Node>(NodeCount);
            Visited.Add(Alpha);
            ////Массив ,що зберігатиме відстані від Alpha до решти вузлів
            double[] D = new double[NodeCount];
 
            for (int i = 0; i < D.Length; i++)
                D[i] = double.PositiveInfinity;
            D[Alpha.Number] = 0;
            ////Масив ,що зберігати найкоротші шляхи
            Node[] AltShortWays = new Node[NodeCount];
 
            ////Постійна мітка
            Node W = Alpha;
            ////
            do
            {
                for (int i = 0; i < NodeCount; i++)
                {
                    if (Visited.Contains(GetNodeByID(i)))
                        continue;
                    Node currentNode = GetNodeByID(i);
                    Edge currentEdge = this[new NodePair(W, currentNode)];//індексатор повертає ребро, що звязує ці вузли
                    double current = currentEdge.Length + D[W.Number];
 
                    if (D[i] > current)
                    {
                        D[i] = current;
                        AltShortWays[i] = currentNode;
                    }
                }
                List<Node> MinList = GetMinList(D, Visited); //повертає мінімальні значення масиву D (на випадок якщо їх багато)
                foreach (var min in MinList)
                {
                    bool Break = false;
                    foreach (var vis in Visited)
                    {
                        if (vis.Number != min.Number)
                        {
                            W = min;
                            Break = true;
                            break;
                        }
                    }
                    if (Break)
                        break;
                }
                Visited.Add(W);
            } while (Visited.Count != NodeCount);
 
            return D;
 
        }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.03.2018, 14:22
Ответы с готовыми решениями:

Алгоритм флойда для поиска кратчайших путей в графе
алгоритм флойда для поиска кратчайших путей в графе. Вывожу длину путей между вершинами, не могу вывести вершины которые попадают в...

Вывести алгоритм флойда с выводом на печать кратчайших путей
Вообщем нужно на си-шарп вывести алгоритм флойда с выводом на печать кратчайших путей , а матрица стоимостей задается ортогональным...

Построение кратчайших путей между всеми парами вершин графа. Алгоритм Флойда
Взялся за свой курсовик. Задача такая: Реализовать алгоритм Флойда для построения кратчайших путей между всеми парами вершин графа. С...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.03.2018, 14:22
Помогаю со студенческими работами здесь

Нахождение кратчайших путей в графах
Здравствуйте, я тут новичок, зарегистрировался только сегодня, прошу Вас помощи. Передо мной стоит задача написать программу на языке...

Поиск кратчайших путей из одной вершины (алгоритм Дейкстры)
Алгоритм Дейкстры . Поиск кратчайших путей из одной вершины. Три файла h, сpp, main (в мэйне тесты/ гугл тесты)

Алгоритм Флойда-Уоршелла [для нахождения кратчайших путей]
Дан ориентированный взвешенный граф. По его матрице смежности нужно для каждой пары вершин определить, существует кратчайший путь между...

Распараллеливание алгоритма дейкстры для поиска кратчайших путей
Есть задача, она выполнена в последовательной программе ниже, помогите сделать её распараллеленый вариант ,что бы сравнить время выполнения...

Алгоритмы нахождения кратчайших путей
Алгоритмы нахождения кратчайших путей. Что это такое и с чем его едят?? И как это все делается?:'(


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru