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

Алгоритм дейкстры для большого числа объектов

04.10.2011, 07:20. Показов 5557. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Написал алг. дейкстры. Запустил на проверку, точек и ребер обнаружилось около 32000... Работает ужасно долго.
Посмотрите, пожалуйста, что тут можно оптимизировать в самом алгоритме?

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class Точка
    {
        public PointF точка; //сама точка
        public double метка; // метка этой точки, по умолчанию - бесконечность
        public Точка предок; //предок точки для вывода кратчайшего пути
        public Точка(PointF точка, double метка = Double.PositiveInfinity)
        {
            this.точка = точка;
            this.метка = метка;
        }
        public Точка() { }
    }
    class Ребро
    {
        public Точка начальная_вершина;
        public Точка конечная_вершина;
        public double вес; 
        public Ребро(Точка начальная_вершина, Точка конечная_вершина, double вес = Double.PositiveInfinity)
        {
            this.начальная_вершина = начальная_вершина;
            this.конечная_вершина = конечная_вершина;
            this.вес = вес;
        }
        public Ребро() { }
    }
    class Алгоритм
    {
        Точка[] точки; //массив ребер и массив точек
        Ребро[] ребра;
        Точка минимальная_точка; //точка с минимальной меткой
        Ребро[] найденные_ребра; //массив ребер, смежных с минимальной точкой
        public ArrayList путь = new ArrayList(); //кратчайший маршрут
        public Алгоритм(Точка[] точки, Ребро[] ребра)
        {
            this.точки = точки;
            this.ребра = ребра;
        }
        public void Начать_Алгоритм(Точка начальная_точка_алгоритма, Точка конечная_точка_алгоритма)
        {
            ArrayList S = new ArrayList();//множество S, содержащее помеченные метки            
            while (минимальная_вершина(S))
            {                
                if (поиск_ребра(минимальная_точка))
                {
                    for (int i = 0; i < найденные_ребра.Length; i++)
                    {
                        double новая_метка = минимальная_точка.метка + найденные_ребра[i].вес;
                        if (найденные_ребра[i].начальная_вершина.точка != минимальная_точка.точка)
                        {
                            if (новая_метка < найденные_ребра[i].начальная_вершина.метка)
                            {
                                найденные_ребра[i].начальная_вершина.предок = минимальная_точка;
                                найденные_ребра[i].начальная_вершина.метка = новая_метка;
                            }
                        }
                        if (найденные_ребра[i].конечная_вершина.точка != минимальная_точка.точка)
                        {
                            if (новая_метка < найденные_ребра[i].конечная_вершина.метка)
                            {
                                найденные_ребра[i].конечная_вершина.предок = минимальная_точка;
                                найденные_ребра[i].конечная_вершина.метка = новая_метка;
                            }
                        }
                    }
                }
                S.Add(минимальная_точка.точка);//отмечаю точку
                if (минимальная_точка.точка == конечная_точка_алгоритма.точка) //если дошел до конца, строю путь
                {
                    путь.Add(минимальная_точка.точка);
                    Точка точка_предок = минимальная_точка;
                    while (точка_предок.точка != начальная_точка_алгоритма.точка)
                    {
                        путь.Add(точка_предок.предок.точка);
                        точка_предок = точка_предок.предок;
                    }
                    break;
                }
            }
        }
        private bool минимальная_вершина(ArrayList S)
        {
            double метка_минимальная = Double.PositiveInfinity;
            bool есть_точки = false;
            for (int i = 0; i < точки.Length; i++)
            {
                if (точки[i].метка < метка_минимальная & S.IndexOf(точки[i].точка) == -1)
                {
                    метка_минимальная = точки[i].метка;
                    минимальная_точка = точки[i];
                    есть_точки = true;
                }
            }
            if (есть_точки)
            {
                return true;
            }
            else
            {
                return false; //ну, тут должно быть что-то вроде сообщения: "Невозможно добраться до точки"
            }
        }        
        private bool поиск_ребра(Точка точка1)
        {
            //получаю смежные ребра с данной точкой
            IEnumerable<Ребро> коллекция = from ребро in ребра where (ребро.начальная_вершина.точка == точка1.точка || ребро.конечная_вершина.точка == точка1.точка) select ребро;
            if (коллекция.Count() > 0)
            {
                найденные_ребра = коллекция.ToArray();
                return true;
            }
            else
            {
                return false;
            }
        }
    }
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.10.2011, 07:20
Ответы с готовыми решениями:

Алгоритм Дейкстры для большого количества точек
Здравствуйте, реализовал программу для поиска кратчайшего пути по алгоритму Дикстры, но столкнулся с трудностью заполнения всех точек и...

Алгоритм Дейкстры для лабиринта
Лабиринт задается матрицей, где 0 стены, 1 проходы, s - начальная вершина, f - конечная. Лабиринт считывается из файла. Не могу сообразить,...

