简体   繁体   中英

Magic square backtracking and recursion C++

I'm trying to solve the problem of the magic square in C ++ using Backtracking and recursion in C ++. Specifically for a 4x4 array.

An example of 4x4 magic square solution is as follows, in which each row, column and diagonal add 34:

在此输入图像描述

The change that I have is this: The user enters some values that will start the algorithm.

My algorithm is this:

在此输入图像描述

here you can appreciate better the image .

I have a notion of how the algorithm should work to solve the problem of the magic square with backtracking and recursion, but I've had problems.

One of them is:

Achievement not make my algorithm "ignore" the values that the user already entered.

My code in C++ is in this link in Github. And here is the code :

#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;
}

My algorithm is mainly the following:

在此输入图像描述

Obviously some features in this case, but if you see my code you will realize what I try to do.

Perhaps my solution method does not work or is not good.

The reason for this publication is, I need help to improve or Need help to solve the code did. Here is my main function and output I get to run:

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;
                }
            }
        }
    }
}

output:

3  16  15  0
5  0  10   0
0  0  0    0
0  0  0    0

as I said before, I have problems when I find a value that the user was already assigned. It is the first time working with backtracking, that is why I find it a bit difficult. Thanks for all.

Well, yes,

Had to do something similar lately, some places to get this "fixed"

Start with a bitmap (1-16) for the numbers already assigned in the grid. ie. those the user entered are already marked as being "used". Only assign numbers to the grid that haven't been marked in that bitmap. If you use non-recursive methods, need to use a stack to know which have been tested to "unset" when backtracking. If using recursive methods (only 16 deep recursion ;) ) pass the bitmap and the already placed square as copies, not references ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM