|
|
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
Добрый день Возникло задание хранения неориентированного, имеющего циклы графа. В основном в форуме рассматривались ориентированные, не имеющие циклы графы - деревья. Пример графа на рисунке P.S. граф взвешенный, без отрицательного веса, Вершины B,C,Q,W,R,E,D имеют координаты на местности моя релизация: t_Versiny(t_id,....) t_Rebra(r_id,t_id1,t_id2,rastojanie,...) какие есть предложения по оптимизации или проектированию моей задачи...Но нужно ещё ориентироваться на задания указанные ниже.... Второе задание: - найти самый короткий путь между двумя вершинами - найти самый короткий путь от заданой вершины до определенного типа вершин Понятно, что наилучшие алгоритмы это A* и Дейксты, основан на поиске в ширину. Наглядные задания: 1. Самый короткий путь K-A, O-K 2. Пусть Q,W,R - вершины определенного типа, нужно дойти до любой из них по самому короткому пути от вершин: О, потом К, потом H ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2009, 23:28 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
mosВозникло задание хранения неориентированного, имеющего циклы графа. В основном в форуме рассматривались ориентированные, не имеющие циклы графы - деревья. Да ну? Плохо читали, видать. Хранить граф очень просто : Таблица ДУГИ: Поля: Узел1, Узел2 (первичный ключ - эти два поля). Ели у вас от одного узла к другому может быть несколько дуг - то первичный ключ убираете. Вот и все... Чтобы быть совсем точным - чтобы исключить попадание обратной записи аналогичной дуги (у вас граф неориентированный) - то надо добавить констрэйнт вида, например "НомерУзла1 > НомерУзла2" и записывать дуги в БД согласно этому правилу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2009, 11:06 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
mos, В добавление - часто неориентированный граф удобно переводить в ориентированный - но у которого есть две дуги (туда и обратно) там где у неориентированного одна. Упрощает некоторые условия сравнивания в алгоритмах, но не более того. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2009, 11:08 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
оказывается это вы до конца не дочитали. Этот вариант я и использую: t_Versiny(t_id,....) t_Rebra(r_id,t_id1,t_id2,rastojanie,...) Может кто более гениальный метод хранение изобрел, для более оптимального хранения и использования алгоритмов поиска по графам ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2009, 16:30 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
А что случается чаще, и на сколько порядков: добавление вершин и ребер в граф, или поиск кратчайшего пути между множествами вершин? Если второе, и на три+ порядка, то удобнее хранить полносвязный орграф, у каждого ребра которого есть признак ближайшей вершины на кратчайшем пути. (там где у исходного графа есть ребра, эта ближайшая вершина совпадает с конечной вершиной пути). При добавлении вершин и ребер придется пересчитывать пути. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2009, 17:50 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
mosМожет кто более гениальный метод хранение изобрел, для более оптимального хранения и использования алгоритмов поиска по графамНичего особенно гениального в хранении двух пар указателей на узлы придумать неполучится. Особенно для хранения в БД. В памяти еще есть несколько вариантов представления графов - в БД они почти все становятся бессмысленными. только вот это имеет смысл добавить в БД. =========================== В добавление - часто неориентированный граф удобно переводить в ориентированный - но у которого есть две дуги (туда и обратно) там где у неориентированного одна. =========================== ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2009, 19:22 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
to Bely: т.е. предложение для каждого соединения между двух вершин, хранить по две записи (дуги)? Как это может повлиять на поиск путей??? to Q: можно по подробней о методе хранения с примерчиком, можно и мой использовать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2009, 09:27 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
Ну вот в этом: mos t_Versiny(t_id,....) t_Rebra(r_id,t_id1,t_id2,rastojanie,...) добавить одно поле t_Rebra(r_id,t_id1,t_id2, t_idNext , rastojanie,...) Для подграфа ABC это будут: (1, ...) //A (2, ...) //B (3, ...) //C (1, 1, 2, 2, 10.5, ...) // Путь A-B совпадает с ребром A-B (2, 2, 3, 3, 7.3, ...) // Путь B-C совпадает с ребром B-C (3, 1, 3, 2, 17.8, ...) // Путь A-C состоит из нескольких ребер, начинается с A-B и еще три записи "в обратном направлении". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2009, 12:12 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
т.е. Q согласен с Bely, что надо переводить неориентированный граф в ориентированный? а ваш метод не будет сложный, в связи с тем, что надо иногда модифицировать граф, например вставить узел в дугу или наоборот? И как он себя ведет с циклами??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2009, 13:39 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
I. Уточнение: mosт.е. Q согласен с Bely, что надо переводить неориентированный граф в ориентированный? Слово "Нада" тут не правильное. Например, получения всех узлов, имеющих дуги с узлом A можно сделать двумя способами: 1) Для неориентированного графа: SELECT t_id2 FROM t_Rebra WHERE t_id1 = A UNION ALL SELECT t_id1 FROM t_Rebra WHERE t_id2 = A 2) Для ориентированного графа (записей в два раза больше, чем в неориентированном варианте): SELECT t_id2 FROM t_Rebra WHERE t_id1 = A Поэтому совет: В случае с ориентированным графом - быстрее и проще запросы, но сложнее модификация данных, в случае неориентированного графа - сложнее и медленнее запросы, но проще модификация данных. (Вообще - традиционная проблема: хочешь быстрее - плати ресурсами, хочешь меньше по объему - плати производительностью или по другому: считать результат можно каждый раз, а можно заранее посчитать и потом только пользоваться сохраненными результатами всей задачи или ее части). Сами выбирайте что "лучше" для Вас! II. Еще вариант (возможно это то, что предлагал Q, но я его не понял) Хранить все возможные пути между всеми вершинами! Этот вариант самый быстрый (с точки зрения решения запрашиваемых задач) и требующий больше всего ресурсов. А также имеющий сложности с вводом исходных данных (но это решаемо). Конкретно: Т.е. кроме предложенных таблиц (вариант неориентированного графа) дополняем еще пару: puti (put_id, t_id1, t_id2, rastojanie) - каждая запись о возможном пути shagi_puti(shag_puti_id, put_id, t_id1, t_id2, N, rastojanie) - запись о дуге, с ее узлами, номером шага в пути и растоянием, причем идем именно от t_id1 к t_id2. Данную таблицу нужно автоматически перегенерировать при любом изменении t_Rebra. Т.е. тратим много места на организацию новых таблиц (в них будет много записей - рост близкий к экспоненте от количества ребер и узлов), тратим время один (каждый) раз при внесении изменений в исходные таблицы для перегенерации ноых таблиц, но! заявленные задачи mosВторое задание: - найти самый короткий путь между двумя вершинами - найти самый короткий путь от заданой вершины до определенного типа вершин Выполняться будут очень быстро (индексы соответствующие не забываем сделать)! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2009, 15:13 |
|
||
|
представление и хранения графа в бд
|
|||
|---|---|---|---|
|
#18+
mosт.е. Q согласен с Bely, что надо переводить неориентированный граф в ориентированный? а ваш метод не будет сложный, в связи с тем, что надо иногда модифицировать граф, например вставить узел в дугу или наоборот? И как он себя ведет с циклами??? Да, операции с орграфом, как правило, гораздо понятнее и короче в виде кода. Да, метод более сложный и затратный при модификации графа (выше -- критерий его применимости). 1. Хранение полносвязного графа и дополнительной первой вершины кратчайшего пути требует O(N^2) памяти, хранение исходного -- o(N^2), т.е, для какой-то специфической задачи, это o(N^2) может оказаться существенно меньше, но в общем случае -- нет :) 2. Хранение полносвяного графа и всех маршрутов требует o(N^3) памяти, при этом порядок сложности построения кратчайшего маршрута такой же, как в моем методе, НО (!) всю оптимизацию за вас сделает SQL. :) Сложность модификации у двух этих методов -- одинаковая. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2009, 20:42 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=35792221&tid=1543459]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
82ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
2ms |
| others: | 226ms |
| total: | 407ms |

| 0 / 0 |
