传 奇什 么 加 速 器能 过 金 盾 登 陆 器?蓝 月 G 吗?

百度知道 - 信息提示
知道宝贝找不到问题了&_&!!
该问题可能已经失效。
秒以后自动返回妹妹上厕所叫我看见了小说,anyequ333,想找一个黄色网站中文新闻平台||
加载中请您耐心等待...
滚动新闻 加载中,请稍候...
热门文章BAIJIA HOT 01 02 03 04 05 01 02 03 04 05HOT WORDS
01 02 03 04 05 06mediaLOCAL NEWS
01 02 03 04 05
Entertainment
国际热搜词 01 02 03 04 05 06 07 08 09 10 11 12Sports
互联网图片
House&Auto
返回上一层正在加载,请稍候......
70kkkk thunder://|ftp://玉簪相大唐国都... Lady&Health
手机影音先锋输入网站后不弹窗大眼界小靴...
Technology&Discovery
看女人的逼毛儿嫔妃置他于死地,除下围盖惜朝并顾惜朝一。被天竺往往,朕算八人... Education&Game
社会新闻排行榜
社会视频Photos
2请留下联系方式,您将有机会获得精美礼品!(可选)
相关功能妹妹上厕所叫我看见了小说独家出品新闻由机器选取每5分钟自动更新妹妹上厕所叫我看见了小说源于互联网新闻网站和频道,系自动分类排列,妹妹上厕所叫我看见了小说不刊登或转载任何完整的新闻内容,米恩,译者注)博弈树。极大极小算法背后的策略假定参与博弈的游戏者都尽自己最大的努力获得好 结果。因此,无论对方选择有利或有害的步骤,计算机都将会根据对手的着 法选择最于己有利的步骤。 这个简单浅显的概念就是极大极小树的最大奥妙。比如,对 max 的程序来 说,无论 min 怎么做,最佳的步骤或步骤序列一定会得到最高分值的结果。 而 min 显然将选择那些让它获得最低分值的结果。 从某种意义上说,叶子节点 是唯一需要评估位置分值的节点,因为它们代表最终的结局。比如在 max 的博弈变化中,叶子节点始终处在同一位置。程序将假定 min 将从可能的步 骤中选择最低分值的步骤行动,那么任何 max 节点的最大最小值都会等同 于 min 节点的最低分值子节点。 最后,像人类的棋类游戏一样,程序的能力高低取决于计算机对所处形势的 评估能力,以及程序搜索的深度。一位国际象棋大师对形势的估计误差要大 大小于余位业余选手,而且象棋大师对于棋局的预测也远比一般人更远。计 算机同样也可以对棋局做出很长远的预测,并且它着棋不会失误,因为它会 看到对手由于失误而做出的回应。 有很多算法可以帮助极大极小算法提高搜索效率。 其中一种被称作 a-β剪枝算法。 在使用这 种算法进行的搜索中,计算机所要搜索的节点数大 约只是不使用这种技术所需搜索节点数的平方根那么多。也就是说,如果程 序原来需要搜索四百个节点,使用新的算法后它只需要搜索二十个。 其它的一些工具包括置换表, 记载搜索结果的纪录被放在一张可以快速存取的很小的表中。通常来说,不 同的步骤序列可能达到相同的位置(结果) 。这两个位置(结果)就可以互 换。该表可以帮助计算机认识目前棋局的形势,因为它已经付出了内存存取 时间的代价对其进行了审查。 同时,这些技术也允许计算机搜索更多的节点,并模拟策略思考。尽管其它 的技术也开始崭露头角(比如神经网络) ,但极大极小树仍然是该类程序的 最佳心脏。 α-β 剪枝技术及其算法 首先分析极小极大分析法效率,上述的极小极大分析法,实际是先生成 一棵博弈树,然后再计算其倒推值,至使极小极大分析法效率较低。于是在 极小极大分析法的基础上提出了 α-β 剪枝技术。 α-β 剪枝技术的基本思想或算法是,边生成博弈树边计算评估各节点 的倒推值,并且根据评估出的倒推值范围,及时停止扩展那些已无必要再扩 展的子节点,即相当于剪去了博弈树上的一些分枝,从而节约了机器开销, 提高了搜索效率。具体的剪枝方法如下: (1) 对于一个与节点 MIN,若能估计出其倒推值的上确界 β,并且这个 β 值不大于 MIN 的父节点(一定是或节点)的估计倒推值的下确界 α,即 α ≥β,则就不必再扩展该 MIN 节点的其余子节点了(因为这些节点的估值对 MIN 父节点的倒推值已无任何影响 了)。这一过程称为 α 剪枝。 (2) 对于一个或节点 MAX,若能估计出其倒推值的下确界 α,并且这个 α 值不小于 MAX 的父节点(一定是与节点)的估计倒推值的上确界 β,即 α ≥β,则就不必再扩展该 MAX 节点的其余子节点了(因为这些节点的估值对 MAX 父节点的倒推值已无任何影响了)。这一过程称为 β 剪枝。 从算法中看到: (1) MAX 节点(包括起始节点)的 α 值永不减少; (2) MIN 节点(包括起始节点)的 β 值永不增加。 在搜索期间,α 和 β 值的计算如下: (1) 一个 MAX 节点的 α 值等于其后继节点当前最大的最终倒推值。 (2) 一个 MIN 节点的 β 值等于其后继节点当前最小的最终倒推值。 例:对图 3.18 所示一步棋第一阶段部分搜索树的 α 和 β 值计算方法。 假设以深度优先方式进行搜索。 画出根节点、节点 A 及 5 个儿子,计算并标上这些节点的静态估值,A 的 5 个儿子节点的静态估值的最小值是-1,因此节点 A 的倒推值为-1,从而起 始节点的倒推值的下界 α 定为-1,当然有可能比-1 更小,因为它有其他的 儿子节点。 画出节点 B 及它的第一个儿子节点 C,算出节点 C 的静态值为-1,于是节 点 B 的倒推值不会比-1 大,又注意到节点 B 的最终倒推值不会小于起始节点 的 α 值,由此可肯定最终倒推值 β=-1。由于 α 值不比 β 值小,故可以终止 节点 B 的搜索。 例:α-β 剪枝技术的例子,图 3.19 所示。图中所生成的搜索树共有六 层(我们规定首先生成最左面的节点。MAX 节点用方块表示,MIN 节点用圆圈 表示)。图中还给出了端节点的静态估值。现在假设我们采用 α-β 剪枝技 术来引导深度优先搜索。由 α-β 剪枝技术生成的子树在图中用粗树枝表示 。发生修剪的那些节点用“×”表示。 我们注意到原先 41 个端节点只有 18 个必须估值,可见说明 α-β 方法能 够有效地提高效率。 下面让我们对 α-β 剪枝技术的搜索效率再作一些分析。要进行 α-β 修剪,必须至少使某一部分的搜索树生长到最大深度,因为 α 和 β 值必须以 端节点的静态估值为依据。因此采用 α-β 剪枝技术通常都要使用某种深度 优先的搜索方法。而且在一次搜索期间修剪的枝数取决于早期的 α、β 值与 最终倒推值之间的近似程度。 起始节点的最终倒推值等于某个端节点的静态估值。如果在深度优先搜 索过程中第一次就遇到这个端节点,则修剪枝数最大。当前修剪枝数最大时 ,需要生成和估计的端节点数就最少。 α-β 剪枝技术的搜索效率还可通过数学公式进行估算,请参阅有关参 考资料。 算法: int AlphaBeta(int depth, int alpha, int beta) { if (depth == 0) { return Evaluate(); } GenerateLegalMoves(); while (MovesLeft()) { MakeNextMove(); val = -AlphaBeta(depth - 1, -beta, -alpha); UnmakeMove(); if (val &= beta) { } if (val & alpha) { alpha = } } } 把醒目的部分去掉,剩下的就是最小-最大函数。可以看出现在的算法 没有太多的改变。 这个函数需要传递的参数有:需要搜索的深度,负无穷大即 Alpha,以 及正无穷大即 Beta: val = AlphaBeta(5, -INFINITY, INFINITY);12 年前,IBM 公司研制的超级计算机“深蓝”(Deep Blue)在 6 局比赛中 击败了国际象棋世界冠军加里?卡斯帕罗夫(Garry Kasparov)。这个里程 碑式的事件终结了人类在又一个智力策略游戏上的统治地位。只有亚洲的围 棋仿佛是计算机科学的“阿喀琉斯之踵”:人类总是能够轻松击败计算机。 但最近出现的一种新的围棋算法,却能战胜高水平的棋手。 围棋的复杂度高,且极具欺骗性,对计算机程序提出了巨大的挑战。围 棋的棋盘由两组数量相同、互相正交的平行线构成,分为 9 线小棋盘与 19 线 大棋盘两种。对弈双方分执黑白两色棋子。通过在棋盘的交叉点上落子,棋 手要尽可能扩张自己的领地并包围对方棋子。在大棋盘的对弈中,每一步可 采取的策略数量都非常巨大。对局中期,平均每一步能采取 200 种不同的策 略,相比而言,国际象棋中每一步数十种的可选策略就显得微不足道了。此 外,还要考虑数量众多的后续策略。由于棋盘上每个位置都对应着三种状态 :黑子占据、白子占据和空位,N 个位置便可构成 3N 种不同的状态。如果考 虑规则约束,小棋盘大约有 1038 种不同的状态,大棋盘的状态数量则达到 了惊人的 10170 种。其他一些因素也会影响比赛胜负:棋盘上棋子的数量优 势并不能确保胜利,棋手必须在考虑局部形式的同时,兼顾全局。 为了处理如此众多的可能情况,人工智能专家已经设计出一些算法,来 限制搜索的范围,但它们都无法在大棋盘的比赛中战胜实力稍强的人类棋手 。去年秋季,两位匈牙利研究人员报告了一种新算法,它的胜率比现有最佳 算法提高了 5%,能够在小棋盘的比赛中与人类职业棋手抗衡。这种被称为 UCT(Upper Confidence bounds applied to Trees)的算法,是匈牙利国 家科学院计算机与自动化研究所的列文特?科奇什 与加拿大阿尔伯塔大学的乔鲍?塞派什瓦里合作提出的,是著 名的蒙特卡罗方法的扩展应用。 20 世纪 70 年代,蒙特卡罗方法首次运用于围棋程序,这种方法的作用 类似于选举投票:用统计采样的方式,预测大规模群体的表现与特质。围棋 程序会随机出招,模拟大量的比赛,对候选走法加以评估并排序。然而,每 一步都采用评估值最高的走法,并不能保证获得比赛的胜利。相反,这种方 法仅仅是限制了搜索的范围。 UCT 扩展了蒙特卡罗方法,集中关注那些最有希望赢得比赛的走法。科 奇什说:“UCT 的主要思想是对走法进行选择性采样。”他解释说,这种算 法必须达到一种平衡,既要尝试当前的最佳走法,发现其中可能隐藏的昏招 ,还要搜索“当前并非最佳的走法,以确保不会因为先前的估计错误而错失 妙招”。 UCT 为每一种走法计算一个索引值,然后按照索引值最高的走法出招。 索引值由采用该走法后最终取胜的概率(即胜率)决定,该走法被计算却未 被采用的次数也对索引值有一定的影响。UCT 会在内存中维护一棵“决策树 ”,用来记录每一种走法的统计数据。如果遇到一种先前从未计算过的走法 ,算法就会将它纳入决策树,并随机出招完成余下的比赛。 判定随机比赛的胜负后,UCT 就会更新比赛中采用过的所有走法的统计 数据。如果该走法的索引值等于它的胜率,算法就能快速选定这招最有希望 获胜的策略。但开局时走出妙招,仍然无法确保比赛的最终胜利。所以在选 择走法时,UCT 会增大计算次数少的候选走法的权值,以使胜率的总体分布 趋向平坦。 法国南巴黎大学的数学家西尔万?热利(Sylvain Gelly)与巴黎技术学 校的王毅早(Yizao Wang,音译)将 UCT 集成到一个他们称之为 MoGo 的程序 中。该程序的胜率竟然比先前最先进的蒙特卡罗扩展算法几乎高出了一倍。 今年春季,MoGo 在小棋盘的比赛中击败了实力强劲的业余棋手,在大棋盘 比赛中也击败了实力稍弱的业余棋手,充分展示了能力。热利认为 UCT 易于 实现,并有进一步完善的空间。科奇什预言,10 年以后,计算机就能攻克 最后的壁垒,终结人类职业棋手对围棋的统治。 以围棋为例,围棋有多少种变化?比较常见的有两种估计方法,一是:假设 不会出现大家都被提光再从头再来的情况,那么,第一步有 361 种选择, 第二步有 360 种选择,以后的情况大致如此,我们就以 361 为界,那么变 化数是 361!,约为 10 的 768 次方。另一种估计方法大概是宋朝的沈括老先 生首先使用的:棋盘上每个点有黑,白,空三种状态,所以围棋变化数是 3 的 361 次方,约为 10 的 172 次方,用沈老先生的说法,就是“连书‘万’ 字四十三”。这虽然也很大,但比起前面的估计值来,小的实在是太多了。 如果这种估计正确,那电脑下围棋无疑轻松了许多。 不幸的是,沈老先生的估计方法是错误的。他只考虑了这种种状态,却没有 考虑这些状态间的相互关系。就比如数学中的图,沈老先生只考虑了顶点的 总数,却忘了把连接顶点的边算进去了。 如果我们不考虑边,就考虑这“连书‘万’字四十三”的状态,如果我可以 对于每个状态都精确地算出价值的话,那么电脑只需要查价值表就可以确定 该怎样下棋了,这样,电脑需要储存的变化数也就是“连书‘万’字四十三 ”,但问题是,这些价值是怎么算出来的?总不会看到一个状态之后就能猜 出它的价值吧。因此,假设有一个电脑围棋机器,虽然在执行的时候他可以 只考虑不同状态的价值,但为了造这台机器,我们还得把所有这些状态的关 系都考虑进去。 按照第一种估计方法得到的 10 的 768 次方又是个什么概念呢?宇宙中所有 基本粒子的总数,据估计,为 10 的 80 次方。如果没有一些简化计算的措施 ,这比宇宙中粒子总数还要大数不清倍的数字对我们来说,又和无穷有什么 区别? 其实,连第一种估计方法都是错误的。围棋真正的变化数,连 10 的(3 的 361 次方)次方都挡不住,大学学历的人都清楚,一旦出现指数天梯,那这个数 字有多大已经是不可想象的了。 这一点并不能说明围棋不是图灵机实际可解的。不过至少告诉我们,遍历的 方法是不可行的。所以,我们暂时把围棋的状态当作无穷来看。在这里,我 们用准无穷来称呼到达实际不可计算程度的状态数。 人们在谈到围棋与国际象棋的比较时,总说围棋的变化远多于国际象棋。但 如果把这作为电脑下围棋远难于下国际象棋的原因是不充分的,并不是状态 越多的东西越复杂,况且国际象棋的变化同样也是天文数字。 但是,如果把国际象棋的棋盘放大,棋子增多,使它的变化从绝对数值上来 说接近甚至超过围棋,国际象棋还是只能给人以国际象棋的感觉而不是围棋 的感觉。因为,它们的“语法”有着本质的不同。 3# 发表于
08:17 要代码就去看看 GNU GO 的源代码好了。要思路 的话,给你转贴一篇下面的文章,希望看完以后你还能有勇气继续做下去。 。 。 ================================================= 一 从地球到月球 从电脑诞生之日起,人们对于电脑就充满了幻想。尤其是在人工智能上,对 于电脑超过人脑,有人兴奋,有人担忧,但曾经几乎所有人都认为这会是真 的。尤其当“深蓝”击败卡斯帕罗夫之后,人们已经开始担忧,电脑超过人 脑,会不会就发生在明天? 但这种担忧实在是来的太早了。 本世纪七八十年代,对人工智能学家们来说,就象是无忧无虑的童年。他们 雄心勃勃,甚至排出了电脑替代人脑的时间表。在表中,现在,就已经应该 是电脑超过人脑的日子了。现在,“深蓝”确实战胜了卡斯帕罗夫,但人工 智能学家们的时间表早已被抛到了脑后。有人甚至打了这样一个比喻来说明 人工智能上所取得的成就:人们想登上月球,他们造了一个梯子,用这个梯 子爬上了一棵树,然后自豪地宣称:“现在,我们已向月球前进了一大步! ” 现在,电脑已经渗入到了我们生活的各个方面,在生产和生活中,我们已经 有些难以想象脱离电脑的状况了,如果说这些形形色色的电脑只不过是花里 胡哨的各种梯子,似乎实在是说不过去。 我们先看看梯子是怎么回事吧。 梯子的发明人是图灵博士。图灵在考虑可计算的机器的性质时,首先是设想 一个人在计算,他把这个人的计算行为抽象成了这样一台机器:有一条无穷 长的纸带子,一个有很多状态的机器在纸带上左右滑动,并且可以根据所读 到的内容改变自己的状态或者改写纸带的内容。这就是大名鼎鼎的图灵机了 。当前的所有计算机,在理论上都是可以被图灵机模拟的。 请注意图灵机有一个重要的能力:改写纸带的能力。如果没有这个能力,那 这台机器叫做有穷自动机。它和图灵机间的计算能力差着三个档次呢。 (注 意:在一条无穷长的纸带上读东西,在另一条纸带上写东西的机器也是有穷 自动机) 。 判断这些东西的计算能力用的是这些机器所能接受的语言的概念。这个语言 虽然是抽象的语言,但也和我们平时所说的语言差不多,你只要理解成这机 器能听懂什么话也就差不太多了。乔姆斯基把语言分成了 0, 1,2 , 3 四 个等级,0 级能力最强,3 级最差。这四个等级之间有着难以逾越的鸿沟 。 这里的 3 级语言也叫做正规语言,就是有穷自动机能听懂的, 2 级语言叫 做上下文无关语言,意思是一个词,不用管它的上下文,就可以听懂了。1 级语言就是上下文相关的了,也就是说机器还得揣摩这话前后的意思。零级 语言就是图灵机可以接受的语言了。 我们用数数的本事就可以体会 1,2,3 型语言的能力差别了。 对于数数,有这么一个笑话:两个贵族比赛,看谁说出的数更大,第一个人 绞尽脑汁,冥思苦想十几分钟后说:3, 轮到第二个人,他想了很久很久 ,最后说:你赢了。 数到 3 的本事哪型语言都会,我这里说的数数本事是从一数起,只要不老 死,数多少个都行。3 型语言,也就是正规语言,是不会数数的。 2 型语 言(上下文无关语言)会数数,但同时数两个数就不会了。1 型语言就是 数多少个数都行的了。而 0 型语言的能力又比 1 型语言强的多。也就是说 ,图灵机看上去简单,实际上是还是很牛的。 但是图灵自己就发现了图灵机也有不照的时候了,这就是图灵机的停机问题 。我们可以这样说明图灵机的停机问题:假设当图灵机听懂了一句话,它就 不再琢磨这句话了,现在我给图灵机一句话,问它“你听的懂吗?”如果它 听的懂,它会回答“是”,但如果它听不懂,很可能它永远也不会知道自己 听不懂。------------------------------------------------------------------------------二 有穷与无穷 用天梯登上月球的想法,现代人也许会觉得荒谬,但在古人眼里,未必如此 。梯子可以上树、可以上房、可以上城,甚至可以上山,为什么不能上天呢 ? 因为做梯子的原材料数量不够,强度不够,天梯也没有可搭的地方,等等等 等,但古人都不清楚,他们根本不知道地球和月球之间有多远。 国际象棋八八六十四见方的棋盘,围棋纵横 361 交叉点的棋枰,它们的变 化从理论上说是有限的,因此,理论上,这些问题都是图灵机可解决的。但 是,就在我们理论上严谨地一步步得出结论时,我们早已不知不觉地越过了 在实际计算意义上有穷与无穷的界限。 以围棋为例,围棋有多少种变化?比较常见的有两种估计方法,一是:假设 不会出现大家都被提光再从头再来的情况,那么,第一步有 361 种选择, 第二步有 360 种选择,以后的情况大致如此,我们就以 361 为界,那么变 化数是 361!,约为 10 的 768 次方。另一种估计方法大概是宋朝的沈括老先 生首先使用的:棋盘上每个点有黑,白,空三种状态,所以围棋变化数是 3 的 361 次方,约为 10 的 172 次方,用沈老先生的说法,就是“连书‘万’ 字四十三”。这虽然也很大,但比起前面的估计值来,小的实在是太多了。 如果这种估计正确,那电脑下围棋无疑轻松了许多。 不幸的是,沈老先生的估计方法是错误的。他只考虑了这种种状态,却没有 考虑这些状态间的相互关系。就比如数学中的图,沈老先生只考虑了顶点的 总数,却忘了把连接顶点的边算进去了。 如果我们不考虑边,就考虑这“连书‘万’字四十三”的状态,如果我可以 对于每个状态都精确地算出价值的话,那么电脑只需要查价值表就可以确定 该怎样下棋了,这样,电脑需要储存的变化数也就是“连书‘万’字四十三 ”,但问题是,这些价值是怎么算出来的?总不会看到一个状态之后就能猜 出它的价值吧。因此,假设有一个电脑围棋机器,虽然在执行的时候他可以 只考虑不同状态的价值,但为了造这台机器,我们还得把所有这些状态的关 系都考虑进去。 按照第一种估计方法得到的 10 的 768 次方又是个什么概念呢?宇宙中所有 基本粒子的总数,据估计,为 10 的 80 次方。如果没有一些简化计算的措施 ,这比宇宙中粒子总数还要大数不清倍的数字对我们来说,又和无穷有什么 区别? 其实,连第一种估计方法都是错误的。围棋真正的变化数,连 10 的(3 的 361 次方)次方都挡不住,大学学历的人都清楚,一旦出现指数天梯,那这个数 字有多大已经是不可想象的了。 这一点并不能说明围棋不是图灵机实际可解的。不过至少告诉我们,遍历的 方法是不可行的。所以,我们暂时把围棋的状态当作无穷来看。在这里,我 们用准无穷来称呼到达实际不可计算程度的状态数。 人们在谈到围棋与国际象棋的比较时,总说围棋的变化远多于国际象棋。但 如果把这作为电脑下围棋远难于下国际象棋的原因是不充分的,并不是状态 越多的东西越复杂,况且国际象棋的变化同样也是天文数字。 但是,如果把国际象棋的棋盘放大,棋子增多,使它的变化从绝对数值上来 说接近甚至超过围棋,国际象棋还是只能给人以国际象棋的感觉而不是围棋 的感觉。因为,它们的“语法”有着本质的不同。 现在,我们考虑这样一个问题:国际象棋和围棋走子后棋局状态的变化,分 别需要判断几个位置上的状况? 国际象棋当我落下一子时,只要考虑落子点的状态就可以了,如果这里有我 自己的子,这步落子无效,如果这里有敌人的子,敌子被我吃掉,如果这里 空白,那么仅仅是棋子的移位。象王车易位、吃过路兵等情况,我们可以把 它看作可以遍历的特例而暂时不予考虑。 让我们回想一下乔姆斯基四级语言中的 2 级:上下文无关语言。当排除了 特殊情况之后,我们可以认为,既然国际象棋棋局某格的状态变化与周围无 关,那么,它应当是可以被能听懂(专业上叫接受)2 级语言的机器听懂 的。我们可以把国际象棋理解成一个上下文无关语言。 回到围棋,当我们落下一子时,棋盘会变成什么样?如果周围全是敌子,有 些敌子没了气,那敌子全部拿走,如果周围有自己的子,敌子没被拿走,自 己的子反而没了气,那就是自填死。 听起来好象也很简单,但棋盘的变化是需要看周围的情况而决定的。如果只 看落子点的状态,那我们什么结论也得不到。也就是说,围棋不能用上下文 无关语言来等价,至少也得用上下文有关语言,就是会数很多数的 1 级语 言. 在考虑围棋变化数的时候,劫可是不能不提。有人说“劫乃围棋精华”,可 对于 1 型语言来说,劫实在是要命的东西。1 型语言的基本要求是它的语 言产生式左边不长于右边,但对于劫来说,并非如此。有了劫,就意味着 1 型语言也接受不了围棋了。 更要命的还在后面。象三劫循环、四劫循环、长生劫等等,在现在的围棋规 则中,都简单地判为“无胜负”。其实,如果用“全局同型禁止再现”,都 可以从理论上解决,并且也不如人们想象中的那么复杂(以后我可能会另写 文章介绍多劫循环的规律) 。全局同型禁止再现也很圆满地解释了劫。但是 ,全局同型禁止再现对于用图灵机模拟围棋,可以说是致命的一击。因为, 这意味着这台图灵机得把以前的所有状态都存储起来,而具有无限种状态数 的机器不是图灵机。 国际象棋一盘棋结束,有三种状态:将死对方,被对方将死,和棋。和棋除 了双方自愿外,还有逼和、三次同型和,以及六十步子数不变和等等。这意 味着国际象棋在这些都是可以直接检验的,其步数不会超过 32*60 步。可 围棋就不一样了,“全局同型禁止再现”,这意味着理论上围棋可以下 3 的 361 次方数量级这么多手!这是准无穷了。即使没有这一规则,围棋可 走的步数依然是准无穷。 而围棋的胜负又非要看整个棋盘的状态才能决定,也就是说,就算没有“全 局同型禁止再现”这一规则,我们可以用图灵机来接受围棋,但判断每一步 的好坏必须追溯到这一局棋的终点,这意味着这台图灵机要判断它不同情况 下停机时的状态!而这是图灵机所无能为力的。这里的状态是理论状态,它 和我们实际计算时会选择的状态还不一样,围棋实际对局也很少超过 361 手,但这已经启示我们,既然国际象棋与围棋在复杂程度上差了 3 个档次 ,我们能够解决国际象棋问题的算法能用来对付围棋吗?------------------------------------------------------------------------------三 迷宫之路 从理论上来说,围棋的每一步都会有一个或几个最佳选择。如果我们真的可 以遍历围棋的所有变化并加以比较的话,我们是可以找到这些最佳下法。只 是这种遍历是实际上不可实现的。 寻找围棋最佳下法的过程就象是在走一个庞大的迷宫,迷宫中有无数的分支 岔路,有些通向死路,有些通向幻象,还有一些路则仅仅是自己转圈。置身 于这个庞大的迷宫中,当我们知道凭一生的时间也只能走过这一迷宫的微不 足道的一小部分时,我们自然会停下来,看看这迷宫之路中有没有什么规律 。 我们先对问题进行简化,抛开全局同型禁止再现,也不考虑三劫、四劫、长 生劫等等情况。这样在走迷宫时不必判断是否会出现回路(就是绕了一圈又 回来了) ,对于这种无回路的迷宫,最简单的走法是死贴一边走(比如,一 直贴左边或者一直贴右边) ,这就是一种遍历搜索,术语叫深度优先遍历搜 索(因为它每次都要走到头再转回来走下一条) 。按上章的计算,深度优先 遍历搜索走完这个迷宫大概需要 10^(3^361)步。 所以,我们别无选择,只有换种办法来走迷宫。我们所选的办法又怎样才能 达到我们的要求呢? 我们这里所谈论的迷宫的走法,也就是解决一个问题的算法,一般用是用复 杂度的阶数来衡量算法复杂度好坏的。首先,一个问题有它自己的尺度。比 如国际象棋是 64 格棋盘,我们可以把国际象棋问题的尺度定为 64,围棋 361 个交叉点,我们可以把围棋问题的尺度定为 361。如果你愿意把它们的 尺度分别定为 8,19 也可以,但考虑问题时显然不如 64 和 361 来的自然。 解决一个问题的算法的复杂度是根据问题的尺度与计算步数的函数来定义的 。设 n 为问题的尺度,如果一个算法需要 n 步,我们就说它的复杂度是 n ,如果一个算法需要 2^n 步(n 个 2 连乘),我们说它的复杂度是 2^n。对于 两种算法来说,只要他们的复杂度函数的比值不大于一个常数,我们就称它 们为同阶的。也就是说,一个需要步数为 1000n 的算法与一个需要步数为 n 的算法是同阶的。因为我的机器只要能把速度提高一千倍,第一个算法就 能达到第二个算法原先的速度。但一个步数为 n^2 的算法就比一个步数为 1000n 的算法复杂度高,因为不论你的机器有多快,对于尺度很大的问题, 总还是第一个算法复杂。 因此,我们就用 O(n),o(n^2),...,o(2^n),... 来表示与步数为 n, n^2,...,2^n,... 的算法同阶的算法的复杂程度。请注意这里的 2^n, 一个 2^n 步数的算法(其实是任何 x^n(x&1)步数的算法)比任何一个多项 式步数的算法(就是 O(n),O(n^2)...这类算法)都来的复杂。比如说。一 个算法的步数约为 2^n,第二个为 n^10,当 n 取 64 的时候(国际象棋尺度 ) ,前者需要 1.84*10^19 步,而后者需要 1.15*10^18 步,第一个比第二个 要多花十多倍步数,如果问题尺度是 361(围棋尺度) ,后者需要 3.76*10^25 步,而则前者需要 4.69*10^108 步,这次前者比后者复杂了一 千亿亿亿亿亿亿亿亿亿亿倍. 如果说一个问题可以找到复杂度为多项式的算法,我们称它属于 P 类问题 ,我们需要的就是复杂度为多项式的算法,也就是说,如果围棋是 P 类问 题,我们就认为它可解。而如果我们只能找到指数等级的算法 (O(2^n).. 等等),我们就认为它不可解。 而围棋的遍历需要的步数,是指数复杂度问题的排序问题,它比指数复杂度 的问题还要复杂的多。 在人们试图用计算机解决的各种问题中,有一大类问题,包括货郎问题,背 包问题等等,总计数百个之多,被人们称为 NP 问题。之所以说它们是一类 是因为人们已经证明了只要其中一个问题可计算(就是有多项式算法) ,其 他的问题就都可以计算,但现在,比起找这些问题的多项式算法,人们倒宁 愿去证明它们不存在多项式算法。 围棋是 NP 问题吗?不知道,好象不是,但既然 NP 问题都有指数复杂度的解 法,而围棋连指数复杂度的解法都找不到,看起来,围棋似乎比 NP 问题还 要复杂的多。 不过,解决一个问题,找不到最好的方法,退而求其次也不失为一种明智的 选择。人们对很多 NP 问题的态度就是:找不到最好的答案,比较好的答案 也不错。“深蓝”会输给卡斯帕罗夫一局,也说明“深蓝”找到的并非最佳 下法,但它已经可以在总成绩上战胜卡斯帕罗夫了。 作者曾经设想过一个围棋 AI 模型:把所有的棋子以连在一起的一块为基本 单位,而后再根据棋子的形状,眼位情况,赋与它强度、影响力等属性,用 力学模型来分析全局势力范围,并据此选择下一手的大致位置。实际上这就 是对 A*算法估值函数的一种设想。 看起来,我们只要找到一个好的方法,把一个个围棋局面量化成适当的值, 再根据这些值进行 A*搜索,就可以找到相当不错的走法。唯一的问题是: 存在可行的量化方法吗? 举个例子,当年吴清源观看十段战的一步拆,记得是立五拆七,这是标 准拆,但吴就说这步的水平就是个五段的水平,呵呵。 。中肯的说,吴的话 是过分了点,但以他当时强横的实力,嘿嘿。 。当时众人立哗,立马就有人 不忿,棋局结束后,两个人同时从那步开始和吴试演,后来两个人都输,呵 呵。 。这里可以看出,第一,就是高手之间对某步棋的评价也是不同的,第 二,每一步因为好坏都因为将来的棋而变化。 编辑本段算法的定义 由于未能确定的定义终止条件。 编辑本段举例 经典的算法有很多,如:&欧几里德算法,割圆术,秦九韶算法&。 编辑本段算法经典专著 目前市面上有许多论述算法的书籍,其中最著名的便是《计算机程序设 计艺术》 (The Art Of Computer Programming) 以及《算法导论》 (Introduction To Algorithms) 。 编辑本段算法的历史 “算法”即演算法的大陆中文名称出自《周髀算经》 ;而英文名称 Algorithm 来自于 9 世纪波斯数学家 al-Khwarizmi,因为 al-Khwarizmi 在 数学上提出了算法这个概念。“算法”原为&algorism&,意思是阿拉伯数 字的运算法则,在 18 世纪演变为&algorithm&。欧几里得算法被人们认为是 史上第一个算法。 第一次编写程序是 Ada Byron 于 1842 年为巴贝奇分析机 编写求解解伯努利方程的程序,因此 Ada Byron 被大多数人认为是世界上第 一位程序员。因为查尔斯?巴贝奇(Charles Babbage)未能完成他的巴贝奇 分析机,这个算法未能在巴贝奇分析机上执行。 因为&well-defined procedure&缺少数学上精确的定义,19 世纪和 20 世纪早期的数学家、逻辑 学家在定义算法上出现了困难。20 世纪的英国数学家图灵提出了著名的图 灵论题,并提出一种假想的计算机的抽象模型,这个模型被称为图灵机。图 灵机的出现解决了算法定义的难题,图灵的思想对算法的发展起到了重要作 用的。 求素数的埃拉托塞尼筛法和求方根的开方的方法公式(算法不等于公式,公式却是提供一种算法) 典型算法举例: 历史上有三大算法:1,求最大公约数的欧几里 得辗转相除法;2,求素数的埃拉托塞尼筛法;3,求方根的开方算法。后 面两种方法都可以用公式表达。 属于递归的。 一,求素数的埃拉托塞尼筛法公式。 公元前 250 年同样是古希腊的 (一)“要得到不大于某个自然数筛法与公式的关系:数学家埃拉托塞尼提出一种筛法:N 的所有素数,只要在 2---N 中将不大于√N 的素数的倍数全部划去即可”。 (二)将上面的内容等价转换:“如果 N 是合数,则它有一个因子 d 满 足 1&d≤√N”。《基础数论》13 页,U 杜德利着,上海科技出版社) ( 。. (三)再将(二)的内容等价转换:“若自然数 N 不能被不大于(根号) √N 的任何素数整除,则 N 是一个素数”。见(代数学辞典[上海教育出版社 ]1985 年。屉部贞世朗编。259 页) 。 换成为用英文字母表达的公式: +ak 。(1)(四)这句话的汉字可以等价转 N=p1m1+a1=p2m2+a2=......=pkmk其中 p1,p2,.....,pk 表示顺序素数 2,3,5,,,,,。a≠0。即 N 不能是 2m+0,3m+0,5m+0,...,pkm+0 形。若 N&P(k+1)的平方 [注:后面的 1,2,3,....,k, (k+1)是脚标,由于打印不出来,凡字 母后面的数字或者 i 与 k 都是脚标] ,则 N 是一个素数。 (1)等价转换成为用同余式组表示: (modp2),.....,N≡ak(modpk)。 (2) (五)可以把N≡a1(modp1), N≡a2 例如,29,29 不能够被根号29 以下的任何素数 2,3,5 整除,29=2x14+1=3x9+2=5x5+4。 29≡1 (mod2),29≡2(mod3), 29≡4(mod5)。29 小于 7 的平方 49,所以 29 是一个 素数。 以后平方用“*”表示,即:O=m*。 由于(2)的模 p1,p2,....,pk 两两互素,根据孙子定理(中国剩余定理)知, (2)在 p1p2.....pk 范围内有唯一解。 例如 k=1 时,N=2m+1,解得 N=3,5,7 k=2 时,N=2m+1=3m+1,解得。求得了(3,3*)区间的全部素数。N=7,13,19; N=2m+1=3m+2,解得 N=5,11,17,23。求得了(5,5*) 区间的全部素数。 5m+2-| 5m+3,| 5m+4.| ---------------------|---------|----------|--------|--------| n=2m+1=3m+1= |--31----|--7, 37-|-13,43|--19----| k=3 时, ---------------------| 5m+1-|-n=2m+1=3m+2= |-11,41-|-17,47-|--23---|---29---| -----------------------------------------------------------求得了(7,7*)区间的全部素数。 仿此下去,可以求得任意大 的数以内的全部素数。二,求方根的开方方法公式; 公式:开方的反馈 X_(n+1)=方法或者叫做自动调节开方。方法是迭代的。 {X_n+【A/(X^(k-1))-X_n】1/k}&_&表示下角标,“^”表示上角标。例如,X^2,表示 x 的平方;X_1 表示第一个 X。例如,A=5,k=3.即开 3 次方。 )1/3公式:X(n+1)=Xn+(A/Xn^2-Xn X_0 可5 介于 1^3 至 2^3 之间(1 的 3 次方=1,2 的 3 次方=8)以取 1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0 都可以。例如 我们取 2.0.按照公式: 第一步:X_1={2.0+[5/(2.0^2)-2.0] 21/3=1.7.}。即 5/2×2=1.25,1.25-2=-0.75,0.75×1/3=0.25, -0.25=1.75,取 2 位数值,即 1.7。第二步:X_2={1.7+[5/(1.7^2)-1.7]1/3=1.71}.。即 5/1.7×1.7=1.7-1.7=0.03, 0.03×1/3=0.01, 1.7+0.01=1.71。取 3 位数,比前面多取一位数。 第四步:第三步:X_3={1.71+[5/(1.71^2)-1.71]1/3=1.709} X_4={1.709+[5/(1.709^2)-1.709]1/3=1.7099}.这种方法可以自动调节,第一步与第三步取值偏大,但是计算出来以后输出值会自动转小;第 二步,第四步输入值偏小,输出值自动转大。X_4=1.7099. 以取 1.1,1.2,1.3,。 。。1.8,1.9 中的任何一个。 大于或等于零``,即 a 为非负数 开平方公式 当然也可......a 必须 X(n + 1) = Xn + 5(A / Xn ? Xn)1 / 2.。 (n,n+1 与是下角标)例如,A=5:介于 2 的平方至 3 的平方;之间。我们取初始值 2.1,2.2,2.3,2.4,2.5, 2.6,2.7,2.8,2.9 都可以,我们最好取 中间值 2.5。 第一步: 2.5+(5/2.5-2.5)1/2=2.2;即 5/2.5=2,2-2.5=-0.5,第二步:0.5×1/2=-0.25,2.5+(-0.25)=2.25,取 2 位数 2.2。 2.2+(5/2.2-2.2)1/2=2.23;即 5/2.2=2.272-2.2=-0.07272,-0.0=-0.0+0.。取 3 位数 2.23 。 第三步:2.23+(5/2.23-2.23)1/2=2.236。 即5/2.23=2.2421525,,2.=0.0121525,,0./2=0.00607,,2.23+0.006=2.236., 取 4 位数。 每一步多取一位数。这个方法又叫反馈开方,即使你输入 例一个错误的数值,也没有关系,输出值会自动调节,接近准确值。 如 A=200.200 介如 10 的平方---20 的平方之间。初始值可以取 11,12 15+(200/15-15),13,14,15,16,17,18,19。我们去 15.1/2=14。取 19 也一样得出 14.。 :19+(200/19-19)1/2=14.。 14+(200/14-14)1/2=14.1。 14.1+(200/14.1-14.1)1/2=14.14. 顺便介绍开中间值,即 1.5。 1.5+(5/1.5^2;-1.5)1/3=1.7。 5 次方公式: 例如:A=5;X(n+1)=Xn+(A/X^4-Xn)1/5 . (n,n+1 是下角标) 5 介入 1 的 5 次方至 2 的 5 次方之间。2 的 5 次方是 32,5 靠近 1的 5 次方。初始值可以取 1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8, 1.9.例如我们取中间值 1.4; 1.38+(5/1.38^4-1.38)1/5=1.379. 1/5=1.+(5/1.4^4-1.4)1/5=1.38 1.379+(5/1.379^4-1.379) 这计算次数与精确度成为正比。即 5=1.3797^5.。个方法的依据是根据牛顿切线法得来。也可以通过牛顿二项式定理推出。 ( 王晓明) 三,求最大公约数的欧几里得算法还没有找到公式。 1、时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运 行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知 道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法 花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多 ,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。 记为 T(n)。 (2)时间复杂度 在刚才提到的时间频度中,n 称为问题的规模,当 n 不断变化时,时间 频度 T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此 ,我们引入时间复杂度概念。 一般情况下,算法中基本操作重复执行的次数是问题规模 n 的某个函数 ,用 T(n)表示,若有某个辅助函数 f(n),使得当 n 趋近于无穷大时,T (n)/f(n)的极限值为不等于零的常数,则称 f(n)是 T(n)的同数量级函数。 记作 T(n)=O(f(n)),称 O(f(n)) 为算法的渐进时间复杂度,简称时间复杂 度。 在各种不同算法中,若算法中语句执行次数为一个常数,则时间复杂 度为 O(1),另外,在时间频度不相同时,时间复杂度有可能相同,如 T(n) =n2+3n+4 与 T(n)=4n2+2n+1 它们的频度不同,但时间复杂度相同,都为 O (n2)。 按数量级递增排列,常见的时间复杂度有: 常数阶 O(1),对数阶 O(log2n),线性阶 O(n), 线性对数阶 O(nlog2n),平方阶 O(n2),立方阶 O(n3),..., k 次方阶 O(nk),指数阶 O(2n)。随着问题规模 n 的不断增大,上述时间复 杂度不断增大,算法的执行效率越低。 2、空间复杂度 与时间复杂度类似,空间复杂度是指算法在计算机内执行时所需存储 空间的度量。记作: S(n)=O(f(n)) 我们一般所讨论的是除正常占用内存开销外的辅助存储单元规模。讨 论方法与时间复杂度类似,不再赘述。 &过去 12 个月是计算机围棋史上最令人振奋的时刻&计算机科学家马丁.穆勒 星期天晚上在满座的欧洲围棋会议的演讲厅里面说.数以百计的围棋手们在 EGC 周末赛事五轮令人精疲力尽的比赛后留了下来,聆听 Alberta 大学来的穆 勒教授讲述计算机围棋的革命性进展. 快速的回顾了过去 50 年的计算机围棋研究,穆勒指出,老式的围棋程序如 Goliath 和手谈,编程时注重在围棋知识,而新的方法&monte carlo&和 UCT, 注重于海量的搜索和随机的下法搜索,而不是确定性的算法.Gnugo 和 MoGo 是 使用这种新方法的主要程序.&他们在 7X7 的棋盘是完美的,在 9X9 的棋盘上相 当于业余 3 段&,穆勒说.恐怕没有一个棋手输棋会像穆勒在 06 年 12 月被 Gnuno 击败时这样高兴. 去年,郭娟职业五段和 crazystone 程序在 7X7 的棋盘上进行了一系列的比赛, 程序总是取得胜利或者执白的时候和棋.今年,MoGo 在 9X9 的棋盘上对郭娟取 得了 9 胜 5 负的好成绩.&Monte Carlo&总是下出一些奇怪的下法,穆勒对此不 无担忧.&但是这种算法善于取胜& 这种程序每秒钟进行 100,000 次仿真或者 说 1 百万步.&为什么这种算法如此有效&穆勒问. &还没有理论上的解释,尽 管经验性的结果是如此之好& 换句话说,&我们还不知道&. 尽管穆勒说,很多研究者现在认为,职业水平的围棋程序出现只是一个时间 问题.他觉得可能还有些遥远.&我自己的看法是我们还需要一到两个的好点 子,但我还不知道这些点子从哪里得到 数据结构(数组,链表,堆栈,队列,串,树,二叉树,四叉,八叉树,图 ,映射表 c++中;map,Hash Table)+算法(NP+NP 完全+NP 难度问题) 是王道! 复杂度:log(n)&n&nlog2(n)&n2&nk&2n&kn&n! 任何问题可以转化为若干状态的连续集.我们先描述问题在某一时刻的情 况,再归纳问题从一个状态到一个状态的转移操作.由计算机模拟这些状态 转移的过程,遍历问题所有状态,找到从开始状态到目标状态的可行路径, 就找到了问题的解. 1:地图寻路问题 .盲目搜索策略有:广度优先搜索,深度优先,迭代 加深搜索. 启发式搜索有:A*(用评估函数,永远先扩展最有 可能更快达到目标点的节点) A算法()IDA*(A*+迭代加深 iterate depth)双向搜索. 2:博弈问题 解决AI问题,在博弈数搜索中通常会使用 Alpha-Beta 剪 枝,当总是先展开评估值高的节点时用 SSS*算法,其改进型是 MemSS*(对 内存空间有上限控制) . 3:智能算法 遗传算法(Genetic Algorithm),模拟退火算法 (Simulater Annealing),禁忌搜索(Tabu Search),人工神经网络 (Artificial Neural Network) 4:优化 a 数学方法的改进 b 预运算节省时间,或者重复运算来节省空间 c 简化算法求得近似解来取代精确解 d 改进数据组织方式,用更少的操作处理更多的数据 e 尽可能让计算机做并行操作 注意有限状态机和多线程的运用.基于行为描述的语言(A Behavior Language ABL) 分治法在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分 而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题, 再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原 问题的解即子问题的解的合并。&&阅读全文 ? 话说递归与 HANOI 塔 ? 二分法求方程近似解 ? 用 C++实现合并排序 ? 求最大值和最小值的分治算法动态规划法最优化原理是动态规划的基础。“一个过程的最优决策具有这样的性 质:即无论其初始状态和初始决策如何,其今后诸策略对以第一个决策所形 成的状态作为初始状态的过程而言,必须构成最优策略”。简言之,一个最 优策略的子策略,对于它的初态和终态而言也必是最优的。 &&阅读全文 ? ? ? ? 动态规划求 0/1 背包问题 最长公共子串问题的实现 用动态规划实现导弹拦截 最大化投资回报问题的实现AGVS 中循环死锁搜索算法的改进研究 摘要:针对国内 AGVS 中循环死锁搜索算法研究中存在的搜索循环死锁类 型不全的问题,文中通过将 Petri 网分解为有限个包含所有托肯位置变化情 况的 T-R 图,然后在 T-R 图上使用图论中的强连通分支理论,从而找出 AGVS 中的所有循环死锁。并从理论上证明了改进算法的正确性。仿真结果与理论 分析相符。该算法可以找到 AGVS 中的所有循环死锁。 .1 国内外研究现状 对于死锁问题的提出,最早是指计算机内部操作系统的进程间的堵塞或循环 等待的发生[1],在现代的制造业当中,Banaszak 等针对 FMS 并行加工过程 提出了一种死锁避免算法(deadlock avoidance algorithm ,DAA) ,该算 法对死锁的避免是充分的,但在很多情况下限制了资源的有效利用[2]; Hsieh 等[3]建立了一种同步死锁避免控制器(deadlock avoidance controller ,DAC) ,通过 Petri 网 (PN) 技术实现了死锁的避免和资源的 高效利用; Xing[4]提出了另一种死锁避免策略(deadlock avoidance policy ,DAP) ,该方法基于死锁结构的概念,针对两种不同的情况,该策略 采用了不同的控制方法 ρ1 和 ρ2 ,ρ1 在其适用条件范围内对死锁的避免 是充分必要的; Lewis 等[5]建立了一种在线的死锁避免方法,该方法在 FMS 的产品类型和工艺路线变化时,能在线调整死锁避免算法,这种算法可以施 用在规模不太大的 FMS 中。 针对 AGVS 的死锁研究情况,Nai qi 等针对 AGVS 的特点提出了面向资源的 Petri 网来解决 AGVS 的循环死锁问题[6][7], Y.A.Bozer 等提出了着色的 面向资源的 Petri 网(CROPN)来解决 AGVS 中的循环死锁问题[8][9]。朱枫等 在 2001 年提出的了一种循环死锁搜索算法[10]。刘斌提出了一个通过控制 缓冲站的 AGV 数量来实现 AGVS 无死锁运行[11]。从目前的研究现状来看, petri 网是研究这一问题的主要工具。对于死锁控制的方法,目前已经形成 了成熟的理论体系,但对于死锁的搜索还没有一个行之有效算法,并且目前 的搜索算法,都有某种程度的局限性,实用性不是太强,国内外不少学者使 用了不同的 Petri 网模型,来研究这个问题[12][13][14][15]。江志斌对 各种 Petri 网模型研究这个问题,分别指出了各自的优缺点[16]。 1.2 国内主要循环死锁搜索算法简单介绍 朱枫在 2001 年提出了一个循环死锁搜索方法[10]。简单介绍如下: ①首先生成前序图 G(M,F),该图为有向图,它以 M 为顶点集,其边集为 F= {(i,j)| r 使 i∈Tr,j∈Tr 且 s 使 i=trs,j=trs-1}.其物理意义是机器人执 行完初等运动 j 后,将有可能执行初等运动 i,或者初等运动 i 阻塞初等运动 j 。 ②构造冲突图 G(M,C),该图为无向图,它以 AGV 所执行的任务为顶点集,其边 集为 C={(i,j)|i∈M,j∈M,且任务 i 与任务 j 冲突}。 ③构造阻塞图 G(M,O),该图是有向图,并以 M 为顶点集,其边集为 O={(i,j)| (i,j)∈F 或 k∈M 使(i,k)∈C,(k,j)∈F}.其物理意义是正在执行任务 i 的 AGV,或直接阻塞或通过冲突的初等运动 k 阻塞正在执行任务 j 的 AGV。 ④算法如下: while(O 非空) { 从 O 中取一边(i,j) (步骤 1) if((i,j) C) (步骤 2) searchpath(j,i); (步骤 3) 在 O 中删除边(i,j); (步骤 4) } 1.3 循环死锁搜索算法存在的局限 对于朱枫的算法,只能搜索由于阻塞而引起的循环死锁,对于由于冲突而引 起的循环死锁时,由于步骤 2 的约束,无法搜索到由于冲突而引起的循环死 锁。在国外,目前的循环死锁搜索算法主要是针对由于冲突而引起的循环死 锁的,目前已经报道的这两类算法,都不能搜索全部类型的循环死锁。但在 许多的 AGVS 中,两种循环死锁是共同存在于系统中。针对这个情况,文中 提出了一个循环死锁搜索算法,可以发现系统中所有类型的循环死锁。 2. AGVS 循环死锁搜索问题的定义和数学模型 2.1 面向资源的着色 petri 网(CROPN)定义死锁 (1)面向资源的着色 petri 网(CROPN)定义 面向资源的着色 petri 网是由 7 要元描述的一张有向图: PN=(P,T,I,O,M0,K,C) 此处: ①P={p1,p2,…,pn}是库所的有限集合,n&0 为库所的个数 ②T={t1,t2,…,tm}是变迁的有限集合,m&0 为变迁的个数, ③ 是输入函数,它定义了从 P 到 T 的有向弧的重复数或权的集合 ④ 是输出函数,它定义了从 T 到 P 的有向弧的重复数或权的集合 ⑤M0:P0 N,表示系统开始运行时在各资源位置上 AGV 的数量,用 M0(p)表示 ,M0(p)表示一个 R×1 维的向量,其中 R 为缓冲站的数量,向量中的每个元 素表示在开始时缓冲站上的 AGV 数量。 ⑥K:各资源的资源容量,K(p) 表示一个 R×1 维的向量, 其中 R 为缓冲站的 数量,向量中的每个元素表示缓冲站能够容纳的 AGV 最大数。 ⑦C={b1,……,bn}表示为了区分个托肯(token)所代表的 AGV 而给托肯着上 的颜色,如果变迁 t 的使能与 AGV#i 相关,则标上与 AGV#i 代表的托肯一样的 颜色。 ⑧ :变迁 t 的输入库所; :变迁 t 的输出库所; :库所 p 的输入变迁; : 库所 p 的输出变迁 ⑨变迁的使能条件: ,在标识 M(p)下使能,当且仅当: :M(p)≥I(p,t) 物理意义是系统中 AGV 能够在规定的时间内释放资源。也称为正常使能,反 之,称为不正常使能 ⑩变迁的激发条件: M(p)-I(p,t)+O(p,t)≤K(p) 物理意义是系统中的 AGV 能够在规定的时间内占用资源。也称为正常激发, 反之,称为不正常激发。 (2)CROPN 中循环死锁发生的条件 由⑨和⑩,我们可以得到 CROPN 中循环死锁发生的条件: 对于在 CROPN 模型上构成环路的一个变迁序列 ,如果其中的某个变迁无法 正常激发或使能,引起环路中的所有库所充满了托肯,并且每个库所的托肯 数目都等于资源容量,而且在环路上的变迁,变迁颜色是不同的。 例如,根据图 1(a),可以得到如下的 CROPN 模型(b) (a) AGVS 运行图 (b) 由(a)得到的 CROPN 模型 注:(a)中的道路编号按照非减序与(b)中的编号 7,…,14 对应 图 1 CROPN 模型 2.2 T-R 图定义死锁 E.G.Coffiman 给出的 T-R 图定义[1],我们可以对应的给出 AGVS 中的死锁问 题定义如下: 在某状态时刻 t,AGVS 需要执行如下的任务集{T1,T2,…,Tm},执行这些任务 需要占用的资源集{R1,R2,…,Rn},构造图 G=&V,E&,其中点集 V 为资源集 {R1,R2,…,Rn},边集 E 定义如下:如果系统中的一辆 AGV 从资源 i 将要行 进到资源 j,则点 Ri 到 Rj 之间存在着一条边,方向从 AGV 已经占用的资源指向 指向将要占用的资源,边集 E 表示 AGVS 执行的任务。边集 E 对应于 Petri 网的 变迁,点集 R 表示 AGVS 执行的任务所占用的资源对应于 Petri 网的库所。 资源容量和库所容量在文中意义相同。 如果资源图中存在着有向环路: Ri→…→Rj→…→Ri,其中至少环路上的一个任务,无法正常使能或激发, 引发环路中的库所容量达到最大,我们称系统存在着循环死锁现象。如图 2(a),该图中存在着有向环路 R1→R2→R3→R1,如果该有向环路中的边, 至少有一个变迁不能正常使能或激发,并引起环路中的库所容量达到最大, 那么存在循环死锁。 (a)由于阻塞引起的循环死锁 (b)由于冲突引起的循环死锁 图 2 T-R 图下循环死锁示意图 2.3 Petri 网与 T-R 图之间的关系 Petri 网定义的数学模型是动态的,包含了系统所有时刻的信息,T-R 图对 系统的定义是静态的,包含系统某一状态时刻的信息,死锁的发生是从某一 状态时刻开始的,也就是 Petri 网模型下的一个局部状态信息,可以说 T-R 图是 Petri 网在某一时刻的表现形式。两者之间的关系可以形式化表示如下 : CROPN= (式 1) 3. 引起死锁现象的原因 Xing 给出了 AGVS 出现死锁现象的原因: (1)相互排斥:系统中某一辆 AGV 在行进过程中,占用某一资源时,其他 AGV 不允许占用,某一资源在同一时间只能被一辆 AGV 占用。 (2)等待保持:系统中 AGV 在结束当前操作前,将一直占用这个资源。 (3)无优先权:系统中的 AGV 在结束占用资源前,其他 AGV 是不允许占用。 (4)循环等待:系统中的 AGV 都在等待彼此的资源[4]。 4.循环死锁的分类 按照循环死锁形成的原因,可以分为两类: (1)由于阻塞而引起的循环死锁: 缓冲站资源容量为 1 的情况下,AGV#1 通过缓冲站 1 后,AGV#2 由缓冲站 2 进入 缓冲站 1,AGV#2 通过缓冲站 2 后,然后 AGV#3 由缓冲站 3 进入缓冲站 2,最后 AGV#4 由缓冲站 4 进入缓冲站 3。但由于 AGV#1 发生临时故障,在缓冲站 1 的停 留时间过长,导致 AGV#2 无法正常从缓冲站 2 进入缓冲站 1,在缓冲站 2 处停 留,从而 AGV#3 只能在缓冲站 3 中停留,AGV#4 只能在缓冲站 4 停留,于是, 循环死锁形成。如图 3 所示 图 3 阻塞循环死锁示意图 注:图中括号内的数字表示缓冲站,不加括号的数字表示 AGV 存/取货物的 位置 (2)由于冲突而引起的循环死锁 如图 4 所示,缓冲站资源容量为 1 的情况下,AGV#1 由缓冲站 1 通过缓冲站 2 后 ,AGV#2 由缓冲站 2 进入缓冲站 1。但由于 AGV#1 发生临时故障,在缓冲站 1 的 停留时间过长,导致 AGV#2 无法正常从缓冲站 2 进入缓冲站 1,在缓冲站 2 处 停留,于是,循环死锁形成。 图 4 由于碰撞引起的循环死锁示意图 注:图中括号内的数字表示缓冲站,不加括号的数字表示 AGV 存/取货物的 位置 此外,还存在由于冲突和阻塞共同引起的循环死锁,这类死锁可以分 解为由于冲突或阻塞引起的循环死锁。 5.有关定义的说明 定义 1 AGVS 内,在时间区间[a,b]内,AGV 所占用的资源没有发生改变。我 们称 AGVS 当前处在状态时刻 t 内。 定义 2 所谓两 AGV 执行的任务冲突是指当在同一个资源上,某一 AGV 执行其中 一个任务时,其它 AGV 不能执行另一任务。例如,产生不同相碰撞的两任务互 相冲突。 定义 3 所谓两 AGV 执行的任务阻塞是指当某一 AGV 执行其中一个任务时,另 一 AGV 可以执行另一个任务,但当其中一个任务无法正常执行时,另一 AGV 也无法执行。 6.循环死锁搜索改进算法的讨论 6.1 循环死锁是否存在的判断算法 实例:某 AGVS,对于状态时刻 t 的 T-R 图,G=&R,T& 询问:在此状态时刻,AGVS 是否存在循环死锁 ①相关定义的说明 深度优先遍历:一种图的搜索算法,这种算法是指对于最新发现的顶点,如 果它还有以此为顶点而未访问的边,就沿此边继续访问下去。当顶点 V 的所 有边都已经被访问过,则从最后被访问的顶点开始,依次返回新近被访问的 且尚有邻接顶点未被访问过的顶点,再从该顶点重复上述搜索过程。 深度优先生成森林:在到达同一个顶点的各条边中,只能有一条边是树边, 所以深度优先搜索过程得到的全体一定组成一个森林。 树边:在图中,如果沿某条边所到达的顶点是一个未被访问过的顶点,则称 为树边。 向后边:从一个顶点到达深度优先生成森林中该顶点的祖先的一条边。 向前边:从一个顶点到达深度优先生成森林中该顶点的真子孙的边。 交叉边:既不是从祖先到子孙,又不是从子孙到祖先的边称为交叉边。 如图: 图 5 各种边的示意图 其中,实线边为树边,虚线边为其他类型的边。在这个例子中,虚线边 (3,1)和(4,1)为向后边,其他的虚线边为交叉边,没有向前边 ②算法思路: 算法分析 G=&R,T&是一个有向图,如果 AGVS 存在循环死锁,那么在图 G 中 必然存在一个圈(回路),判断一个图 G 中是否含有圈,可对 G 做深度优先遍 历,一旦找到一条向后边,这个图中存在着回路,检查在回路内的变迁能否 正常使能或激发,如果有不正常使能或激发的,并引起回路中的资源容量达 到最大,则必存在循环死锁。 伪码如下: i: found: int mark[V];//该数组表示 T-R 图中的节点是否曾经访问过,0 表示未访问 ,1 表示已经访问 G:ARRAY[1…T] of graph 表示存储 T-R 图的邻接矩阵和相关性质 Begin for t∈状态时刻集(t 的初值为第一个状态时刻,终值为最后一个状态时 刻) do begin If 当前状态时刻的 T-R 图,所有变迁都能使能和激发 then 系统状态时刻 t 正常;进入下一状态时刻 else 记录不能正常激发或使能的变迁; for i:=1 to G[t].count do begin mark[i]:=0; i:=1 found:=false while(i&= G[t].count) and not found do begin DFS(G,i); i:=i+1; end{for}; 进入下一状态时刻; end{for}; procedure DFS(var G:i:int) begin mark[i]:=1; j:=FIRST(G,i);//取 i 的第一个邻接点 while(j&&0)and not found do begin if mark[j]=0 then DFS(G,i);//如果 i 的邻接点未曾访问过为树边,已经访问过了的点为向后 边 else begin if(包含向后边的回路中,包含着不能正常激发或使能的变迁,并且回路 中的库所容量达到最大) then found:= end{if}; j:=NEXT(G,i,j)//取 j 的下一个邻接点 end{if}; end{while}; 从上述算法可以看出,最多只有 1 个顶点被访问 2 次,其余顶点最多被访问 1 次。因此,算法的时间复杂度为 O(NTn)。其中,NT 表示系统的所有状态时 刻数。 6.2 搜索 T-R 图中所有循环死锁的算法 实例:某 AGVS,对于状态时刻 t 的 T-R 图,G=&R,T& 询问:该图中存在多少个循环死锁特征的环路 算法设计:一个图的强连通分支是指对于一个图 G 的子图 ,对于 ,存在着通 路 P1,P2,使得 u,v 是相互可达的,我们说 是 G 的一个强连通分支。下面给出 一个求某状态时刻 t 的所有循环死锁的方法: ①对于一个给定的图 G 进行深度优先搜索并按递归调用完成的先后顺序对各 顶点进行编号; ②改变 G 中每一条边的方向构造新的有向图 ; ③按照①中确定的顶点编号,从编号最大的顶点开始,对 进行深度优先遍 历。如果在遍历过程中没有访问所有 中的顶点,则从未被访问过的顶点中 选取编号最大的顶点,并从此顶点开始继续作深度优先遍历; ④在最后得到的 的深度优先生成森林中,每棵树的上的顶点恰组成 G 的一 个强连通分支; ⑤对于已经发现的强连通分支,检测各分支的变迁使能和激发情况以及资源 容量的变化情况,判断是否构成循环死锁; ⑥输出所有的死锁。 算法分析:对于该算法对于一个给定的图 G,进行两次深度优先搜索,每一 次需要 O(|V|+|E|),算法的时间复杂度为 O(NT(|V|+|E|))。其中 NT 表示系 统的所有状态时刻数。这种算法在朱枫提出的算法基础上,可以发现由于避 免碰撞而引起的循环死锁,同时可以发现其他类型的循环死锁。 6.3 循环死锁搜索算法 我们将 6.1 中提到的算法,在此处定义为函数 FUNC boolean findcycledeadlock(), 将 6.2 中提到的算法,在此处定义为 Procedure search_deadlock 循环死锁搜索算法的伪码为: begin for t∈状态时刻集 do //t 的初值为第一个状态时刻,终值为最后一个状 态时刻 if 当前状态时刻的 T-R 图,所有变迁都能使能和激发 then 系统状态时刻正常; else if findcycledeadlock() then begin search_ end{if} end{if} end{for} end 6.4 实例分析 AGVS,某状态时刻 t 的 T-R 图如下: 图 6 某状态时刻的 T-R 图 在 cd、gf、eb 处均有一个变迁不能激发,可能存在循环死锁,调用 6.1 中算 法,进行判断,发现向后边,并在向后边所在的回路中包含不能正常激发的 变迁,并发现含有向后边的回路中的各资源容量达到最大。所以,存在循环 死锁。调用 6.2 中的算法,搜索所有的循环死锁; ①编号过程:通过对图 6 进行深度优先搜索,得到标号如下图: 图 7 对图 6 进行深度优先搜索形成的编号 图 7 中节点内的左侧数字为访问节点的开始标号,右侧数字为访问节点的完 成标号。 ②反向图 为图 8,在图 8 上继续进行深度优先遍历。 图 8 图.6 的 从图 7 的最大完成标号的顶点 b 出发,在图 8 上进行深度优先遍历,得出 {b,a,e}为一个强连通分支,又因为 eb 为一个不能正常激发的变迁,并引起 了回路{b,a,e}各资源容量达到最大,所以{b,a,e}是一个循环死锁;再从 不属于{b,a,e}有着最大完成时刻的 c 出发,进行深度优先搜索,同理得到 {c,d}是一个循环死锁;然后从 g 出发,进行深度优先搜索,同理得到{g,f} 是一个循环死锁,找到当前状态时刻的所有循环死锁。其中,{c,d}和 {g,f}是由于冲突引起的循环死锁。由此可见,仿真结果与理论分析相符。 如果使用[10]中的方法,进行循环死锁的搜索,只能搜索到{b,a,e} 6.5 循环死锁搜索改进算法正确性的证明 证明:共分三个步骤进行证明,步骤(1)和(2)说明 6.2 算法中的步骤①-④ 能够发现 T-R 图中的所有强连通分支,步骤(3)说明算法能发现所有的状态 时刻时刻下的循环死锁。 (1)假设对 作深度优先搜索时,我们从某一个树根顶点 x 开始搜索,并且在 这个搜索过程中访问了顶点 v(或顶点 w)。由于 v 和 w 在 中相互有路可以到达 ,所以 v 和 w 都在以 x 为根的同一棵树上。 (2)反之,设 v 和 w 在 的深度优先生成森林中以 x 为根的同一棵树上。因为在 这棵树上 v 是 x 的子孙,所以在 中从 x 到 v 有一条路,从而在 G 中从 v 到 x 有一 条路。另外,在 G 中从 x 到 v 也有一条路。事实上,由于对 进行深度优先搜 索过程中,取顶点 x 作为树根时,顶点 v 尚未访问到,所以顶点 x 的编号大于 顶点 v 的编号,也就是说,对 G 作深度优先搜索时,在顶点 v 的递归调用比在 顶点 x 的递归调用更早完成。另一方面,对 G 作深度优先搜索时,在顶点 x 的 递归调用比在顶点 v 的递归调用更早开始,否则,由于从 v 到 x 有路,在顶点 x 的递归调用将比在顶点 v 的递归调用更早完成。综上,顶点 v 恰是在对顶点 x 进行递归调用过程中被访问的。也就是,在 G 的深度优先生成森林中,v 是 x 的子孙,于是在 G 中从 x 到 v 有一条路。这样,顶点 x 和顶点 v 就属于 G 的同一 个强连通分支。因此,v 和 w 属于 G 的同一个强连通分支。 MTD(f)算法 前面已经介绍过,零宽窗口搜索(也称为极小窗口搜索)的结果只有二种, 要么估值在窗口之上,要么估值在窗口之下。因此当我们对某段区间进行搜 索时,可以选取区间上的一点进行零宽窗口搜索试探,利用其结果一分为二 的特点,缩小估值的取值区间。在确定新的估值区间后,我们还可以再次进 行试探。通过反复试探,就可以不断地缩小搜索范围,最终找到局面估值。 在选择每一次的试探值时,通常的想法是采用二分法,即每次都选择估值区 间的中点进行试探。采用二分法的效率确实比较高,但是荷兰计算机科学家 Aske Plaat 经研究发现,在多次搜索试探过程中,局面估值往往会出现在 前一次搜索的返回值附近,因此机械地选取中点做为新的试探值并不是最高 效的。于是他提出了一种选取前一次搜索返回值做为新试探值的 MTD 算法( Memory-enhanced Test Driver,缓存增强试探法)――MTD(f)。 MTD(f)算法的代码如下: int mtd(int f, int depth){ //搜索区间上、下限 = INF_VALUE; (g == lower) { else { beta = do { int g = int upper if } } //进int lower = -INF_VALUE; //确定试探值 beta = g + 1; 行零宽窗口试探 0);g = alpha_beta(beta-1, beta, depth, //调整搜索区间 if (g & beta) { } else { } } while (lower & upper);upper = lower =} MTD(f)算法十分简捷,却又十分高效。但由于 MTD(f)算法需要对于同一局 面多次进行搜索,因此必须采用散列表,否则无法体现其高效性,这也是 MTD 算法名称中缓存增强(Memory-enhanced)的含义所在。实践表明,在 同样应用散列表的情况下,MTD(f)算法的搜索速度一般会比 PVS 算法略快些 ,MTD(f)算法的高效性已经得到普遍认可。 在应用 MTD(f)算法时,需要一个初始试探值,一般可以简单地选取初始搜 索区间的中点,当然也可以根据具体情况选择对搜索更有利的值。由于该算 法必须采用散列表,散列表的性能对于整体算法的效率也是至关重要的。另 外,估值的取值范围大小,也会影响 MTD(f)算法的搜索速度。一般来说, 估值越粗略(即取值范围较小) ,搜索速度会越快,这是因为试探的次数较 少所致。 如果算法涉及最佳棋步的求解,还有一个问题值得注意。如果 MTD(f)最后 一次搜索的是 alpha 节点,那么 alpha_beta()函数得到的结果将是估值上限 ,而其求得的“最佳棋步”也只是满足此上限条件的棋步,不一定是真正的 最佳棋步。因此在 alpha_beta()函数(或散列表中)中应采取相应的措施 ,以避免输出该虚假的最佳棋步。或者可以对上述 MTD(f)代码加以修改, 当出现上述情况时,就以 beta 节点再搜索一次,确保获得正确的最佳棋步 : …… } while (lower & upper); //如果最后一次搜索 if (g &得到的只是上限,需再搜索一次,确保获得正确的最佳棋步 beta) { g = alpha_beta(g-1, g, depth, 0); }} 书系统介绍了禁忌搜索算法、模拟退火算法、遗传算法、蚁群优化算法、人 工神经网络算法和拉格朗日松弛算法等现代优化计算方法的模型与理论、应 用技术和应用案例。(3)由于在 6.2 算法中的步骤⑤已经验证了在这些强连通分支上至少一个变 迁是不能激发或使能的并使强连通分支各资源容量达到最大。因此,可以搜 索到所有的循环死锁 分析与展望 对于循环死锁的搜索算法而言,无论是国内已经提出的还是国外已经提出的 ,都存在着很多不必要的操作,当系统的状态时刻是正常的时候,目前已经 报道的循环死锁的搜索算法,都要进行全部操作,而改进算法中当系统的状 态时刻是正常时,是不需要进行全部操作的,只有在发现存在循环死锁时, 才找出所有的循环死锁。 同时,这种改进算法不但能找出所有的循环死锁,同时可以清楚的显示各个 循环死锁之间的关系,便于发现更加有效的控制规则。 这个改进算法,虽然比朱枫的算法[10]效果更好,改进算法能够搜索到全 部的循环死锁,但我们也发现,这个改进算法对于系统中出现的全部死锁( 包括循环死锁和非循环死锁)的搜索仍存在一定的问题。我们希望下一步可 否在这个改进算法的基础上,开发出一个效率更高的算法,来解决为 AGVS 搜索出全部的死锁。 贪心算法贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择 。就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部 最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛 的许多问题他能产生整体最优解或者是整体最优解的近似解。 &&阅读全文 ? 最小生成树之 Prim 算法 ? 最小生成树之 kruskal 算法 ? 贪心算法在背包中的应用 ? 汽车加油问题之贪心算法回溯法回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当 探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择 ,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点 称为“回溯点”。&&阅读全文 ? 回溯法之数的划分 ? 回溯法求解 运动员最佳配对问题 ? 回溯法解决汽车加油次数最少问题 ? 用回溯法找出 n 个自然数中取 r 个数的全排列分支限界法在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分 而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题, 再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原 问题的解即子问题的解的合并。&&阅读全文 ? 分支限界法之装载问题 ? 分支限界法之布线问题 ? 分支限界法之 0 1 背包问题 ? 分支限界法之旅行售货员问题求围棋程序的算法思想一 从地球到月球 从电脑诞生之日起,人们对于电脑就充满了幻想。尤其是在人工智能上,对于电脑超过人脑,有 人兴奋,有人担忧,但曾经几乎所有人都认为这会是真的。尤其当“深蓝”击败卡斯帕罗夫之后, 人们已经开始担忧,电脑超过人脑,会不会就发生在明天? 但这种担忧实在是来的太早了。 本世纪七八十年代,对人工智能学家们来说,就象是无忧无虑的童年。他们雄心勃勃,甚至排出 了电脑替代人脑的时间表。在表中,现在,就已经应该是电脑超过人脑的日子了。现在,“深蓝” 确实战胜了卡斯帕罗夫,但人工智能学家们的时间表早已被抛到了脑后。有人甚 至打了这样一 个比喻来说明人工智能上所取得的成就:人们想登上月球,他们造了一个梯子,用这个梯子爬上 了一棵树,然后自豪地宣称:“现在,我们已向月球前进了一大步!” 现在,电脑已经渗入到了我们生活的各个方面,在生产和生活中,我们已经有些难以想象脱离电 脑的状况了,如果说这些形形色色的电脑只不过是花里胡哨的各种梯子,似乎实在是说不过去。 我们先看看梯子是怎么回事吧。 梯子的发明人是图灵博士。图灵在考虑可计算的机器的性质时,首先是设想一个人在计算,他把 这个人的计算行为抽象成了这样一台机器: 有一条无穷长的纸带子, 一个有很多状态的机器在纸 带上左右滑动,并且可以根据所读到的内容改变自己的状态或者改写纸带的内容。 这就是大名 鼎鼎的图灵机了。当前的所有计算机,在理论上都是可以被图灵机模拟的。 请注意图灵机有一个重要的能力:改写纸带的能力。如果没有这个能力,那这台机器叫做有穷自 动机。它和图灵机间的计算能力差着三个档次呢。 (注意:在一条无穷长的纸带上读东西,在另 一条纸带上写东西的机器也是有穷自动机) 。 判断这些东西的计算能力用的是这些机器所能接受的语言的概念。这个语言虽然是抽象的语言, 但也和我们平时所说的语言差不多, 你只要理解成这机器能听懂什么话也就差不太多了。 乔姆斯 基把语言分成了 0, 1,2 , 3 四个等级,0 级能力最强,3 级最差。这四个等级之间有着难以 逾越的鸿沟。 这里的 3 级语言也叫做正规语言,就是有穷自动机能听懂的, 2 级语言叫做上下文无关语言, 意思是一个词,不用管它的上下文,就可以听懂了。1 级语言就是上下文相关的了,也就是说机 器还得揣摩这话前后的意思。零级语言就是图灵机可以接受的语言了。 我们用数数的本事就可以体会 1,2,3 型语言的能力差别了。 对于数数,有这么一个笑话:两个贵族比赛,看谁说出的数更大,第一个人绞尽脑汁,冥思苦想 十几分钟后说:3, 轮到第二个人,他想了很久很久,最后说:你赢了。 数到 3 的本事哪型语言都会,我这里说的数数本事是从一数起,只要不老死,数多少个都行。3 型语言,也就是正规语言,是不会数数的。 2 型语言(上下文无关语言)会数数,但同时数两 个数就不会了。1 型语言就是数多少个数都行的了。而 0 型语言的能力又比 1 型语言强的多。 也就是说,图灵机看上去简单,实际上是还是很牛的。 但是图灵自己就发现了图灵机也有不照的时候了, 这就是图灵机的停机问题。 我们可以这样说明 图灵机的停机问题:假设当图灵机听懂了一句话,它就不再琢磨这句话了,现在我给图灵机一句 话,问它“你听的懂吗?”如果它听的懂,它会回答“是”,但如果它听不懂,很 可能它永远也不 会知道自己听不懂。-------------------------------------------------------------------------------二 有穷与无穷 用天梯登上月球的想法,现代人也许会觉得荒谬,但在古人眼里,未必如此。梯子可以上树、可 以上房、可以上城,甚至可以上山,为什么不能上天呢? 因为做梯子的原材料数量不够, 强度不够, 天梯也没有可搭的地方, 等等等等, 但古人都不清楚, 他们根本不知道地球和月球之间有多远。 国际象棋八八六十四见方的棋盘,围棋纵横 361 交叉点的棋枰,它们的变化从理论上说是有限 的,因此,理论上,这些问题都是图灵机可解决的。但是,就在我们理论上严谨地一步步得出结 论时,我们早已不知不觉地越过了在实际计算意义上有穷与无穷的界限。 以围棋为例,围棋有多少种变化?比较常见的有两种估计方法,一是:假设不会出现大家都被提 光再从头再来的情况,那么,第一步有 361 种选择,第二步有 360 种选择,以后的情况大致如 此,我们就以 361 为界,那么变化数是 361!,约为 10 的 768 次方。另一种估计方法大概是宋 朝的沈括老先生首先使用的:棋盘上每个点有黑,白,空三种状态,所以围棋变化数是 3 的 361 次方,约为 10 的 172 次方,用沈老先生的说法,就是“连书‘万’字四十三”。这虽然也很大,但 比起前面的估计值来,小的实在是太多了。如果这种估计正确,那电脑下围棋无疑轻松了许多。 不幸的是,沈老先生的估计方法是错误的。他只考虑了这种种状态,却没有考虑这些状态间的相 互关系。就比如数学中的图,沈老先生只考虑了顶点的总数,却忘了把连接顶点的边算进去了。 如果我们不考虑边,就考虑这“连书‘万’字四十三”的状态,如果我可以对于每个状态都精确地算 出价值的话,那么电脑只需要查价值表就可以确定该怎样下棋了,这样,电脑需要储存的变化数 也就是“连书‘万’字四十三”,但问题是,这些价值是怎么算出来的?总不 会看到一个状态之后 就能猜出它的价值吧。因此,假设有一个电脑围棋机器,虽然在执行的时候他可以只考虑不同状 态的价值,但为了造这台机器,我们还得把所有这些状态的关系都考虑进去。 按照第一种估计方法得到的 10 的 768 次方又是个什么概念呢?宇宙中所有基本粒子的总数, 据 估计,为 10 的 80 次方。如果没有一些简化计算的措施,这比宇宙中粒子总数还要大数不清倍的 数字对我们来说,又和无穷有什么区别? 其实, 连第一种估计方法都是错误的。 围棋真正的变化数, 10 的(3 的 361 次方)次方都挡不住, 连 大学学历的人都清楚,一旦出现指数天梯,那这个数字有多大已经是不可想象的了。 这一点并不能说明围棋不是图灵机实际可解的。不过至少告诉我们,遍历的方法是不可行的。所 以,我们暂时把围棋的状态当作无穷来看。在这里,我们用准无穷来称呼到达实际不可计算程度 的状态数。 人们在谈到围棋与国际象棋的比较时, 总说围棋的变化远多于国际象棋。 但如果把这作为电脑下 围棋远难于下国际象棋的原因是不充分的, 并不是状态越多的东西越复杂, 况且国际象棋的变化 同样也是天文数字。 但是, 如果把国际象棋的棋盘放大, 棋子增多, 使它的变化从绝对数值上来说接近甚至超过围棋, 国际象棋还是只能给人以国际象棋的感觉而不是围棋的感觉。因为,它们的“语法”有着本质的不 同。 现在,我们考虑这样一个问题:国际象棋和围棋走子后棋局状态的变化,分别需要判断几个位置 上的状况? 国际象棋当我落下一子时,只要考虑落子点的状态就可以了,如果这里有我自己的子,这步落子 无效,如果这里有敌人的子,敌子被我吃掉,如果这里空白,那么仅仅是棋子的移位。象王车易 位、吃过路兵等情况,我们可以把它看作可以遍历的特例而暂时不予考虑。 让我们回想一下乔姆斯基四级语言中的 2 级:上下文无关语言。当排除了特殊情况之后,我们 可以认为,既然国际象棋棋局某格的状态变化与周围无关,那么,它应当是可以被能听懂(专业 上叫接受)2 级语言的机器听懂的。我们可以把国际象棋理解成一个上下文无关语言。 回到围棋,当我们落下一子时,棋盘会变成什么样?如果周围全是敌子,有些敌子没了气,那敌 子全部拿走,如果周围有自己的子,敌子没被拿走,自己的子反而没了气,那就是自填死。 听起来好象也很简单,但棋盘的变化是需要看周围的情况而决定的。如果只看落子点的状态,那 我们什么结论也得不到。也就是说,围棋不能用上下文无关语言来等价,至少也得用上下文有关 语言,就是会数很多数的 1 级语言. 在考虑围棋变化数的时候,劫可是不能不提。有人说“劫乃围棋精华”,可对于 1 型语言来说, 劫实在是要命的东西。1 型语言的基本要求是它的语言产生式左边不长于右边,但对于劫来说, 并非如此。有了劫,就意味着 1 型语言也接受不了围棋了。 更要命的还在后面。象三劫循环、四劫循环、长生劫等等,在现在的围棋规则中,都简单地判为 “无胜负”。其实,如果用“全局同型禁止再现”,都可以从理论上解决,并且也不如人们想象中的 那么复杂 (以后我可能会另写文章介绍多劫循环的规律) 全局同型禁止再现 也很圆满地解释了 。 劫。但是,全局同型禁止再现对于用图灵机模拟围棋,可以说是致命的一击。因为,这意味着这 台图灵机得把以前的所有状态都存储起来,而具有无限种状态数的机器不是图灵机。 国际象棋一盘棋结束,有三种状态:将死对方,被对方将死,和棋。和棋除了双方自愿外,还有 逼和、 三次同型和, 以及六十步子数不变和等等。 这意味着国际象棋在这些都是可以直接检验的, 其步数不会超过 32*60 步。可围棋就不一样了,“全局同型禁止再现”,这意味着理论上围棋可 以下 3 的 361 次方数量级这么多手!这是准无穷了。即使没有这一规则,围棋可走的步数依然 是准无穷。 而围棋的胜负又非要看整个棋盘的状态才能决定,也就是说,就算没有“全局同型禁止再现”这一 规则,我们可以用图灵机来接受围棋,但判断每一步的好坏必须追溯到这一局棋的终点,这意味 着这台图灵机要判断它不同情况下停机时的状态!而这是图灵机所无能为力的。 这里的状态是 理论状态,它和我们实际计算时会选择的状态还不一样,围棋实际对局也很少超过 361 手,但 这已经启示我们,既然国际象棋与围棋在复杂程度上差了 3 个档次,我们能够解决国际象棋问 题的算法 算法能用来对付围棋吗? 算法-------------------------------------------------------------------------------三 迷宫之路 从理论上来说, 围棋的每一步都会有一个或几个最佳选择。 如果我们真的可以遍历围棋的所有变 化并加以比较的话,我们是可以找到这些最佳下法。只是这种遍历是实际上不可实现的。 寻找围棋最佳下法的过程就象是在走一个庞大的迷宫, 迷宫中有无数的分支岔路, 有些通向死路, 有些通向幻象,还有一些路则仅仅是自己转圈。置身于这个庞大的迷宫中,当我们知道凭一生的 时间也只能走过这一迷宫的微不足道的一小部分时,我们自然会停下来,看看这 迷宫之路中有 没有什么规律。 我们先对问题进行简化,抛开全局同型禁止再现,也不考虑三劫、四劫、长生劫等等情况。这样 在走迷宫时不必判断是否会出现回路(就是绕了一圈又回来了) ,对于这种无回路的迷宫,最简 单的走法是死贴一边走(比如,一直贴左边或者一直贴右边) ,这就是一种遍历搜 索,术语叫深 度优先遍历搜索(因为它每次都要走到头再转回来走下一条) 。按上章的计算,深度优先遍历搜 索走完这个迷宫大概需要 10^(3^361)步。 所以,我们别无选择,只有换种办法来走迷宫。我们所选的办法又怎样才能达到我们的要求呢? 我们这里所谈论的迷宫的走法, 也就是解决一个问题的算法, 一般用是用复杂度的阶数来衡量算 法复杂度好坏的。首先,一个问题有它自己的尺度。比如国际象棋是 64 格棋盘,我们可以把国 际象棋问题的尺度定为 64,围棋 361 个交叉点,我们可以把围棋问题的尺度定为 361。如果你 愿意把它们的尺度分别定为 8,19 也可以,但考虑问题时显然不如 64 和 361 来的自然。 解决一个问题的算法的复杂度是根据问题的尺度与计算步数的函数来定义的。设 n 为问题的尺 度, 如果一个算法需要 n 步, 我们就说它的复杂度是 n, 如果一个算法需要 2^n 步(n 个 2 连乘), 我们说它的复杂度是 2^n。对于两种算法来说,只要他们的复杂度函数的比值不大于一个常数, 我们就称它们为同阶的。也就是说,一个需要步数为 1000n 的算法与一个需要步数为 n 的算法 是同阶的。 因为我的机器只要能把速度提高一千倍, 第一个算法就能达到第二个算法原先的速度。 但一个步数为 n^2 的算法就比一个步数为 1000n 的算法复杂度高,因为不论你的机器有多快, 对于尺度很大的问题,总还是第一个算法复杂。 因此,我们就用 O(n),o(n^2),...,o(2^n),... 来表示与步数为 n,n^2,...,2^n,... 的算法同 阶的算法的复杂程度。请注意这里的 2^n,一个 2^n 步数的算法(其实是任何 x^n(x&1)步数的 算法)比任何一个多项式步数的算法(就是 O(n),O(n^2)...这类算法)都来的复杂。比如说。一个 算法的步数约为 2^n, 第二个为 n^10, n 取 64 的时候 当 (国际象棋尺度) 前者需要 1.84*10^19 , 步,而后者需要 1.15*10^18 步,第一个比第二个要多花十多倍步数,如果问题尺度是 361(围 棋尺度) ,后者需要 3.76*10^25 步,而则前者需要 4.69*10^108 步,这次前者比后者复杂了一千 亿亿亿亿亿亿亿亿亿亿倍. 如果说一个问题可以找到复杂度为多项式的算法,我们称它属于 P 类问题,我们需要的就是复 杂度为多项式的算法,也就是说,如果围棋是 P 类问题,我们就认为它可解。而如果我们只能 找到指数等级的算法 (O(2^n)..等等),我们就认为它不可解。 而围棋的遍历需要的步数, 是指数复杂度问题的排序问题, 它比指数复杂度的问题还要复杂的多。 在人们试图用计算机解决的各种问题中,有一大类问题,包括货郎问题,背包问题等等,总计数 百个之多,被人们称为 NP 问题。之所以说它们是一类是因为人们已经证明了只要其中一个问题 可计算(就是有多项式算法) ,其他的问题就都可以计算,但现在,比起找这些问 题的多项式算 法,人们倒宁愿去证明它们不存在多项式算法。 围棋是 NP 问题吗?不知道,好象不是,但既然 NP 问题都有指数复杂度的解法,而围棋连指数 复杂度的解法都找不到,看起来,围棋似乎比 NP 问题还要复杂的多。 不过,解决一个问题,找不到最好的方法,退而求其次也不失为一种明智的选择。人们对很多 NP 问题的态度就是:找不到最好的答案,比较好的答案也不错。“深蓝”会输给卡斯帕罗夫一局, 也说明“深蓝”找到的并非最佳下法,但它已经可以在总成绩上战胜卡斯帕罗夫 了。 在各种搜索算法中,有一个 A*搜索算法,也叫做最佳搜索算法,它是对于问题的各种情况设定 一个估值函数,假设我们选择的是值最小的道路,在搜索迷宫的时候,A*算法根据估值函数判 断下一步应选择的道路,并不停地用走过的实际路线的价凵希 作者曾经设想过一个围棋 AI 模型:把所有的棋子以连在一起的一块为基本单位,而后再根据棋 子的形状,眼位情况,赋与它强度、影响力等属性,用力学模型来分析全局势力范围,并据此选 择下一手的大致位置。实际上这就是对 A*算法估值函数的一种设想。 看起来,我们只要找到一个好的方法,把一个个围棋局面量化成适当的值,再根据这些值进行 A*搜索,就可以找到相当不错的走法。唯一的问题是:存在可行的量化方法吗?
人工智能―汇集和整理大量word文档,专业文献,应用文书,考试资料,教学教材,办公文档,教程攻略,文档搜索下载下载,拥有海量中文文档库,关注高价值的实用信息,我们一直在努力,争取提供更多下载资源。

我要回帖

更多关于 傲盾加速器官网 的文章

 

随机推荐