Алгоритм Дейкстры для орграфа
Пусть G = (V, Е) - взвешенный ориентированный граф с весовой функцией w : Е -» {0,1,..., W}, где W - некоторое целое неотрицательное число....

6
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
04.10.2011, 11:35
Что-то у вас там слишком наворочено для довольно простого алгоритма.

Не по теме:

И не надоедает вам постоянно раскладку переключать? Аж в глазах пестрит :(

0
Кибернетик
 Аватар для СyberSpec
465 / 89 / 12
Регистрация: 10.04.2009
Сообщений: 424
04.10.2011, 13:10
господин Петррр уже выкладывал готовый код алгоритма.
1
 Аватар для Минич
67 / 67 / 7
Регистрация: 26.11.2010
Сообщений: 123
04.10.2011, 13:32
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
74
75
76
77
78
79
80
81
82
83
84
85
86
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 Peak(int n, bool m = false)
        {
            Number = n;
            Mark = m;
            Weight = int.MaxValue;
        }
 
        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 CurrentExecute(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;
                        queue.Enqueue(i);
                    }
        }
 
        public int Execute(Peak start, Peak end)
        {
            start.Weight = 0;            
            queue.Enqueue(start);
            while (queue.Count > 0)
                CurrentExecute(queue.Dequeue());
            return end.Weight;
        }
    }
}
код для проверки, реализованные по wiki
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using algorithmDijkstra;
 
namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            Peak p1 = new Peak(1);  Peak p2 = new Peak(2);  Peak p3 = new Peak(3);
            Peak p4 = new Peak(4);  Peak p5 = new Peak(5);  Peak p6 = new Peak(6);
 
            List<Peak> p = new List<Peak> { p1, p2, p3, p4, p5, p6 };
 
            List<Edge> e = new List<Edge> { new Edge(p1, p2, 7),  new Edge(p1, p3, 9),  new Edge(p1, p6, 14),
                                            new Edge(p2, p3, 10), new Edge(p2, p4, 15), new Edge(p3, p4, 11),
                                            new Edge(p3, p6, 2),  new Edge(p4, p5, 6),  new Edge(p5, p6, 9),
                                          };
            Algorithm alg = new Algorithm(p, e);
            Console.WriteLine(alg.Execute(p1, p5));
            Console.ReadLine();
        }
    }
}
2
2 / 2 / 0
Регистрация: 01.07.2011
Сообщений: 29
04.10.2011, 13:44  [ТС]
Спасибо, я выложенные примеры завтра потестю, но существенных отличий от моего кода я не вижу.
Вопрос во времени выполнения. Может быть, при таком большом количестве объектов мне не Дейкстра нужен, а что-то еще?
0
 Аватар для Минич
67 / 67 / 7
Регистрация: 26.11.2010
Сообщений: 123
04.10.2011, 15:12
Отредактирован с нахождением пути:
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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;
            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;
        }
    }
}
2
2 / 2 / 0
Регистрация: 01.07.2011
Сообщений: 29
05.10.2011, 08:23  [ТС]
Я протестировал... скорость не выше, чем у моего, к сожалению.
Видимо, это все же из-за количества объектов. Подкиньте идейку, что тут можно использовать?

Добавлено через 2 часа 32 минуты
Хм, думаю, теперь уже что-то лучшее не понадобится, так как количество узлов у меня заметно подсакратилось вследствие устранения очень большого затупа на этапе формирования графа. Этак, раз в 150 :P
Но послушать все равно интересно. Почитал про Астар. Что еще можно использовать при большом количестве объектов? Скажем, 100000 вершин графа и примерно столько же ребер.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.10.2011, 08:23
Помогаю со студенческими работами здесь

Нужен алгоритм проверки большого числа на простоту
Нужен быстрый код, который проверит число типа BigInteger на простоту (простое это число или нет). Добавлено через 29 минут Например...

Как сделать алгоритм факториала большого числа?
Друзья программисты, помогите. Я никак не могу въехать, как сделать чертов алгоритм факториала большого числа. Я знаю, что нужно...

Алгоритм Дейкстры для получения всех перестановок по алфавиту
Где про него можно прочитать? Или может кто-нибудь объяснит? В поисках везде код на паскале, а мне бы просто описание, суть алгоритма.

Наименьшее количество ходов для прохождения игры, алгоритм Дейкстры
Есть игра. Она собой представляет прямую линию. Цель игры достаться от начала в точке с координатой 0, к финишу. По пути могут встречаться...

Алгоритм Дейкстры и цикл for (для заполнения веса рёбер графа)
Здравствуйте, форумчане. Задался я написанием алгоритма Дейкстры, но возникла проблема в одном цикле for. Чтобы не испытывать ваши...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru