Re: коммивояжёр
- From
- Oleg I. Khovayko ()
- To
- Vitaly Lugovsky
- Date
- 2003-01-17T17:48:11Z
- Area
- RU.ALGORITHMS
.n5080.z2.fidonet.ftn> <b02f2e$lpp$1@ddt.demos.su> <3377601035@f1003.n5080.z2.fidonet.ftn>
From: "Oleg I. Khovayko" <olegh@ncbi.nlm.nih.gov>
> считать за труд. Сам же алгоритм простенький, намного короче его и не
> записать:
Итак, Вы признали, что применение рекурсии не дает пользы
дла решения первого примера. И даже написали свое решение,
которое точь-в-точь воспроизводит приведенный мною алгоритм на ML-e.
Хочу отметить еще такой момент: Сначала я дал описание
задачи (что бы подумать), а потом с задержкой привел решение.
Судя по Вашей реакции, вначале Вы не поверили, что матричный
алгоритм и есть решение задачи, и требовали от меня доказательств
адекватности приведенного алгоритма поставлений задаче.
Отсюда вывод: Ваши рекурсивные изыскания в области
разработки алгоритма явно лежали в стороне от правильного
решения. Следовательно, знание рекурсии во всех ее проявлениях
не сильно помогло Вам самому разработать правильный алгоритм
для решения этой задачи. И где-то сутки Вам потребовались,
чтобы убедиться в адекватности приведенного мною матричного
алгоритма поставленой задаче.
Напоминаю: на topcoder-e люди, не зацикленые исключительно
на рекурсии, такой алгоритм разрабатывают и кодируют примерно
за 40 минут.
То есть человек получил описание задачи
(не способа ее решения, а именно описание задачи) - и через
40 минут засабмитил безглючный код, решающий эту задачу.
----------------------------------------------------------
Перейдем теперь к сравнению примеров:
**** Первый пример:
Итерацинное решение от меня:
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)
**** Второй пример:
Мое итерационное решение:
queue<Node*> q;
q.put(&root);
while(!q.empty()) {
Node *cur = q.get();
do_something(cur); // Processing current node
q.put(cur->left); q.put(cur->right);
}
Ваше рекурсивное решение:
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) | Tnone -> nxtlyr tl
)
| [] -> []
in tfindl f (nxtlyr nl)
--------
Теперь пусть обшество сравнит приведенные примеры,
и выскажет свое мнение в пользу читабельности, понятности,
компактности, эффективности и возможности анализа того или
иного алгоритма и приведенной в примерах его реализации.
В обшем же случае вопрос стоит так: Сильно ли рекурсия облегчила
жизнь при решении вышеприведенных задач-примеров?
Покамест же я не вижу реальных преимушеств Вашего подхода
перед классическим.
Резюмирую же я свой ответ фразой из произведения Михаила Афанасьевича Булгакова:
"Вы, профессор, воля ваша, что-то нескладное придумали! Оно,
может, и умно, но больно непонятно. Над вами потешаться будут".
--
#include <best/regards.hpp>
Oleg I. KHOVAYKO
(301)435-5885 || WEB: http://olegh.spedia.net
--- ifmail v.2.15dev5
* Origin: National Center for Biotechnology Information (2:5020/400)