我正在尝试使用C ++中的Backtracking和recursion来解决C ++中的magic square问题。特别适用于4x4阵列。
4x4魔方解决方案的示例如下,其中每行,每列和对角线添加34:
我所做的更改是:用户输入一些将启动算法的值。
我的算法是:
here您可以更好地欣赏图片。
我有一个关于算法如何解决带有回溯和递归的魔术方问题的概念,但我遇到了问题。
其中一个是:
成就不会使我的算法“忽略”用户已输入的值。
我在C ++中的代码位于Github的 link 中。这是代码:
#include <iostream>
using namespace std;
int sudoku[4][4];
int row = 0;
int column = 0;
bool isFull(int s[4][4]){
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if(s[4][4] == 0){
return false;
}
}
}
return true;
}
void printMatrix(int s[4][4]){
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
cout << sudoku[i][j] << " ";
}
cout << endl;
}
}
bool isAssigned(int row, int column){
if(row == 1 && column == 0 ||
row == 0 && column == 2 ||
row == 1 && column == 2){
return true;
} else return false;
}
bool verify(int s[4][4], int row, int column){
bool flag = false;
int sumrow = 0, sumcolumn = 0, sumDiagonal = 0, sumDiagonal2 = 0;
int value = 3;
for(int i = 0; i < 4; i++){
sumrow = sumrow + s[row][i];
sumcolumn = sumcolumn + s[i][column];
sumDiagonal = sumDiagonal + s[i][i];
sumDiagonal2 = sumDiagonal2 + s[i][value];
value--;
}
if(sumrow <= 34 && sumcolumn <= 34 && sumDiagonal2 <= 34 && sumDiagonal2 <= 34){
return true;
} else return false;
}
bool backtracking(int s[4][4], int row, int column){
if(isFull(s) == true){ //verify if there are no zeros in the matrix
printMatrix(sudoku);
cout<<"Solution find ";
}
else {
if(isAssigned(row, column) == false){ // verify if the cell is already assigned
for(int i = 1; i <= 16; i++){
s[row][column] = i; // assigned value
if(verify(s, row, column) == true){ // verify that the sum of the column, row and diagonal not greater 34
if(column == 4) {
row++;
column=0;
}
backtracking(s, row, column + 1); // recursion
printMatrix(s); // Print the matrix to see progress
cout<<endl;
} else { // the sum value exceeds 34
s[row][column] = 0;
return false;
}
}
}
}
}
int main(){
sudoku[1][0] = 5;
sudoku[0][2] = 15;
sudoku[1][2] = 10;
backtracking(sudoku, row, column);
return 0;
}
我的algorithm
主要是以下内容:
在这种情况下显然有一些功能,但是如果你看到我的code
,你就会意识到我会尝试做什么。
也许我的解决方法不起作用或不好。
本出版物的原因是,我需要帮助改进或需要帮助来解决代码问题。这是我运行的主要功能和输出:
bool backtracking(int s[4][4], int row, int column){
if(isFull(s) == true){ //verify if there are no zeros in the matrix
printMatrix(sudoku);
cout<<"Solution find ";
}
else {
if(isAssigned(row, column) == false){ // verify if the cell is already assigned
for(int i = 1; i <= 16; i++){
s[row][column] = i; // assigned value
if(verify(s, row, column) == true){ // verify that the sum of the column, row and diagonal not greater 34
if(column == 4) {
row++;
column=0;
}
backtracking(s, row, column + 1); // recursion
printMatrix(s); // Print the matrix to see progress
cout<<endl;
} else { // the sum value exceeds 34
s[row][column] = 0;
return false;
}
}
}
}
}
输出:
3 16 15 0
5 0 10 0
0 0 0 0
0 0 0 0
正如我之前所说,当我找到用户已分配的值时,我遇到了问题。 这是第一次使用回溯,这就是我觉得有点困难的原因。谢谢大家。
答案 0 :(得分:0)
嗯,是的,
最近不得不做类似的事情,有些地方可以做到这一点&#34;修复&#34;
从位图(1-16)开始,为网格中已分配的数字。即。用户输入的那些已标记为&#34;已使用&#34;。 仅为尚未在该位图中标记的网格指定数字。如果你使用非递归方法,需要使用一个堆栈来知道已经测试过哪些&#34; unset&#34;回溯时。如果使用递归方法(只有16个深度递归;))将位图和已经放置的方块作为副本传递,而不是引用;)