现在的位置: 首页 > 综合 > 正文

取球游戏

2013年09月17日 ⁄ 综合 ⁄ 共 3641字 ⁄ 字号 评论关闭

问题出自:

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

抱歉!评论已关闭.