博弈论最简单例子TacTicToe

博弈论是人工智能中的一个分支。顾名思义就是下棋的算法。当然引申出来的应用可能不止用来下棋,也可以用来做游戏或者模拟战争策略等。

博弈的基本算法也是模拟人的思维,比如当自己下子时遍历所有可能寻求最有利步骤,但是一种走法如果不能一步取胜则要考虑对方可能采取的对自己最不利的走法,如果对方不能取胜,然后再进一步考虑在对方的走法下自己最佳的应对是什么,如此递归下去,找到每条路径的胜算,采取最优策略。

伪代码可以这样:

function find_best(P)
{
var bestSolution=WORST;
for every possible step S after P:
if ( willWin(s))
return S;
else if(willEnd(S))
if( S >= bestSolution) bestSolution = S;
else
var W= find_worse(S);
if( W >= bestSolution ) bestSolution =W;

return bestSolution;
}

find_worse函数应该有类似的逻辑,唯一不同在于find_worse判断逻辑反过来,找出对对方最有利的解决办法。

上边描述的只是最简单的算法,实际上,在稍微复杂的棋类游戏中,这种算法都无法工作。原因是上述算法会递归遍历所有的可能性,在很多棋类游戏中,这在时间上无法支持的 – 太耗时。如果预先计算好所有可能又太耗存储空间。这时往往需要递归到特定深度即结束,并且由于往往不能搜索到棋局的最终胜或者负的结局,必须对任一状态有一个评估函数来评估分数。为了进一步优化,可能要对遍历的路径做些裁剪。比如,五子棋中不去考虑那些离已经存在的子太远的解决方案等等。

既然我们今天只研究最简单的情况,那么上边的算法还是可以解决问题的。我们就以井字棋为例,完全可以遍历所有情况,直接上递归算法都不会引起栈溢出 – 总共只有9步深度:).

代码在这里:http://www.luoxq.com/tic.html

时间: 2024-09-29 04:38:02

博弈论最简单例子TacTicToe的相关文章

从一个简单例子来理解js引用类型指针的工作方式

? 1 2 3 4 5 6 7 <script> var a = {n:1};  var b = a;   a.x = a = {n:2};  console.log(a.x);// --> undefined  console.log(b.x);// --> [object Object]  </script> 上面的例子看似简单,但结果并不好了解,很容易把人们给想绕了--"a.x不是指向对象a了么?为啥log(a.x)是undefined?".&

Hadoop RPC简单例子

jdk中已经提供了一个RPC框架-RMI,但是该PRC框架过于重量级并且可控之处比较少,所以Hadoop RPC实现了自定义的PRC框架. 同其他RPC框架一样,Hadoop RPC分为四个部分: (1)序列化层:Clent与Server端通信传递的信息采用了Hadoop里提供的序列化类或自定义的Writable类型: (2)函数调用层:Hadoop RPC通过动态代理以及java反射实现函数调用: (3)网络传输层:Hadoop RPC采用了基于TCP/IP的socket机制: (4)服务器端

extern外部方法使用C#简单例子

外部方法使用C#简单例子 1.增加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", SetLastError = true)] 3.声明外部方法public static extern int GetCurrentDirectory(int a, StringBuilder b); 4.对外部方法操作  GetCurrentDirectory(300, pathstring); using

事件简单例子

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.InteropServices; 6 7 namespace EventTest 8 { 9 /// <summary> 10 /// 事件订阅者类 11 /// </summary> 12 class Program 13 { 14 static v

spring mvc(注解)上传文件的简单例子

spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方1.form的enctype=”multipart/form-data” 这个是上传文件必须的2.applicationContext.xml中 <bean id=”multipartResolver” class=”org.springframework.web.multipart.commons.CommonsMultipartResolver”/> 关于文件上传的配置不能少 大家可以看具体代码如下: web.xml &

自定义隐式转换和显式转换c#简单例子

自定义隐式转换和显式转换c#简单例子 (出自朱朱家园http://blog.csdn.net/zhgl7688) 例子:对用户user中,用户名first name和last name进行转换成合成一个限定长度为10个字符新name. 自定义隐式转换: namespace transduction { public partial class transductionForm : Form { public transductionForm() { InitializeComponent();

使用fastjson转换json的简单例子

pom添加依赖: <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.41</version> </dependency> 代码: package JsonTest.JsonTest; import java.util.ArrayList; import java.util.Hash

最简单例子图解JVM内存分配和回收

一.简介 JVM采用分代垃圾回收.在JVM的内存空间中把堆空间分为年老代和年轻代.将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象.年轻代中又被分为Eden区(圣经中的伊甸园).和两个Survivor区.新的对象分配是首先放在Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次收集仍然存活的,就会被转移到年老区. 简单讲,就是生命期短的对象放在一起,将少数生命期长的对象放在一起,分别采用不同的回收

BIP_Case_以RDF为数据源以RTF为模板的简单例子

一. 汇总    1. 建立rdf报表    2. 开发rtf模板    3. 建立可执行程式    4. 建立并发程式    5. 注册data defination    6. 注册template    7. 运行程式    8. 开发程式中间,需将输出模式修改为xml,产生xml文件,以做rtf开发准备原始数据 二.分步解析1. 建立rdf报表2. 开发rtf模板3. 建立可执行程式4. 建立并发程式5. 注册data defination6. 注册template7. 运行程式8. 开