8皇后问题

传说中的问题。

传说中的算法:回溯法

Python实现:

def place\_queen(l):
    if type(l)==list:
        tq=l[-1]
        k=len(l)
        for i,iq in enumerate(l[0:-1],start=1):
            if iq==tq or abs(iq-tq)==abs(i-k):
                return False
        return True
def output\_queens(number,l,n):
    print "Solution:%d" % number
    for i in range(1,n+1):
        for j in range(1,n+1):
            if j==l[i-1]:
                print "1   ",
            else:
                print "0   ",
        print ''
def n\_queens(l,n):
    nCount=0
    l.append(0)
    while(len(l)):
        l[-1]=l[-1]+1
        while(l[-1]\<=n and not place\_queen(l)):
            l[-1]+=1
        if l[-1]\<=n:
            if len(l)==n:
                nCount+=1
                output\_queens(nCount,l,n)
            else:
                 l.append(0)
        else:
            l.pop()
    return nCount
def main():
    n=12
    l=[]
    nCount=n\_queens(l,n)
    print "There are %d solutions!" % nCount
if \_\_name\_\_=='\_\_main\_\_':
    import time
    start=time.clock()
    main()
    end=time.clock()
    print "Run time: %f seconds " % (end-start)

话说第一次感觉Python有点慢了。

当n=8时命令行下需要0.852626s,IDLE运行则需要16.468123s。而当n=12命令行下时需要266.441883s,就不在IDLE下运行了。

而C代码呢。n=8时,0.188s;n=12时,10.674s。

C真的快的如此彪悍。

附C代码:

出处:链接

\#include \
\#include \
\#include \
\#include \
\#define MAXNUMBER 20
//判断当前得到的解向量是否满足问题的解
bool place\_queen(int x[],int k)
{
    int i;
    for(i=1;i\
    {
        if((x[i]==x[k]) || (abs(x[i]-x[k])==abs(i-k)))
            return false;
    }
    return true;
}
//将结果简单信息打印到屏幕
void output\_queens(int x[],int n)
{
    for(int i=1;i\<=n;i++)
        printf("%3d",x[i]);
    printf("\\n");
}
//将结果详细信息写入文件
void output\_queens(FILE \*fp,int number,int x[],int n)
{
    fprintf(fp,"solution %d: ",number);
    for(int i=1;i\<=n;i++)
    {
        for(int j=1;j\<=n;j++)
        {
            if(j==x[i])
                fprintf(fp,"1  ");
            else
                fprintf(fp,"0  ");
        }
        fprintf(fp,"\\n");
    }
    fprintf(fp,"\\n");
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 \*  n后问题求解
 \*  input  : n, the number of queens
 \*  output : the vector of solution, X
 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
int n\_queens(FILE \*fp,int n,int x[])
{
    int nCount=0;    //解个数
    int k=1;        //先处理第1个皇后
    x[1]=0;
    while(k\>0)
    {
        x[k]=x[k]+1;//在当前列加1的位置开始搜索
        while(x[k]\<=n && !place\_queen(x,k))    //当前列位置是否满足条件
            x[k]=x[k]+1;    //不满足,继续搜索下一列位置
        if(x[k]\<=n)    //若存在满足条件的列
        {
            if(k==n)//是最后一个皇后,则得到一个最终解
            {
                //break;    //此处若break,则只能得到一个解
                nCount++;
                output\_queens(x,n);    //输出
                output\_queens(fp,nCount,x,n);
            }
            else    //否则,处理下一个皇后,即第 k+1 个皇后
            {
                k++;
                x[k]=0;
            }
        }
        else        //若不存在满足条件的列,则回溯
        {
            x[k]=0;    //第k个皇后复位为0
            k--;    //回溯到前一个皇后
        }
    }
    return nCount;
}
int main()
{
    int n=8,x[MAXNUMBER]={0};
    FILE \*fp=fopen("8皇后问题的解.txt","w");
    if(fp==NULL)
    {
        printf("can not wirte file!");
        exit(0);
    }
    printf("the queens are placed on the coloums : ");
    //求解并写入文件
    int nCount=n\_queens(fp,n,x);
    printf("there are %d solutions! ",nCount);
    fclose(fp);
    return 0;
}

Comments