【问题标题】:Knight Tour using backtrackingKnight Tour 使用回溯
【发布时间】:2013-12-03 13:00:21
【问题描述】:

我正在使用回溯在 C++ 中开发骑士之旅的程序 这是我的代码:

#include <iostream>
#include <iomanip>
using namespace std;

template <class T>
class Stack
{
public:
    Stack(int len = 100)
    {
        length = len;
        sp = -1;
        a = new T [length];
    }

    int getLength()
    {
        return length;
    }

    void push(T v)
    {
        if(isFull())
        {
            throw std::exception("Stack Overflow!");
            return;
        }
        a[++sp] = v;
    }
    bool isFull()
    {
        if(sp < getLength()-1)
            return false;
        return true;
    }
    T pop()
    {
        if(isEmpty())
        {
            throw std::exception("Stack Underflow!");
        }
        return a[sp--];
    }
    bool isEmpty()
    {
        if(sp == -1)
            return true;
        return false;
    }
    T getTop()
    {
        if(isEmpty())
        {
            throw std::exception("Stack Underflow!");
        }
        return a[sp];
    }

private:
    T * a;
    int sp;
    int length;

};

class MoveStk
{
public:
    MoveStk()
    {
        set(0,0,0);
    }

    MoveStk(int r , int c , int d)
    {
        set(r,c,d);
    }

    void set(int r , int c , int d)
    {
        row = r;
        col = c;
        dir = d;
    }

    void get(int& r , int & c , int & d)
    {
        r = row;
        c = col;
        d = dir;
    }

private:
    int row , col , dir;
};

class Position
{
public:
    int x , y;
    Position(int i = 0 , int j = 0)
    {
        x = i;
        y = j;
    }
};


bool move(Position pos[],int posLen,int ** chess ,int n, int col, int row , int&newRow , int & newCol , int moveNo )
{
    if (row+pos[moveNo].x>=0 && row+pos[moveNo].x<n && col+pos[moveNo].y>=0 && col+pos[moveNo].y<n && chess[row+pos[moveNo].x][col+pos[moveNo].y] == 0 )
    {
        newRow = row+pos[moveNo].x;
        newCol = col+pos[moveNo].y;
        return true;
    }
    return false;
}

int main()
{

    int n = 8;

    //create stack
    Stack<MoveStk> myStack(100);



    //create dynamic array
    int ** chess = new int* [n];
    for (int i = 0; i < n; i++)
        chess[i] = new int[n];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            chess[i][j] = 0;

    //setup moves
    Position pos[8];

    pos[0] = Position(-2,1);
    pos[1] = Position(-2,-1);
    pos[2] = Position(2,1);
    pos[3] = Position(2,-1);
    pos[4] = Position(-1,-2);
    pos[5] = Position(-1,2);
    pos[6] = Position(1,2);
    pos[7] = Position(1,-2);


    //input for start (must be optional) :
    int row = 4;
    int col = 3;


    int count = 1 , moveChoose = 0;
    int newCol , newRow;

    MoveStk temp(row,col,0);//adding first move to stack
    myStack.push(temp);

    chess[row][col] = count;

    while(count<=(n*n) && !myStack.isEmpty())
    {
        temp = myStack.getTop();
        temp.set(row,col,moveChoose);

        while(moveChoose<8 && !move(pos,8,chess,n,col,row,newRow,newCol,moveChoose))//avalin khoone azad baray karkat
        {
            moveChoose++;
        }

        if(moveChoose != 8)//there is somewhere we can go
        {
            myStack.pop();
            temp.set(col,row,moveChoose+1);//adding next possible move for returning back
            myStack.push(temp);
            chess[newRow][newCol] = ++count;
            temp.set(newRow,newCol,0);
            myStack.push(temp);
        }
        else//we must return
        {
            myStack.pop();
            chess[newRow][newCol] = 0;
            count--;
        }

    }

    printArray(chess);

    cin.ignore();
    cin.get();
}

问题是,这个应用程序只适用于第一步,我的堆栈在结束游戏之前会变空。 我找不到哪里错了?!

可能是什么问题?

【问题讨论】:

  • 调试告诉你什么?
  • @Angew 我无法通过调试应用程序找到问题...
  • 尝试打印出您的rowcolmoveChoosepushpop 事件,看看您的递归是否按照您认为的方式工作...
  • 您需要在每个循环的顶部将 moveChoose 重置为 0。
  • @Trenin:我怀疑这是一个可怕的想法。

标签: c++ stack backtracking knights-tour


【解决方案1】:

首先,我认为你需要换行:

while(count<=(n*n) && !myStack.isEmpty())
{
    temp = myStack.getTop();
    temp.set(row,col,moveChoose);

收件人:

while(count<=(n*n) && !myStack.isEmpty())
{
    temp = myStack.getTop();
    temp.get(row,col,moveChoose);

就目前而言,每次循环时,您都会覆盖上一次移动和位置。你应该做的是从你离开的地方开始,尝试从上一个位置开始下一步。

另外,我注意到您稍后在 set 调用中设置了错误的参数:

        temp.set(col,row,moveChoose+1);//adding next possible move for returning back

应该是row,然后是col

【讨论】:

  • 感谢您的回答,现在它适用于大约 55 个动作……但不是全部。你知道为什么吗?
  • 查看en.wikipedia.org/wiki/Knight%27s_tour。这是蛮力的困难问题。您需要实施启发式方法来修剪搜索。
猜你喜欢
  • 2021-07-16
  • 2021-09-07
  • 2016-08-03
  • 2022-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多