Добрый день, есть задача разработать БД таким образом, чтобы можно было определить расстояние между двумя станциями. Но проблема в том, что все тарифное расстояние РЖД находится на бумаге так сказать, либо в электронном виде, вот пример(http://lawrussia.ru/2001_legislation_of_russia_documents/russian_laws_1547.htm). В принципе, я немного имею идею, как сделать алгоритм расчета от станции А до станции Б, ноя не могу никак придумать, как лучше организовать структуру БД. Есть Страна, Есть дорога, есть участок, на это участке набор остановочных пунктов, вот как можно лучше всего сделать это, ведь не буду я для каждого узла делать отдельные таблицы, может кто понимает в этом, подскажите плиз. Пока идея, все станции запихнуть в одну таблицу, и сделать ссылки на узлы, узлы на дороги, а дороги на страны, но это как-то не очень получается.
Я в этом не особо силен, поэтому мог некорректно вопрос составить.
Ответ
Для ответа на этот вопрос необходимо вспомнить немого теории.
Для поиска Вам идеально подходит структура данных - матрица растояний. Фактически, это квадартная матрица, в которой по осях находятся идексы станций, а значения по этому индексу и есть искомое растояние. Это именно та структура к которой нужно стремится при работе в программном коде. Но у неё есть небостатки. Она обладает высокой избыточностью. Фактически вы дублируете растояние из узла А в узел Б и наоборот т.е. Вам это придётся дублировать. Кроме того, добавление новых станций будет требовать изменения структуры БД, для расширения на добавляемые станции.
Если посмотреть внимательно - то в этой задаче данные о растояниях будут сильно "прорежены". Т.к. почти у всех станций растояний м.б. только два - к предыдущей и последующей станции. И только у узлов их будет больше. Наиболее подходящим в этом случае будет хранить информацию о растояних отдельно от станций.
CREATE TABLE STATION (
STATION_ID INT PRIMARY KEY
);
CREATE TABLE STATION_DISTANCE (
STATION1_ID INT,
STATION2_ID INT,
DISTANCE NUMERIC NOT NULL,
PRIMARY KEY (STATION1_ID, DISTANCE, STATION2_ID),
FOREIGN KEY (STATION1_ID) REFERENCES STATION (STATION_ID),
FOREIGN KEY (STATION2_ID) REFERENCES STATION (STATION_ID)
);
Такая структура БД предоставит достаточно удобное хранение записи о растоянии, но совершить поиск оптимального пути на уровне базы данных при указанных условиях, не предоставляется возможным.
Поиск в этом случае можно будет совершить двумя способами:
Способ с предварительной подготовкой и подниманием всей информации о путях из БД.
Способ требующий уточняющих запросов.
Первый - потребует подготовки которая заключается в постороении из этой таблицы матрицы растояний к примеру при помощи алгоритма Флойда - Уоршелла. И хотя этот алгоритм достаточно тяжёлый его результат, можно сохранить сериализовав матрицу растояний в файл и далее работать с ним, при этом его модификацию потребуется выполнять только при изменении структуры ЖД, что не так и часто.
При таком подходе можно быстро находить нужное растояние по матрице растояний.
Второй - базируется на алгоритме Дейкстры для разреженных графов. У Вас есть возможность оптимизировать решение отталкиваясь от информации является ли станция узловой, и относится ли она к одной и той-же линии. При этом критерием сложности я бы назвал количество обращений к базе данных.
Надеюсь здесь, в нескольких строках, мне удалось немного приблизить Вас к нужному варианту ответа по этой достаточно сложной задаче.
Комментариев нет:
Отправить комментарий