В общем небольшая пердыстория. Писал я когда то в институте курсач по искусственному интелекту. Задание было - расставить N ферзей на доске N*N (что бы друг друга не били, ессно). Писал на Delphil. И вот недавно раскопал эту прогу, но в Делфи уже 100 лет не писал, отвык уже. Решил переписать на Builder. Так вот, переписал алгоритм на с++ (ничего особо не менял, чисто синтаксис под С переделал) все работает, результаты совпадают, но почему то работает раз в 100 медленнее. Например, доска 15*15 считается 40 секунд, а раньше были доли секунды. Я в шоке. Неужели компилятор Билдера настолько плохо оптимизирует по сравнению с Дельфи? Или я что то накосячил? Но явных ошибок вроде нет... Пробовал разные настройки компилятора - тоже самое.
Последний раз редактировалось Afx 13.07.2007 14:07, всего редактировалось 1 раз.
typedef int * CCoord; // массив будет содержить положения ферзя в каждой строке
bool f(CBord A, int m, int n, CCoord coord) // собственно функция. m - размерность доски, n - с какой строки начинать. { CBord B; int i; bool bResult = false;
if (n==1) // терминальная ситуация for (i = 0; i < m; i++) { if ( A.V[i] && A.D1[i+1] && A.D2[m+i-1]) // если есть куда поставить ферзя в последней строке { coord[0] = i; // ставим bResult = true; // и возращаем истину } } else { for (i = 0; i< m; i++) { if (A.V[i] && A.D1[i+n] && A.D2[m+i-n]) // ищем куда можно поставить ферзя { B = A; B.V[i] = 0; B.D1[i+n] = 0; B.D2[m+i-n] = 0; // отмечаем битые вертикаль и диагонали if (f(B,m,n-1,coord)) // рекурсивный вызов { bResult = true; coord[n-1] = i; } } }
} return bResult; }
Потом идет вызов основной программе:
Код:
CBord A; int coord[L];
for (int i = 0; i < L; i++) A.V[i] = 1; for (int i = 0; i < 2*L-1; i++) A.D1[i] = 1; for (int i = 0; i < 2*L-1; i++) A.D2[i] = 1; // вначале доска пустая
for (int i = 0; i < L; i++) coord[i] = 0; // обнуляем координаты
if f(A,L,L,coord) {/*сохранить в файл*/} ; // вычисляем расстановку, если F возвращает True, сохраняем координаты в файл.
А вот оригинал на дельфи:
Код:
const L = 15;
type bord = record V: array[1..L] of boolean; D1: array[1..2*L-1] of boolean; D2: array[1..2*L-1] of boolean; end;
Pos = array [1..L] of byte;
function f_optimized(A:bord; n,m:byte;var coord:pos):boolean;
implementation
function f(A:bord; n,m:byte;var coord:pos):boolean; var B:bord; i:byte; begin result:=false; if n=1 then begin for i:=1 to m do if A.V[i] and A.D1[i] and A.D2[m-i+1] then begin coord[1]:=i; result:=true; end end else begin for i:=1 to m do if A.V[i] then if A.D1[i+n-1] then if A.D2[m-i+n] then begin B:=A; B.V[i]:=false; B.D1[i+n-1]:=false; B.D2[m-i+n]:=false; if f(B,n-1,m,coord) then begin result:=true; coord[n]:=i; exit; end end; end; end;
И вызов из основной проги:
Код:
for i:=1 to l do A.V[i]:=true; for i:=1 to 2*l-1 do A.d1[i]:=true; for i:=1 to 2*l-1 do A.d2[i]:=true;
for i:=1 to m do coord[i]:=0;
if f(A,m,m,coord) then begin // сохранить коорд. в файл end;
Функции немного отличаются, т.к. в оригинале размер таблицы задавался переменной m, а в с++ я для простоты поставид константу. Но думаю это тут не причем. Добавлено спустя 7 минут, 44 секунды mein Алгоритмы разные. Я ищу только 1 решение (поиск в глубину), а там все решения, и это конечно намного медленнее. В курсаче поиск в ширину тоже был, но там стоит ограничение на размерность 12*12, т.к. больше нужно больше памяти. Под рукой дистриба дельфи нет, что бы поправить. На доске 12*12 все варианты старый вариант считает 0.4 сек (это на прескоте 3.0 ггц). А дельфофская прога при поиске в глубину даже на 37*37 могла расчитать (это максимум что я расчитывал) примерно за 10 минут на P4-3 GHz и 5 минут на профильном компе.
Member
Статус: Не в сети Регистрация: 07.10.2003 Откуда: Russia, Moscow
сравнивать надо на одном компе в один день. Возможно, что-то нашаманено в настройках компилятора билдера.
по алгоритму - смотреть особо времени нет, но в дельфи увидел exit; в цикле.
_________________ В поиске включайте "Искать все слова". Избегайте многоточий.
Зачем нужен разгон? http://tsc.overclockers.ru
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения