实现回溯N-Queens算法

时间:2015-10-31 05:30:46

标签: c algorithm n-queens

我在C中实现了一个算法来解决N-Queens问题。我的代码解决了n = 4的问题,但不适用于n的任何其他值。我认为问题可能出在打印代码中,但我不确定。我尝试过改变for循环中的条件,但还没有发现任何有效的东西。我还需要在求解时找到从解决方案树中删除的节点数。我该如何解决此问题并找到已修剪的节点数?

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int count = 0;

void queens(int n, int row, int col[]);
int promising(int row, int col[]);
void usage(char *argv);

int main(int argc, char *argv[])
{    
    if (argc < 2) { usage(argv[0]); }
    int n = atoi(argv[1]);
    int col[n];
    queens(n, 0, col);
}

void queens(int n, int row, int *col)
{
    int index;

    if (promising(row, col))
    {
        if (row == n)
        {
            printf("\nSolution %d\n------------\n", ++count);
            for (int i = 1; i <= n; i++, putchar('\n')) // This works for n = 4.            
            {
                for (int j = 0; j <= n - 1; j++) // This works for n = 4.
                {                    
                    if (j == col[i]) { putchar('Q'); }
                    else { putchar('*'); }
                }
            }
            return;
        }
        else
        {
            for (index = 0; index < n; index++)
            {
                col[row + 1] = index;
                queens(n, row + 1, col);
            }
        }
    }
}

int promising(int row, int *col)
{
    int index;
    int is_promising;

    index = 0;
    is_promising = 1;
    while (index < row && is_promising)
    {
        if (col[row] == col[index] || abs(col[row] - col[index]) == row - index)
        {
            is_promising = 0;
        }
        index++;
    }
    return is_promising;
}

void usage(char *argv)
{
    printf("usage: %s <number of queens>", argv);
    exit(0);
}

1 个答案:

答案 0 :(得分:2)

您的代码存在多个问题:

您对索引范围不够系统:您使用0n1n-1,包含或排除(运营商<=和{ {1}})混淆读者......并在访问<时调用未定义的行为。根据经验:在C中,有cols[n],有一个错误

您没有在<=函数中正确测试终止:在枚举当前行的所有可能列之前,不先测试终止,而是首先测试充分性:因此,您错过了那里的所有解决方案在A1单元格中不是女王。

以下是更正后的简化版本:

queens

该算法使用蛮力,你仍然需要做一些工作来计算修剪过的节点等。