【问题标题】:Eight Queens using backtracking and recursion c++八皇后使用回溯和递归 C++
【发布时间】:2015-02-04 06:35:46
【问题描述】:

我刚刚学习了回溯和递归,并且有一个在八皇后问题中使用它的任务。我应该提示用户输入一行,然后程序 place_next_queen(bool& done) 应该尝试将下一个皇后放在下一列。这个过程是递归函数,我相信这就是问题所在。请看一下,任何帮助将不胜感激!如果您需要更多信息,请告诉我... 问题是程序在第一列中正确打印出 1,但板子的其余部分全为零。

这是我的班级八皇后问题:

class EightQueensProblem
{
public:
//Default constructor, initializes NUM_QUEENS to 8 in initializer list
EightQueensProblem() : NUM_QUEENS(8){}; 
void clear_board();
void display_board(ostream& os);
bool queen_under_attack(int row, int column);
bool start_game(int row);
private:
static const int CHESSBOARD_SIZE = 8; 
//2D array of int values not on the heap of dimension CHESSBOARD_SIZE x CHESSBOARD_SIZE
int chessboard[CHESSBOARD_SIZE][CHESSBOARD_SIZE];
const int NUM_QUEENS;
//int representing number of queens currently placed on the chessboard
int num_queens_on_board;
void place_queen_on_square(int row, int column);
void remove_queen_from_square(int row, int column);
void place_next_queen(bool& done);
};

void EightQueensProblem::clear_board()
{
//resets all squares on chessboard to value 0
for(int row = 0; row < CHESSBOARD_SIZE; row ++)
{
    for(int column = 0; column < CHESSBOARD_SIZE; column ++)
    {
        chessboard[row][column] = 0;
    }
}
//sets number of queens on board to 0
num_queens_on_board = 0;
}

void EightQueensProblem::display_board(ostream& os)
{
//outputs chessboard to given output stream without changing calling object
for(int row = 0; row < CHESSBOARD_SIZE; row ++)
{
    for(int column = 0; column < CHESSBOARD_SIZE; column++)
    {
        os << chessboard[row][column] << " ";
    }
    os << endl;
}
}

bool EightQueensProblem::queen_under_attack(int row, int column)
{
//detect if a queen occupies a square along the southwest diagonal of square (row, col)
for(int i = 0; (row + i) < CHESSBOARD_SIZE && (column - i) >= 0; i ++)
{
    if(chessboard[row + 1][column - i] != 0)
        return true;
}
//along southeast diagonal
for(int i = 0; (row + i) < CHESSBOARD_SIZE && (column + i) < CHESSBOARD_SIZE; i ++)
{
    if(chessboard[row + i][column + i] != 0)
        return true;
}
//along northwest diagonal
for(int i = 0; (row - i) >= 0 && (column - i) >= 0; i ++)
{
    if(chessboard[row - i][column - i] != 0)
        return true;
}
//along northeast diagonal
for(int i = 0; (row - i) >= 0 && (column + i) < CHESSBOARD_SIZE; i ++)
{
    if(chessboard[row - i][column + i] != 0)
        return true;
}
//along same row
for(int i = 0; i < CHESSBOARD_SIZE; i ++)
{
    if(chessboard[row][i] != 0)
        return true;
}
//along same column
for(int i = 0; i < CHESSBOARD_SIZE; i ++)
{
    if(chessboard[i][column] != 0)
        return true;
}
return false;
}

bool EightQueensProblem::start_game(int row)
{
//places the first queen at the given row in the left most column
chessboard[row][0] = 1;
    num_queens_on_board = 1;
bool done;
place_next_queen(done);
if(done == true)
    return true;
else
    return false;
}

void EightQueensProblem::place_queen_on_square(int row, int column)
{
//places a queen on the board at the given location (row, column)
chessboard[row][column] = column + 1;
    num_queens_on_board++;
}

void EightQueensProblem::remove_queen_from_square(int row, int column)
{
//removes a queen from the board at the given location (row, column)
chessboard[row][column] = 0;
    num_queens_on_board--;
}

void EightQueensProblem::place_next_queen(bool& done)
{
if(num_queens_on_board == NUM_QUEENS)
{
    done = true;
}
else
{
    done = false;
    for(int row = 0; row < (num_queens_on_board - 1); row ++)
{
    if(!queen_under_attack(row, num_queens_on_board))
    {
        place_queen_on_square(row, num_queens_on_board);
        place_next_queen(done);
    }
    else
    {
        remove_queen_from_square(row, num_queens_on_board);
        row ++;
        place_queen_on_square(row, num_queens_on_board);
        place_next_queen(done);
    }
}
    }
    }

这是我的主要功能:

int main()
{
cout << "Position the first queen on the chessboard:" << endl << endl;
cout << "Enter the row for the first queen (from 1 to 8): ";
int input_row;
cin >> input_row;
cout << "From the position (" << input_row << ", 1), the EightQueensProblem has solution: " << endl << endl;

EightQueensProblem game;
game.clear_board();
game.start_game(input_row);
game.display_board(cout);
string TargetFileName = "Solutions.txt";
ofstream out(TargetFileName);
game.display_board(out);
out.close();

return 0;
}

【问题讨论】:

  • 那么,问题是什么?你的程序在哪里失败?阅读How to Ask
  • 哦,问题是程序在第一列正确打印出1,但板子的其余部分全为零。
  • 我对你的主要功能很好奇,因为整个事情对我来说简直就是崩溃。
  • 大卫,我已经添加了我的主要功能。

标签: c++ recursion boolean backtracking


【解决方案1】:

这不是解决方案,但评论太长了。解决问题后,我将对其进行编辑。

这是如何工作的完全超出了我的范围。我直接复制了你的代码,保存main函数,就是:

int main() {
    EightQueensProblem e;

    e.clear_board();
    e.start_game(1);
    e.display_board(cout);
}
  1. 游戏通过在棋盘上放置皇后开始
  2. 召唤下一个女王
  3. num_queens_on_board,永远不变,还是0
  4. queen_under_attack 返回真(总是)
  5. 之前放置的皇后被移除(为什么?)
  6. 一个新的被放置
  7. 重复 2-7

有点讽刺的是,由于递归遵循相同的步骤,它永远不会停止,我得到了一个 StackOverflow。我认为你需要逐步检查你的逻辑,(很容易使用调试器)并修复你出错的地方。

【讨论】:

  • 我已经意识到,当我复制和粘贴代码时,有几件事被遗漏了,试图正确格式化它。对不起。我已经编辑了它,所以现在 num_queens_on_board 应该改变。请使用这个新代码。 Queen_under_attack 不应该返回 true ......我做错了吗?
  • 另外,我删除之前放置的女王的原因是因为我试图回溯。大概是做错了吧?我是否可以将那部分全部省略,并暗示女王将被移除?
  • 我认为只有在找到打开的东西后才放置东西会更容易,而不是放置、移除、放置、移除。您是否尝试过使用调试器来单步调试您的代码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 2013-12-27
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多