下给出一种算法,针对两人有限零和博弈——其实这种问题本质上是有一般性方程解法的,这里不做赘述——从另一个角度来看,蒙特卡洛解法似乎是将双方的同时博弈转化为一个一前一后的迭代过程。
下看一个田忌赛马的问题
田忌赛马是一个一般性 的 没有鞍点 的 两人有限零和博弈。
赢得矩阵如下:
下面给出matlab代码:
可以自己输入迭代的次数试一下
Win=[3 1 1 1 1 -1;
1 3 1 1 -1 1;
1 -1 3 1 1 1;
-1 1 1 3 1 1;
1 1 -1 1 3 1;
1 1 1 -1 1 3]
indexNext=randi([1,6]);%首先任取一个值初始化田忌的策略
suanzi=-1;
k=input('需要计算的次数为:');
n=2*k;
result=[zeros(2,7);
indexNext Win(indexNext,:);zeros(n-1,7)];
%下面进行循环,i中每次生成17个元素的一行
for i=3:n+2
if suanzi==-1
[Y,I] = sort(result(i,[2:7]),2,"ascend");
if Y(1) ~= Y(2)
indexNext=I(1,1);
elseif Y(1) == Y(2)
temp=Y(1);
a=length(find(Y==temp));
indexNext=I(randi([1,a]));
end
nextrow=[indexNext (Win(:,indexNext))'+result(i-1,[2:7])];
result(i+1,:)=nextrow;
else
[Y,I] = sort(result(i,[2:7])',1,"descend");
if Y(1) ~= Y(2)
indexNext=I(1,1);
elseif Y(1) == Y(2)
temp=Y(1);
a=length(find(Y==temp));
indexNext=I(randi([1,a]));
end
nextrow=[indexNext (Win(indexNext,:))+result(i-1,[2:7])];
result(i+1,:)=nextrow;
end
suanzi=suanzi*(-1);
end
result=result([3:n+2],:);
resultFinal=zeros(k,14);
for l=1:k
resultFinal(l,:)=[result(2*l-1,:) result(2*l,:)];
end
下面我们计算最后的三行 v
rCumulate=[0 0 0 0 0 0];
cCumulate=[0 0 0 0 0 0];
%首先我们进行田忌的策略累计
vTj=zeros(k,1);
for i=1:k
for g=1:6
if resultFinal(i,1)==g
rCumulate(g)=rCumulate(g)+1;
end
end
tjM=Win.*(rCumulate/i)';
tj=min(sum(tjM,1));
vTj(i)=tj;
end
%首先我们进行齐王的策略累计
vQw=zeros(k,1);
for i=1:k
for g=1:6
if resultFinal(i,8)==g
cCumulate(g)=cCumulate(g)+1;
end
end
qwM=Win.*(cCumulate/i);
qw=max(sum(qwM,2));
vQw(i)=qw;
end
v=(vQw+vTj)/2;
output=[resultFinal vTj vQw v];
前三十次模拟结果如下
可以看到收敛结果符合我们的预期值。