Иллюстрация - sergeresko/Lem_in-explanation GitHub Wiki

Вот иллюстрация работы алгоритма Бхандари на примере, которым я пользовался в процессе написания своего Lem_in: https://github.com/sergeresko/lem_in/blob/master/_maps/3-groups.map.

На фотографии ниже изображён процесс нахождения путей, я на неё буду ссылаться. Нумерация рисунков:

A1  A3  A5
A2  A4

Первый запуск алгоритма

Рис. R1 — Граф выглядит так. Стрелки, которые выходят из комнаты, обозначают рёбра, хранящиеся в списке links этой комнаты (если вес ребра не указан на рисунке, он равен 1).

1) modify graph: не делает ничего, т.к. все pred/succ равны NULL

2) find path: в результате работы алгоритма Дейкстры мы получим путь S-11-8-5-T, который будет представлен так:

 room   |    S | 11 |  8 | 5 | T
--------+------+----+----+---+---
 parent | NULL |  S | 11 | 8 | 5

На рис. R1 около вершин подписаны их distance и parent.

3) adjust parents: ничего не делает

4) restore graph: ничего не делает

5) combine paths: поскольку в pred/succ пока ничего нет, просто сохраняем в них найденный путь:

 room |    S | 11 |  8 | 5 |    T
------+------+----+----+---+------
 pred | NULL |  S | 11 | 8 | NULL
 succ | NULL |  8 |  5 | T | NULL

Этот путь показан на рис. A1.

Второй запуск алгоритма

1) modify graph: делим вершины вдоль пути, который хранится в pred/succ:

Рис. R2

2) find path: алгоритм Дейкстры найдёт путь S-6-16-17-5in-8out-9-10-T, который будет представлен через parent (рис. R2).

3) adjust parents: зависит от реализации; идея в том, чтобы после выполнения следующего (4-го) шага через parent оказался представленным путь S-6-16-17-5-8-9-10-T.

4) restore graph: склеиваем вершины вдоль пути, который хранится в pred/succ: связи через links вновь приобретают такой вид, как на рис. A1, а поля parent имеют такие значения (рис. A2):

 room   |    S | 6 | 16 | 17 |  5 | 8 | 9 | 10 |  T
--------+------+---+----+----+----+---+---+----+----
 parent | NULL | S |  6 | 16 | 17 | 5 | 8 |  9 | 10

5) combine paths: совмещаем этот путь с тем, что хранится в pred/succ, убирая накладывающиеся участки (в данном случае участок 5-8 есть в обоих путях), получим:

 room |    S |  6 | 16 | 17 |  5 | 11 |  8 |  9 | 10 |    T
------+------+----+----+----+----+----+----+----+----+------
 pred | NULL |  S |  6 | 16 | 17 |  S | 11 |  8 |  9 | NULL
 succ | NULL | 16 | 17 |  5 |  T |  8 |  9 | 10 |  T | NULL

Это соответствует двум путям, которые изображены на рис. A3.

Третий запуск алгоритма

1) modify graph: делим вершины вдоль обоих путей, которые хранится в pred/succ:

Рис. R3 (На рисунке ошибка: стрелка из 5out должна идти не в 8out, а в 8in.)

2) find path: алгоритм Дейкстры найдёт путь S-1-2-3-4-5in-17out-17in-16out-16in-6out-7-8in-11out-12-13-14-15-T (рис. R3)

3) adjust parents: меняем поля parent так, чтобы после выполнения следующего шага они указывали путь S-1-2-3-4-5-17-16-6-7-8-11-12-13-14-15-T (рис. A4)

4) restore graph: склеиваем вершины вдоль обоих путей, которые хранится в pred/succ

5) combine paths: совмещаем новый путь (рис. A4) с теми двумя (рис. A3), устраняя наложения (участки 6-16-17-5 и 17-8)

 room |    S | 1 | 2 | 3 | 4 | 5 |   17 |   16
------+------+---+---+---+---+---+------+------
 pred | NULL | S | 1 | 2 | 3 | 4 | NULL | NULL
 succ | NULL | 2 | 3 | 4 | 5 | T | NULL | NULL

 room | 6 | 7 | 8 |  9 | 10 | 11 | 12 | 13 | 14 | 15 |    T
------+---+---+---+----+----+----+----+----+----+----+------
 pred | S | 6 | 7 |  8 |  9 |  S | 11 | 12 | 13 | 14 | NULL
 succ | 7 | 8 | 9 | 10 |  T | 12 | 13 | 14 | 15 |  T | NULL

Получили три пути, изображённые на рис. A5.


Дальше: Алгоритм Дейкстры