Время
Все узлы в дереве должны быть сгенерированы один раз в какой-то момент, и предполагается, что генерация узла требует постоянного времени c
(постоянное время может варьироваться, вы можете просто выбрать c
, чтобы быть наибольшее постоянное время для генерации любого узла). Порядок определяется алгоритмом и гарантирует, что узлы не нужно многократно расширять.
nodes b=2 b=3
b^0 * *
/ \ / | \
b^1 * * * * *
/ \ / \ / | \ / | \ / | \
b^2 * * * * * * * * * * * * *
... ...
Как видно на рисунке, для расчета первого уровня стоит c*b^0
стоимость - в точности c
. Следующий уровень в дереве будет содержать b^1
узлов, а генерация второго уровня будет стоить c*b^1 = c*b
. Для третьего уровня снова будет b
узлов для каждого узла на втором уровне, это означает b*b^1 = b^2$
узлов и стоимость c*b^2
.
На самом глубоком уровне дерева на глубине d
будет b^d
узлов, работа на этом уровне для этого будет c*b^d
. Общий объем проделанной работы к этому моменту составляет c*b^0 + c*b^1 + ... + c*b^d
. Для сложности мы смотрим только на самый быстро растущий член и отбрасываем константу, чтобы получить:
O(c + c*b + ... + c*b^d) = O(c*b^d) = O(b^d)
.
По существу : время является функцией f(d) = SUM(i=1..d){c*b^i}
и O(f(d)) = O(b^d)
.
Space
На рисунке показан алгоритм на разных этапах для b=3
. *
обозначает развернутые в данный момент узлы, ?
обозначает неизвестные узлы, а +
обозначает узлы, оценка которых была полностью рассчитана.
branching factor b = 3 space
* * * * b
/ | \ / | \ / | \ / | \
* ? ? * ? ? + * ? + + * b
/ | \ / | \ / | \ / | \
* ? ? + + * + * ? + + * b
/ | \ / | \ / | \ / | \
* ? ? + * ? + * ? + + * b
Чтобы вычислить оценку узла, вы расширяете узел, выбираете дочерний элемент и рекурсивно расширяетесь, пока не достигнете конечного узла на глубине d
. Как только дочерний узел полностью рассчитан, вы переходите к следующему дочернему узлу. Как только все b
дочерние узлы вычислены, оценка родителей рассчитывается на основе дочерних узлов, и в этот момент дочерние узлы могут быть удалены из хранилища. Это показано на рисунке выше, где алгоритм показан на 4 разных этапах.
В любой момент у вас есть один раскрытый путь, и вам нужно c*b
хранилище для хранения всех дочерних узлов на каждом уровне. Здесь снова предполагается, что вам нужно постоянное количество места на узел. Ключ в том, что любое поддерево можно обобщить по его корню. Поскольку максимальная длина пути равна d
, вам максимально потребуется c*b*d
пространства. Как и выше, мы можем отбросить постоянные условия и получить O(c*b*d) = O(b*d)
.