取球游戏

问题出自:

http://topic.csdn.net/u/20090518/21/8b96f19a-af92-4eb8-8021-2977c29f27d2.html#replyachor

http://topic.csdn.net/u/20090524/15/485d92e2-759e-496c-8725-fab7862ab5d2.html

但在这里对题目作了修改,增加了些难度。

--

r个红球和b个蓝球。
A,B轮流取球:A每次从箱子里随机取出一个球,B每次从箱子里取出一个蓝球。
当如下两种情况之一发生时A胜:
(1),最后一个取出的球是蓝球。
(2),剩余的红球比蓝球恰多两个。
否则B胜。
问:若给定r,b值及A,B谁先取,求A获胜的概率。

 

解:(matlab代码)

(一)递归解法:

function rs=g(r,b,guy)    
%计算“有r个红球,b个蓝球,guy先取”时A获胜的概率

if guy=='A'
    if r-2==b
        rs=1;
        return;
    end
    if r==0&&b==0
        rs=0;
        return;
    end
    if r==0&&b>=1
        rs=1;
        return;
    end
    if r>=1&&b==0
        rs=0;
        return;
    end
    if r>=1&&b>=1
        rs=g(r-1,b,'B').*r./(r+b)+g(r,b-1,'B').*b./(r+b);
        return;
    end
elseif guy=='B'
    if r-2==b
        rs=1;
        return;
    end
    if r==0&&b==0
        rs=0;
        return;
    end
    if r==0&&b>=1
        rs=1;
        return;
    end
    if r>=1&&b==0
        rs=0;
        return;
    end
    if b>=1&&r>=1
        rs=g(r, b-1,'A');
        return;
    end
end
end

例:

>> g(3,10,'A')

ans =

    0.4386

 

(二)动态规划解法:

将A,B轮流取球的过程看作离散随机过程(马尔可夫链)。

function rsp=f(r,b,guy)
%计算“有r个红球,b个蓝球,guy先取”时A获胜的概率

%最初状态空间p只有(i_(r),j_(b))格有概率值(为1),其余格均为0
p(i_(r),j_(b))=1;
rsp=0;
%开始进行状态转移
count=0;%计数取球已进行了多少次
while(1)
    tp=p;%以tp接管当前状态空间,腾出p来存放下一状态空间
    p=zeros(size(p));%将p清零
    %用tp去渲染p
    %遍历tp的每一个格
    for i=0:size(tp,1)-1
        for j=0:size(tp,2)-1
            %tp(i_(i),j_(j))将散射到p的若干个格上对其概率值作出贡献
            if guy=='A'%如果是A取球
                %tp(i_(i),j_(j))转移到p(i_(i-1),j_(j))和p(i_(i),j_(j-1)),为其概率值作出贡献
                %要注意渲染不要出格
                if i>=1&&i+j~=0;p(i_(i-1),j_(j))=p(i_(i-1),j_(j))+i./(i+j)*tp(i_(i),j_(j));end
                if j>=1&&i+j~=0;p(i_(i),j_(j-1))=p(i_(i),j_(j-1))+j./(i+j)*tp(i_(i),j_(j));end
            elseif guy=='B'%如果是B取球
                %tp(i_(i),j_(j))转移到p(i_(i),j_(j-1)),为其概率值作出贡献
                %要注意渲染不要出格
                if j>=1;p(i_(i),j_(j-1))=p(i_(i),j_(j-1))+tp(i_(i),j_(j));end
            end
        end
    end%p渲染完毕
    %将终止点概率计入并清零
    for i=0:size(p,1)-1
        for j=0:size(p,2)-1
           if i-2==j||(i==0&&j~=0)
               rsp=rsp+p(i_(i),j_(j));
               p(i_(i),j_(j))=0;%注意,终止状态每次都要清零
           end
        end
    end
    %换人
    if guy=='A'
        guy='B';
    else
        guy='A';
    end
    count=count+1;
    if count==r+b%在r+b次以内游戏必定已结束,故此时rsp必已经将所有可能的p(i_(0),j_(1))全部计入。终止。
        break;
    end
end
end

其中用到两个辅助函数,作用是将下标从1开始(matlab特性)变换为下标从0开始:

function newivalu=i_(ivalu)
newivalu=ivalu+1;
end
function newivalu=j_(ivalu)
newivalu=ivalu+1;
end

例:

>> f(3,10,'A')


ans =

    0.4386

 

(三),模拟解法:

function rs=f(Nr,Nb,firstguy,rep)
%模拟计算“有Nr个红球,Nb个蓝球,firstguy先取”时A获胜的概率,rep为实验次数
%如果输入为特殊情况,则直接得出结果,无需模拟
if Nr==0&&Nb==0
    rs=0;
    return;
end
if Nr-2==Nb
    rs=1;
    return;
end
if Nr==0&&Nb>0
    rs=1;
    return;
end
if Nr>0&&Nb==0&&~(Nr-2==Nb)
    rs=0;
    return;
end
%进行模拟
NAwin=0;%A胜次数
for i=1:rep%重复游戏rep次
    %游戏初始状态
    r=Nr;
    b=Nb;
    guy=firstguy;
    %A,B轮流取球
    while(1)
        if guy=='A'%轮到A取球
            k=floor(rand()*(r+b))+1;%随机数k用于选球
            if k>r%取蓝球
                b=b-1;
                if r==0&&b==0%如果A刚取的这个蓝球为最后一个球,游戏结束,A胜。
                    NAwin=NAwin+1;
                    break;
                end
            else%取红球
                r=r-1;
                if r==0&&b==0%如果A刚取的这个红球为最后一个球,游戏结束,B胜。
                    break;
                end
            end
            if r-2==b%如果满足条件(2),游戏结束,A胜。
                NAwin=NAwin+1;
                break;
            end
            guy='B';%换人
        elseif guy=='B'%轮到B取球
            b=b-1;%B只取蓝球
            if r==0&&b==0%如果B刚取的这个蓝球为最后一个球,游戏结束,A胜。
                NAwin=NAwin+1;
                break;
            end
            if r-2==b%如果满足条件(2),游戏结束,A胜。
                NAwin=NAwin+1;
                break;
            end
            guy='A';%换人
        end
    end
end
rs=NAwin./rep;%得到概率
end

 

例:

>> f(3,10,'A',100000)

ans =

    0.4383

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值