论坛首页 Java企业应用论坛

目前最快的N皇后问题算法!!!

浏览 18541 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-04-24  
最近老师布置了一道算法题目--N皇后问题。这个算法在本科时已经做过,现在的要求是尽可能的提高算法的执行效率。如果采用传统的办法,用3个数组来记录列、主对角线和次对角线的方式,虽然优化过语句,并且使用对称原则来减少一半的运算时间,但在1.66Ghz的机器上计算16皇后仍需要100多秒。
有的同学使用多线程方式来改进了算法,有效利用了服务器的多个CPU同时计算,好像在4CPU机器上用了17秒。但我觉得这并没有体现出算法的高效。
昨天在google上有幸找到了一个难得一见的算法,在1.66Ghz的机器上计算16皇后才用了35秒,是我目前见到的最快的皇后问题算法了。简单的看了一下算法原理,它有别于传统的数组判断模式,而是采用了位运算。我也跟踪了几个变量的位结构变化情况,但是直到今天仍没能理解作者对该算法的设计思想和算法原
理。
因此期望各位算法高手不吝赐教,能对这个算法做个注释,并描述一下算法原理,感激不尽!
原始程序是C语言版的,我把它转换成Java语言版,并且惊奇的发现,几乎是一样的程序,Java执行速度居然比C的快了2秒。
-----------------------------------
import java.util.Calendar;

public class Queen {

public static int sum = 0, upperlimit = 1;

public static void compute(int row, int ld, int rd); {

if (row != upperlimit); {
int pos = upperlimit & ~(row | ld | rd);;
while (pos != 0); {

int p = pos & -pos;
pos -= p;
compute(row + p, (ld + p); << 1, (rd + p); >> 1);;
}

} else
sum++;
}

public static void main(String[] args); {
Calendar start;
int n = 8;

if (args.length > 0);
n = Integer.parseInt(args[0]);;
start = Calendar.getInstance();;
if ((n < 1); || (n > 32);); {
System.out.println(" 只能计算1-32之间\n");;
return;
}
System.out.println(n + " 皇后\n");;
upperlimit = (upperlimit << n); - 1;
compute(0, 0, 0);;
System.out.println("共有"
+ sum
+ "种排列, 计算时间"
+ (Calendar.getInstance();.getTimeInMillis(); - start
.getTimeInMillis();); / 1000 + "秒 \n");;
}

}

-------------------------------

    
   发表时间:2006-04-24  
另外一个加速提示:解是对称的
0 请登录后投票
   发表时间:2006-04-24  
对称可以减少近一半的运算时间,这点我是清楚的。现在的问题是如何把这个算法原理搞清楚,才能对它进行修改,以便进一步的提高效率。还请各位帮忙分析一下这个算法的原理吧。
0 请登录后投票
   发表时间:2006-04-24  
引用
原始程序是C语言版的,我把它转换成Java语言版,并且惊奇的发现,几乎是一样的程序,Java执行速度居然比C的快了2秒。

真的假的?????
0 请登录后投票
   发表时间:2006-04-24  
是真的,用的是jdk1.5。而c版本使用lcc-win32编译执行的。不知是不是jdk1.5中做了优化。
0 请登录后投票
   发表时间:2006-04-24  
n 不能超过 32 的算法 ……

嗯嗯,这类算法的思想基本上是这样的:拿一个整数来代表棋盘的一列,用这个整数中的各个二进制位保存这一列里某个格子是不是能放子。然后用三个变量,分别保存之前各列中的皇后能够横吃的格子、能够上斜吃的格子、能够下斜吃的格子,看看合起来是不是还有空位,没有的话就回溯,有的话就把子放下去,更新上面三个变量,继续走下去,他那个 row / ld / rd 就是干这个的。对照规则很容易就能想通了。

不过这类算法没啥价值,N-皇后问题真要做起来,n 小于 500 的结果是没人看的,而且这个东西离“目前最快”也远得很 ……

Craft 写道
是真的,用的是jdk1.5。而c版本使用lcc-win32编译执行的。不知是不是jdk1.5中做了优化。


你编译的时候 lcc-win32 的优化选项开了没?
0 请登录后投票
   发表时间:2006-04-24  
法师出马绝对ok!

特羡慕你们这些数据专业出生的人.
0 请登录后投票
   发表时间:2006-04-25  
非常感谢Elminster的指点,对我学习这个算法有了很大的帮助。
另外这个问题在csdn中已经有不少网友对算法做了一些说明,有兴趣的朋友可以参考一下:)
http://community.csdn.net/Expert/TopicView3.asp?id=4709025
0 请登录后投票
   发表时间:2006-04-27  
原始程序是C语言版的,我把它转换成Java语言版,并且惊奇的发现,几乎是一样的程序,Java执行速度居然比C的快了2秒

我试了一下,是38秒呀,哪有你说的那厉害用了33秒??????????
0 请登录后投票
   发表时间:2006-04-27  
不同的机器,不同的配置,后台运行的软件对CPU的占用,都可能造成时间的延误。
现在我改写出了一个新版本的,JAVA+位运算+对称原则+分布式,我的双核本本1.66G+一台机架服务器(双超线程CPU)同时计算,5秒多一些。如果继续增加终端,时间还会更少。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics