分享

深度优先搜索 广度优先搜索 A*搜索的算法封装

 yiyiyicz 2012-11-09
http://www./html/jsjc/20080425/1906.html

封装了搜索算法 包括一个通用的搜索模板和三种搜索:深度优先搜索 广度优先搜索 A*搜索

  1. function Currying(func)//将一个函数转换为Currying形式 参考51js月影的旧帖
  2. {
  3.     return function()
  4.     {
  5.         var args = Array.prototype.slice.call(arguments,0);   
  6.         if(args.length<func.length)
  7.         {                     
  8.             return function(){
  9.                 var _args = args.concat(Array.prototype.slice.call(arguments,0));   
  10.                 return Currying(func).apply(this,_args);
  11.             }
  12.         }
  13.         else return func.apply(this,args);
  14.     }
  15. }
复制代码

//搜索算法的通用模板
//Collection是保存open节点的数据结构 不同的搜索算法需要不同的Collection结构 如果是自己写的数据结构 需要用一个Adapter使它实现 put get和empty三个方法
//Extend 是一个函数 它描述问题中如何从一个节点扩展子节点 它接受一个参数表示访问一个已经搜索到的节点 返回一个表示新节点数组
//Beam 是一个函数 它决定已知节点是否应该被剪枝 它接受一个参数表示要检查节点 返回true或者false 如果不需要剪枝它可以总是返回false
//Finish是一个函数 它决定搜索到当前节点 是否应该结束搜索。 它接受一个参数表示要检查节点 返回true或者false 如果要搜索所有可行解 它可以总是返回false

  1. function Search(Collection,Extend,Beam,Finish)
  2. {
  3.     return function(node){
  4.         var openlist=new Collection();
  5.         openlist.put(node);
  6.         while(!openlist.empty()){
  7.             var current=openlist.get();

  8.             if(!Beam(current)){
  9.                 var extended=Extend(current);

  10.                 for(var i=0;i<extended.length;i++)    {
  11.                     if(Finish(extended[i]))
  12.                         return extended[i];
  13.                     openlist.put(extended[i]);
  14.                 }
  15.             }
  16.         }
  17.         return null;
  18.     }
  19. }
  20. Search=Currying(Search);//将Search科里化。

  21. function Stack()//实现了Collection接口的栈容器
  22. {
  23.     var buf=new Array();
  24.     this.empty=function(){
  25.         return !buf.length;
  26.     }
  27.     this.get=function(){
  28.         return buf.pop.apply(buf,arguments);
  29.     }
  30.     this.put=function(){
  31.         return buf.push.apply(buf,arguments);
  32.     }
  33. }


  34. function Queue()//实现了Collection接口的队列容器
  35. {
  36.     var buf=new Array();
  37.     this.empty=function(){
  38.         return !buf.length;
  39.     }
  40.     this.get=function(){
  41.         return buf.pop.apply(buf,arguments);
  42.     }
  43.     this.put=function(){
  44.         return buf.unshift.apply(buf,arguments);
  45.     }
  46. }

  47. function SortCollection(compare)//实现了Collection接口的排序结构
  48. {
  49.     return function(){
  50.         var buf=new OrderArray(compare);
  51.         this.empty=function(){
  52.             return !buf.length;
  53.         }
  54.         this.get=function(){
  55.             return buf.pop.apply(buf,arguments);
  56.         }
  57.         this.put=function(){
  58.             return buf.insert.apply(buf,arguments);
  59.         }
  60.     }
  61. }

  62. var DepthFirstSearch=Search(Stack);//用栈做为openlist 深度优先搜索
  63. var BreadFirstSearch=Search(Queue);//用队列做为openlist 广度优先搜索
  64. var AStarSearch=Currying(function(compare,Extend,Beam,Finish)//使用估值函数的A*搜索。
  65. {
  66.     return Search(new SortCollection(compare),Extend,Beam,Finish);
  67. })
复制代码

链接中有两个附件

1,8皇后问题 适用深度优先搜索和广度优先搜索
2,寻路 使用AStar搜索和广度优先搜索

JavaScript二叉树
在JavaScript中使用数组对象实现二叉树的深度与广度搜索。

<script type="text/javascript">
var t = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];

