Веб приложение по планированию маршрутов. _________________________________________________ Отображение _________________________________________________ Для отображения элементов интерфейса используется фреймворк devextreme, в частности используются следующие элементы: - карта https://js.devexpress.com/jQuery/Demos/WidgetsGallery/Demo/Map/ProvidersAndTypes/MaterialBlueLight/ - кнопка https://js.devexpress.com/jQuery/Demos/WidgetsGallery/Demo/Button/PredefinedTypes/MaterialBlueLight/ - списки https://js.devexpress.com/jQuery/Demos/WidgetsGallery/Demo/List/ListSelection/MaterialBlueLight/ - выпадающий список https://js.devexpress.com/jQuery/Demos/WidgetsGallery/Demo/DropDownButton/Overview/MaterialBlueLight/ Для указанных элементов и сайта используются стили из этого же фреймворка: dx.material.blue.dark.compact.css Также из сторонних библиотек используется jquery, для обращения к элементам страницы, и создания новых элементов. Собственные стили находятся в файле css/styles.css. Данные по точкам доступным для посещения хранятся в файле js/data.js _________________________________________________ Логика работы _________________________________________________ Все функции находятся в файле js/index.js При входе на страницу отобажается карта со всеми доступными для расчета порядка посещения точками. Пользователь, в первую очередь, выбирает регион посещения, из списка под картой. При выборе региона будут отображены точки для посещения в данном регионе в виде списка с возможности выбирать элемента, а карта отобразит только точки выбранного региона. На следующем шаге пользователь отбирает интересующие точки в списке, при выборе будет формироваться новый список в правой части страницы, который содержит выбранные элементы. По окончании отбора точек, пользователь нажимает кнопку Рассчитать маршрут. После чего под кнопкой отобразится найденный маршрут с относительно оптимальной длиной пути. Маршрут отображается в виде списка точек посещения, между которыми отображается расстояние. В конце списка отображается общая длина маршрута. _________________________________________________ Алгоритм построения маршрута _________________________________________________ Для расчета расстояния между точек, используется метод calculateDistance из библиотеки https://github.com/chrisveness/geodesy Которая позволяет определить дистанцию между двумя точками заданными координатами в виде широты и долготы. Для построения оптимального маршрута используется следующий подход: 1. Если точек три или меньше, выводятся в порядке заданном пользователем (старт, промежуточная точка, окончание маршрута) 2. Если точек больше трех, то используется метод stochasticPathFind: 2.1 Вычисляется количество комбинаций точек, как факториал общего количества точек за минусом двух (начало и окончание маршрута) 2.2 Если количество комбинаций превышает допустимое (300.000), то используется максимально допустимое количество комбинаций 2.3 Перебираются возможные комбинации, каждая новая комбинация формируется случайным перемешиванием точек маршрута, кроме начальной и конечной 2.4 Для каждой комбинации вычисляется общая длина пути, если найденная длина меньше предыдущей минимальной, запоминается длина маршрута и комбинация 2.5 Метод возвращает маршрут с минимальной найденной длиной пути. Для точек количеством менее 10, будут перебраны все доступные комбинации (10 - 2)! < 300.000, для 11 будут перебраны почти все комбинации (11 - 2)! = 362 880 Для большего числа точек будет выбран лучший из перебранных маршрутов, но не лучший из всех возможных. Данный подход был выбран после попыток использовать построение Гамильтонова пути (https://ru.wikipedia.org/wiki/%D0%93%D0%B0%D0%BC%D0%B8%D0%BB%D1%8C%D1%82%D0%BE%D0%BD%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84) и нескольких других алгоритмов на графах. Попытки использовать данные алгоритмы показали что для большого числа точек (>9), временные затраты на поиск и нагрузка на браузер, процессор и память, превышают разумные границы. Вследствие чего было принято решение использовать простой перебор, и ограничить количество анализируемых маршрутов в 300.000 комбинаций.