Re: коммивояжёр
- From
- Vitaly Lugovsky (2:5080/1003)
- To
- Oleg Khovayko
- Date
- 2003-01-16T18:01:25Z
- Area
- RU.ALGORITHMS
.n5080.z2.fidonet.ftn> <b02f2e$lpp$1@ddt.demos.su>
From: Vitaly Lugovsky <vsl@ontil.ihep.su>
Oleg Khovayko <olegh@hotpop.com> wrote:
> Так и быть, привожу решение:
>
> int NumWays(int I, int J, int K, vector< vector<int> > matrix) {
> vector<int> V(N);
> V[I] = 1;
> while(K--)
> V *= matrix; // тут векторное произведение вектора на матрицу
> return V[J];
> }
Так... Тут я погорячился. Обламываюсь с доказательством - оно
неэлементарное в достаточной мере для того, чтоб перевод в рекурсию вообще
считать за труд. Сам же алгоритм простенький, намного короче его и не
записать:
let numways n i j k m =
let v0 = Array.make n 0 in v0.(i) <- 1;
let v = dowhile (fun x -> vm_mul x m) k v0 in
v.(j)
> А вот еще один пример:
> Есть дерево. Задача: обойти дерево по слоям.
> Я утверждаю, что существует итеративное решение этой задачи,
> пропорциональное N, то есть каждый узел дерева посещается один раз.
>
> Рекуррентный алгоритм - в студию!
> А потом я дам итерационный...
Вот, типа, самый тупой и примитивный вариант:
let rec tfindl f nl =
let rec nxtlyr = function
hd :: tl ->
(match hd with
Tnode(v,l,r) -> if f v than raise (Found(v)) else
l::r::(nxtlyr tl)
)
| [] -> []
in tfindl f (nxtlyr nl)
Причём, тут рекурсия хвостовая - так что стек не растёт ни фига.
Нефункциональным тут является только исключение - но можно и без исключений
написать, мало что изменится.
Естественно, каждый узел дерева тут посещается лишь один раз.
--- ifmail v.2.15dev5
* Origin: (http://news.cca.usart.ru/) USURT's FidoNET<-> (2:5080/1003@fidonet)