|
|
|
Как эффективно искать пути в N-арном дереве?
|
|||
|---|---|---|---|
|
#18+
Есть задача хранить дерево размножения животных. Т.е. две вершины (отэць, мат) у них куча детей. Получается, что у каждой вершины 0-2 предка и 0-N потомков. В принципе хранить все это легко получается, просто указывая для каждой вершины ее двух предков, если бы не одно но. Так-же, помимо хранения необходимо уметь находить пути (или хотя бы один кратчайший путь) между двумя вершинами. Другими словами проверять родство двух животных. Вроде в каком колене у них там где общий предок или потомок одного где-то родственник предка другого и т.п. Делать это с помощью рекурсивного просмотра всех возможных путей, очень накладно. В связи с чем прошу пнуть в верном направлении, про какие деревья, их представления да алгоритмы почитать, чтобы понять, как пооптимальнее решить эта задачу. Или здесь кроме рекурсии никак? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.12.2007, 23:39 |
|
||
|
Как эффективно искать пути в N-арном дереве?
|
|||
|---|---|---|---|
|
#18+
Divog wrote: > родство двух животных. Вроде в каком колене у них там где общий предок > или потомок одного где-то родственник предка другого и т.п. > Делать это с помощью рекурсивного просмотра всех возможных путей, очень > накладно. Интересует проверить родство (найти общего предка) или узнать точный путь? Это разные задачи. Если родство - можно гнать волну вверх по дереву. Точнее две волны, по одной из каждого узла. Для этого узлы, составляющие фронт волны объединяется в список. Кроме того, к каждому узлу добавляется цвет (белый=не видели, красный=видели из узла a, синий=видели из узла b). На каждом шаге фронт волны распространяется вверх к предкам. Для этого проверяется цвет вершины предка - белая попадает в новый фронт и перекрашивается, вершина соответствующая своему цвету - игнорируется, вершина чужого цвета - ближайший общий предок. Если нужно точно найти пути, то задача несколько усложняется. Придется еще хранить ссылку на узел при переходе из которого вершина была перекрашена. > > В связи с чем прошу пнуть в верном направлении, про какие деревья, их > представления да алгоритмы почитать, чтобы понять, как пооптимальнее > решить эта задачу. Оптимальность зависит от условий. Как вариант - найти транзитивное замыкание отношения предок для каждого из узлов и взять их пересечение. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.12.2007, 03:15 |
|
||
|
Как эффективно искать пути в N-арном дереве?
|
|||
|---|---|---|---|
|
#18+
авторИнтересует проверить родство (найти общего предка) или узнать точный путь? Это разные задачи. Надо найти именно путь. автор Если родство - можно гнать волну вверх по дереву. Точнее две волны, по одной из каждого узла. Для этого узлы, составляющие фронт волны объединяется в список. Кроме того, к каждому узлу добавляется цвет (белый=не видели, красный=видели из узла a, синий=видели из узла b). На каждом шаге фронт волны распространяется вверх к предкам. Для этого проверяется цвет вершины предка - белая попадает в новый фронт и перекрашивается, вершина соответствующая своему цвету - игнорируется, вершина чужого цвета - ближайший общий предок. Подобный алгоритм мне на ум приходил, однако, накладный получается, при частом поиске и большом кол-ве животных. авторОптимальность зависит от условий. Как вариант - найти транзитивное замыкание отношения предок для каждого из узлов и взять их пересечение. Сейчас так и делаю, однако построение оного, при моей схеме хранения данных оч. накладно, да и великоватое оно получается, если там предков 20 колен. 2*2^20 пар id-шников. Думал, может что пооптимальнее есть. Вы мне дайте ключевых слов, я в инете найду доки, почитаю :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2007, 01:00 |
|
||
|
Как эффективно искать пути в N-арном дереве?
|
|||
|---|---|---|---|
|
#18+
Divog wrote: >> Оптимальность зависит от условий. Как вариант - найти транзитивное >> замыкание отношения предок для каждого из узлов и взять их пересечение. > > Сейчас так и делаю, однако построение оного, при моей схеме хранения > данных оч. накладно, да и великоватое оно получается, если там предков > 20 колен. 2*2^20 пар id-шников. А как находите путь? Замыкания ведь недостаточно. Просто поиск по отношению прямой предок до заданного предка? Пофантазирую еще. Может скрестить транзитивное замыкание отношения прямой предок и волновой поиск? Отношение предок позволяет относительно быстро проверить существование общего предка для двух особей, но не показывает пути. И в вашей задаче это отношение можно строить по мере роста. Скрещивание будет заключаться в том, что на каждой итерации волна распространяется только на те узлы, у которых есть общий предок со второй особью. Таким образом все сторонние ветви отмирают сразу. Как вариант оптимизации по памяти - хранение не полного отношения, а прореженного. Скажем - запоминается только предки в 5,10,...5*n колене. При поиске придется считать количество шагов для каждого узла, вовлеченного в фронт, и если таких шагов становится больше, чем коэффициент прореживания - поиск прекращается. Еще такая мысль - хранить помимо самого отношения еще и колено. В этом случае, помимо нахождения множества общих предков можно выбирать ближайших из них (понятно, что их может быть несколько) - и искать путь только до них (до любого из них), используя скрещенный вариант. На мой взгляд, это будет самый быстрый поиск, с самыми большим расходом памяти. > > Думал, может что пооптимальнее есть. Вы мне дайте ключевых слов, я в > инете найду доки, почитаю :) Не, с ключевыми словами - сложно. Очевидно, что задача из области дискретной математики и теория графов, но это слишком общо. Приведенный волновой алгоритм применяется в области трассировки печатных плат. Можно, конечно еще покопаться в ней, возможно что-нибудь найдете: <http://algolist.manual.ru/maths/graphs/shortpath/smartmove.php> Опять-же, если бы у вас и в самом деле было дерево, а не ациклический орграф, можно было бы подумать о множественной модели представления дерева <http://www.sedinko.ru/algo/doc1.php>. Вот пожалуй и все, что приходит в голову. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2007, 16:53 |
|
||
|
Как эффективно искать пути в N-арном дереве?
|
|||
|---|---|---|---|
|
#18+
Почему ацикличный? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2007, 17:33 |
|
||
|
Как эффективно искать пути в N-арном дереве?
|
|||
|---|---|---|---|
|
#18+
apapacy wrote: > Почему ацикличный? А как вы себе представляете цикл в данном случае? Как можно быть прямым или косвенным предком самого себя? Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2007, 18:08 |
|
||
|
Как эффективно искать пути в N-арном дереве?
|
|||
|---|---|---|---|
|
#18+
Прошу прощения, чуток пропал :) В общем прикинул я, для реальных данных (ожидаемых) волнового поиска, описанного Вами выше, будет достаточно. И по памяти хорошо и по скорости нормально, учитывая, что в большинстве случаев уже где-то на 5-10-м колене будет результат. И для худших случаев где 20-ые колена, сносно будет работать. А если что, то отношение прореженное можно будет прикрутить без больших переделок. Спасибо за помощь и за ссылки. Почитаю на досуге :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2007, 22:38 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=35006033&tid=1345617]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
51ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
| others: | 254ms |
| total: | 410ms |

| 0 / 0 |
