论文网
English Papers
万事OK网
发表论文
 
 首页 > IT文章 > 程序设计 >
采用比特位运算改进的N皇后算法

[科技论文网] http://www.scipapers.com    2007-12-01  

    采用比特位运算改进的N皇后算法

     目前最快的N皇后递归解决方法                                          */
    #include <iostream>
    using namespace std;
    #include 
    <time.h>
    long sum=0,upperlim=1;
    //该算法的思想是遍历每一行(虽然算法中没有直接体现行遍历),然后对每一行中的所有
    //有效列(即与上面行已放置皇后在列和左右对角线方向上不会造成冲突的列)进行尝试
    //row是代表已经遍历的列,1表示该列已被皇后占有了
    void GetSum(long row, long rightdiagonal, long leftdiagonal)
    ...
    {
        
    //每一列都被皇后占领了,表示该方案可行
        if (row != upperlim)
        ...
    {
            
    //下面进行行遍历
            
    //row表示当前行中每一列放置了皇后,则该列在之后的行遍历中均不能再放置皇后了
            
    //rightdiagonal表示在下一行的尝试中当前放置点的左一列位置(下一行左一列的点与当前放置
            
    //点刚好形成了右对角线,会造成冲突)不可用
            
    //同样的leftdiagonal表示在下一行的尝试中当前放置点的右一列(下一行右一列的点与当前放置
            
    //点刚好形成了左对角线,会造成冲突)不可用
            long pos = upperlim & ~(row | leftdiagonal | rightdiagonal);
            
    //这里得到该行中所有可以尝试的列(格),然后从右到左进行尝试
            
    //如果遍历到的该行上的每一列已经都是无效的话则无需进行下一行的尝试了
            while (pos)
            ...
    {
                
    //该位操作能得到一个二进制数组中最右面的1的位置,如pos = 00010110进行如下操作之后
                
    //p = 00000010,p的作用是取得当前遍历的行中所有有效列的最右面的一列(格)(其实每次取
                
    //最左的列也行的)
                long p = pos & -pos;
                pos 
    -= p;
                
    //p代表的是当前行上放置的列,递归调用函数遍历下一行
                
    //此时需将本行的尝试的列在row中标记上表明下一行不可再在此列放置皇后了
                
    //同时,在下一行中本放置点的左一列和右一列也需标记为不可再放置
                GetSum(row+p, (rightdiagonal+p)<<1, (leftdiagonal+p)>>1);
            }

        }

        
    else
        ...
    {
            sum
    ++;
        }

    }

    int main(int argc, char *argv[])
    ...
    {
        time_t tm; 
    int n=15;
        
    if(argc!=1)
            n
    =atoi(argv[1]);
        tm
    =time(0);
        
    if((n<1)||(n>32))
        ...
    {
            printf(
    " heh..I can't calculate that. ");
            exit(
    -1);
        }


        printf(
    "%d Queens ",n);
        
    //upperlim中前n位为1,用于标识探索是否已完成
        upperlim=(upperlim<<n) - 1;
        GetSum(
    0,0,0);
        printf(
    "Number of solutions is %ld, %d seconds ", sum,(int)(time(0)-tm));
        
    return 0;
    }


    下面一段转的是人家用string类写的一个实现.效率较低,但是比较好懂

    #include 
    <iostream>
    #include 
    <string>
    using namespace std;
    //t表示被占领的行,s表示未测试过的行
    void queen(const string t, const string s)
    {
        
    if (s=="") printf("%s  ",t.c_str());
        
    else
            
    //第一个for循环测试当前测试列的每一行
            for (int i=0; i<s.length(); i++{
                
    bool safe=true;
                
    //第二个for循环测试当前点与之前点是否处于同一对角线上
                
    //由于字符串的设计巧妙,使判断冲突情况限制在了对角线的情况上而已
                for (int j=0;j<t.length();j++)
                
    {
                    
    //列间隔等于行间隔
                    if (t.length()-j==abs(s[i]-t[j]))
                    
    {
                        safe
    =false;
                        
    break;
                    }

                }

                
    if (safe)
                    queen(t
    +s[i], s.substr(0,i)+s.substr(i+1));
            }

    }


    int main()
    {
        
    //string中的每一位代表一列,从左到右开始,而每一位中的数字代表了每一行
        
    //由于每个位的数字都是唯一的,因此可以保证已测试列和待测试列之间不会有
        
    //行相同的情况
        string s="01234567";
        queen(
    "",s);
        exit(EXIT_SUCCESS);
        
    return 0;
    }

        来源:

声明:本文由网友推荐或作者提交,版权归原作者所有,刊登此文仅为传播知识,展示研究成果,提高文章引用率。未经原作者授权,禁止用于任何形式的商业行为。科技论文网倡导尊重知识、尊重劳动、保护原创、知识共享。由于部分论文文章来于网络,文章作者不祥,请相关的原创作者与我们联系,以便加上您的署名。

  
采用比特位运算改进的N皇后算法
下面没有链接了     快速排序C语言实现
最新论文
·[程序设计]采用比特位运算改进的N皇后算法
·[程序设计]快速排序C语言实现
·[程序设计]SHA1算法源代码
·[程序设计]利用二叉树结构的快速排序
·[程序设计]C语言有头结点链表的经典实现
·[程序设计]算法——动态规划法
·[程序设计]回溯法:子集树与排列树
·[程序设计]有序表的查找(折半查找)
·[程序设计]全排列问题(回溯求解)
·[程序设计]模式匹配之Boyer-Moore算法
 
 

搜索论文

Google
论文分类

论文网 论文发表网 论文 免费论文网 找论文网 毕业论文 中国论文网 英语论文 百度论文 聘教网 易搜
 免费发布论文    中国论文网 2008版权所有  业务联系:pinjiao@126.com