蒙特卡洛法预测比赛冠军

本期是关于蒙特卡洛的第一讲,使用蒙特卡洛法预测比赛冠军。可以根据不同的赛制简单地更改代码,适用于不同类型比赛的模拟。另外需要注意的是,在写模拟代码时,默认的是还未划分对阵表,如果已知对阵情况,需要更改相应的代码,固定对阵模式。

本次代码所模拟的赛制为:参赛选手64位,分16个小组首先进行小组赛,每个小组决出一名获胜者进入淘汰赛;淘汰赛在相邻编号小组胜者之间展开,淘汰赛共四轮,分别决出8强,4强,2强,冠军。比赛结果只有输和赢,没有平局。如图1所示。
图1:比赛赛制

以下为全部源代码,注释非常详细,大家可以直接下载运行下。

% 使用蒙特卡洛方法预测比赛冠军
% 公众号【数学建模公会】,HCLO4原创
% 20190920

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%% 赛制 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 模拟赛制为:参赛选手64位,分16个小组首先进行小组赛,每个小组决出一名获胜者进入
% 淘汰赛;淘汰赛在相邻编号小组胜者之间展开,淘汰赛共四轮,分别决出8强,4强,2强,冠军。
% 比赛结果只有输和赢,没有平局


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  胜率矩阵  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 
% 64人对阵,通过历史比赛战绩,得到胜率矩阵winProb。
% 这里我们简单的随机产生一个胜率矩阵。

% 随机产生一个胜率矩阵
% winProb(i,j)表示第i个人和第j个人比赛i赢的概率 winProb(i,i)无意义
% winProb(i,j)=1-winProb(j,i)
winProb=rand(64,64); 
for i=1:63
    for j=i+1:64
        winProb(i,j)=1-winProb(j,i);
    end
end


% 模拟10000轮对阵,使用wintime记录每个选手在10000次模拟中夺冠的次数
wintime=zeros(1,64); %

for iter=1:10000  % 总共模拟10000轮对阵


    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  小组赛模拟  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % 本次模拟的前提假设是还未分小组,并且假设分组是完全随机的

    % 产生随机分组,每一列代表一个小组,每个小组4人,共16个小组
    group=reshape(randperm(64),4,16);

    groupwiner=zeros(1,16); % 记录小组赛胜者
    % 记录小组赛相互战绩,ifwin(j,k)=1表示j赢了k,ifwin(j,k)=-1表示j输了k
    ifwin=zeros(4); 
    
    for i=1:16
        
        % 从所有选手胜率矩阵winProb中提取小组赛选手胜率矩阵
        subwinProb=winProb(group(:,i),group(:,i));

        for j=1:3
            for k=j+1:4
                pjk=subwinProb(j,k); %选手j对选手k的胜率
                if rand<pjk %选手j胜利
                    ifwin(j,k)=1;
                    ifwin(k,j)=-1;
                end
            end
        end

        numwin=sum(ifwin==1,2); % 小组赛四个选手胜利场数

        winerind=find(numwin==max(numwin)); % 找到胜场最多的选手
        % 如果有多余一个最大胜场选手,随机选一个作为小组出线者
        temp=randperm(length(winerind));
        winerind=winerind(temp(1));
        groupwiner(i)=group(winerind,i);

    end




    %%%%%%%%%%%%%%%%%%%%%%%%%%  淘汰赛模拟  %%%%%%%%%%%%%%%%%%%%%%%%%%%


    %%%%%%%%%%% 第一轮淘汰赛 1组对2组,3组对4组,依次类推  %%%%%%%%%%%%%
    secondwinner=zeros(1,8);
    for i=1:8
        player=groupwiner(i*2-1:i*2);  %1组对2组,3组对4组,依次类推
        %prob表示player1对player2的胜率
        prob=winProb(player(1),player(2));
        if rand<prob
            secondwinner(i)=player(1);
        else
            secondwinner(i)=player(2);
        end
    end


    %%%%%%%%%%%%%%%%%%%%%%% 第二轮淘汰赛 %%%%%%%%%%%%%%%%%%%%%
    thirdwinner=zeros(1,4);
    for i=1:4
        player=secondwinner(i*2-1:i*2); 
        % player1对player2的胜率
        prob=winProb(player(1),player(2));
        if rand<prob
            thirdwinner(i)=player(1);
        else
            thirdwinner(i)=player(2);
        end
    end


    %%%%%%%%%%%%%%%%%%%%%%% 第三轮淘汰赛 %%%%%%%%%%%%%%%%%%%%%
    fourthwinder=zeros(1,2);
    for i=1:2
        player=thirdwinner(i*2-1:i*2); 
        % player1对player2的胜率
        prob=winProb(player(1),player(2));
        if rand<prob
            fourthwinder(i)=player(1);
        else
            fourthwinder(i)=player(2);
        end
    end


    %%%%%%%%%%%%%%%%%%%%%%%  决胜局  %%%%%%%%%%%%%%%%%%%%%%
    player=fourthwinder; 
    % player1对player2的胜率
    prob=winProb(player(1),player(1));
    if rand<prob
        winder=player(1);
    else
        winder=player(2);
    end

    % 本轮模拟的胜者胜次加1
    wintime(winder)=wintime(winder)+1;

 
end


prob_win=wintime/sum(wintime);  % 最终的每个人的夺冠概率

disp('每个选手的夺冠概率为')
disp(prob_win)

欢迎关注公众号,获取更多数学建模相关内容:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值