Возможно, алгоритм моего рыцарского тура работает в бесконечном цикле

Вот код, который я написал.

#include "genlib.h"
#include <iostream>
#include <math.h>
#include "vector.h"

struct square
{
    int x;
    int y;

};


bool knighttour(square start,int &counter,int cb[][8]);
Vector <square> generatemoves (square start);
void Marksquare(int &cb,int ctr);
void Unmarksquare(int &cb);
bool IsLegal(square a,int cb[][8]);




int main() 
{
    int chessboard[8][8];

    for (int i=0;i<8;i++)
        for (int j=0;j<8;j++)
            chessboard[i][j]=-1;

    int counter=1;

    for (int i=0;i<8;i++){
        for (int j=0;j<8;j++){
            square temp;
            temp.x=i;
            temp.y=j;
            if (knighttour(temp,counter,chessboard))
            {
                for (int k=0;k<8;k++){
                    cout<<chessboard[k][0]<<chessboard[k][1]<<chessboard[k][2]<<chessboard[k][3]<<chessboard[k][4]<<chessboard[k][5];
                    cout<<chessboard[k][6]<<chessboard[k][7]<<endl;}


            }

        }
    }


    return 0;
}


bool knighttour(square pt,int &counter,int cb[][8])
{

    Marksquare(cb[pt.x][pt.y],counter);
    if (counter==64)
        return true;

    counter++;

    Vector <square> temp = generatemoves(pt);

    for (int i=0;i<temp.size();i++)
    {
        if (IsLegal(temp[i],cb))
            knighttour(temp[i],counter,cb);
    }

    Unmarksquare(cb[pt.x][pt.y]);
    counter--;
    return false;

}



Vector <square> generatemoves (square start)
{
    Vector <square> temp;
    Vector <square> temp2;

        square mv1;
        mv1.x=start.x+2;
        mv1.y=start.y+1;
        temp.add(mv1);

        square mv2;
        mv2.x=mv1.x;
        mv2.y=start.y-1;
        temp.add(mv2);


        square mv3;
        mv3.y=start.y+2;
        mv3.x=start.x+1;
        temp.add(mv3);

        square mv4;
        mv4.y=start.y+2;
        mv4.x=start.x-1;
        temp.add(mv4);

        square mv5;
        mv5.x=start.x-2;
        mv5.y=start.y+1;
        temp.add(mv5);

        square mv6;
        mv6.x=start.x-2;
        mv6.y=start.y-1;
        temp.add(mv6);

        square mv7;
        mv7.y=start.y-2;
        mv7.x=start.x-1;
        temp.add(mv7);

        square mv8;
        mv8.y=start.y-2;
        mv8.x=start.x+1;
        temp.add(mv8);


        for (int i=0;i<temp.size();i++)
            if (temp[i].x>=0 && temp[i].x<=7 && temp[i].y>=0 && temp[i].y<=7)
                temp2.add(temp[i]);




        return temp2;
}



void Marksquare(int &a,int ctr)
{
    a=ctr;

}



void Unmarksquare(int &a)
{
    a=-1;
}


bool IsLegal(square a,int cb[][8])
{
    if (cb[a.x][a.y]==-1)
        return true;
    else 
        return false;
}

Небольшое объяснение. Я использую int [8] [8] для представления шахматной доски, и сначала я помещаю в каждую клетку доски число -1.

Когда конь движется, он отмечает квадрат, который он посещает с помощью счетчика (int counter), и оттуда (и для всех разрешенных ходов, которые может сделать рыцарь) делает рекурсивные вызовы, чтобы найти путь (цель состоит в том, чтобы посетить каждую клетку ровно один раз. ).

Как только счетчик достигнет 64, функция bool knighttour(square start,int &counter,int cb[][8]) должна вернуть истину, а затем основная программа должна отобразить «тур коня», как он отмечен на шахматной доске [8] [8].

Я считаю, что приведенный выше код работает в бесконечном цикле. Я дал ему поработать 3 минуты.


person Vaios Argiropoulos    schedule 20.09.2011    source источник
comment
Добро пожаловать в мир экспоненциальных алгоритмов.   -  person Jon    schedule 21.09.2011
comment
Возможно ли, что я не даю достаточно времени для его запуска?   -  person Vaios Argiropoulos    schedule 21.09.2011
comment
запустите программу, запустите gdb и подключите его к работающему pid, затем нажмите ctrl-c, чтобы прервать выполнение. Исследуйте стек с помощью bt full. Тогда возвращайся сюда, если не понимаешь, что происходит   -  person Fredrik Pihl    schedule 21.09.2011
comment
Вы можете просто knighttour печатать значение counter каждый раз, когда оно вводится, чтобы вы могли наблюдать, что происходит.   -  person Jon    schedule 21.09.2011


Ответы (3)


Согласно теории:

... Важно отметить, что исчерпывающий метод грубой силы (тот, который повторяет все возможные последовательности ходов) никогда не может быть применен к задаче Knight's Tour (за исключением очень маленьких размеров доски). Для обычной шахматной доски 8x8 существует приблизительно 4 × 1051 возможных последовательностей ходов [9], и на повторение такого большого количества ходов уйдет непостижимое количество времени.

Поэтому, чтобы убедиться, что ваша программа работает, попробуйте использовать плату меньшего размера (скажем, 4x4).

Чтобы ваша программа работала для 8x8 в разумные сроки, вам придется изменить алгоритм. Их еще много, помимо перечисленных здесь.

--редактировать--

Кроме того, чтобы убедиться, что ваша программа что-то делает, всегда полезно добавлять следы, пока вы ее еще разрабатываете.

E.g.

bool knighttour(square pt,int &counter,int cb[][8]) {

printf("\r%d    ", counter);  // <<<---
Marksquare(cb[pt.x][pt.y],counter);
if (counter==64)
    return true;

counter++;

Vector <square> temp = generatemoves(pt);

for (int i=0;i<temp.size();i++)
{
    if (IsLegal(temp[i],cb))
        knighttour(temp[i],counter,cb);
}

Unmarksquare(cb[pt.x][pt.y]);
counter--;
return false;

}
person Kashyap    schedule 20.09.2011

Этот код, вероятно, пытается найти все возможные маршруты в Knights Tour и вернет последний найденный маршрут.

Вместо того

for (int i=0;i<temp.size();i++)
{
    if (IsLegal(temp[i],cb))
        knighttour(temp[i],counter,cb);
}

Пытаться

for (int i=0;i<temp.size();i++)
{
    if (IsLegal(temp[i],cb))
    {
        if(knighttour(temp[i],counter,cb))
        { 
             return true;
        }
    }

}
person Luka Rahne    schedule 20.09.2011

Я вижу одну вещь: хотя вы return true когда counter==64 в knighttour, это не распространяется, вызывающая его функция вернет false ... так что вы никогда не заметите этого в main ().

Тем не менее, даже если вы исправите свой алгоритм, он может не закончиться в течение вашей жизни.

person Karoly Horvath    schedule 20.09.2011