//下面这段深度优先搜索方法出自Aimingoo的【JavaScript语言精髓与编程实践】
var deepView = function(aTree,iNode){
    (iNode in aTree) && (document.write(aTree[iNode]+'<br/>'),arguments.callee(aTree,2*iNode+1),arguments.callee(aTree,2*iNode+2))
}

//广度优先
var wideView = function(aTree,iNode){
    var aRTree = aTree.slice(0),iRNode = iNode,iLevel = 1;
    (iRNode in aRTree) && document.write(aRTree[iRNode]+'<br/>');
    (function(){
        var iStart = iRNode*2+1,iEnd = iStart+Math.pow(2,iLevel);
        document.write(aRTree.slice(iStart,iEnd).join(',')+'<br/>');
        if(iEnd>=aRTree.length) return;
        iRNode = iStart,iLevel++,arguments.callee();
    })()
}

document.write('<h3>二叉树 深度优先</h3>');
//深度优先
deepView(t,0);

document.write('<h3>二叉树 广度优先</h3>');
//广度优先
wideView(t,0);
</script>

javascript实现的二分查找法


[摘要]: 一般二分都用到int[]型上.....在js中可能会更灵活的用到a-z上,或者用到拼音...或者用到...... 不过值得深思的一个问题是,如果为了实现对拼音之类的二分查找.而经过如下流程是否值得: 1。对拼音排序,貌似代码量不小吧。 2。然后再二分查找。这又需要识别拼音的大小

一般二分都用到int[]型上.....在js中可能会更灵活的用到a-z上,或者用到拼音...或者用到......
不过值得深思的一个问题是,如果为了实现对拼音之类的二分查找.而经过如下流程是否值得:
1。对拼音排序,貌似代码量不小吧。
2。然后再二分查找。这又需要识别拼音的大小,貌似也不算太小吧。
找到结果的速度快了,可是别人下你的js文件速度慢多了,呵呵,到底舍弃谁。
下面的代码甚至可以10亿条,一样会很快找到,可是用遍例的模式创建那个数组。。。所以还是别尝试了。只是给个思路,下次我再来发个js的八皇后问题解决方案,呵呵算法很奇妙哦

var array = [];
var key = 482;
var number = 1000;

for(i=0;i<number;i++){
array.push(i);
}
//-->>
var time = new Date();
var a;
var left = 0;
var right= array.length;
while(left<=right){
var center=Math.floor((left+right)/2);
if(array[center] == key) a = center;
if(key < array[center]){
  right = center - 1;
}else{
  left = center + 1;
}
}
alert("二分查找法搜索的结果:"+a);
alert((new Date() - time)/1000);

八皇后深度优先搜索javascript实现


http://hi.baidu.com/lmj80/item/85343b03e935821bcc34ea86

  1. 所有排列:<input id="text3" type="text"></input><br/>
  2. <div id="md"><br/></div>
复制代码
  1. <script>
  2. var text3=document.getElementById("text3");
  3. var md=document.getElementById("md");
  4. var i=0,num=0,size=8,j=0,sum=0;
  5. var arr=new Array(size);
  6. for(i=0;i<arr.length;i++)arr[i]=-1;
  7. function traverse(i){
  8. if(i==-1){text3.value=num;return;}
  9. j=arr[i]==-1?0:arr[i]+1;
  10. arr[i]=-1;
  11. var flag=0;
  12. while(j<size){
  13. flag=1;
  14. for(k=0;k<i;k++){
  15. if(j==arr[k]||Math.abs(i-k)==Math.abs(j-arr[k])){
  16. flag=0;break;
  17. }
  18. }
  19. if(flag)break;
  20. j++;
  21. }
  22. if(j==size){traverse(--i);
  23. }else{
  24. if(flag){
  25. arr[i]=j;
  26. if(i==(size-1)){
  27. md.innerHTML+=arr+"<br/>";num++;
  28. }else{i++;}
  29. //setTimeout("traverse("+i+")",10);
  30. traverse(i);
  31. }
  32. }

  33. }
  34. traverse(0);
  35. </script>
复制代码


结果:  92种
opera测试没有问题,IE6可能造成堆栈溢出,加个延时即可

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多