蒙特卡洛模拟以模拟选举

时间:2018-10-29 14:13:18

标签: java

上个星期左右,我一直被这个问题折磨着,似乎找不到解决办法。

我的问题是,在总统选举中,我有6名候选人的赔率,我必须使用蒙特卡洛模拟法来确定某些3名候选人以任何顺序在最后3名中完成的可能性。

我的第一种方法是用1000000 +票数运行x次模拟。问题是我从来没有发现这些候选人最后获得投票的任何情况,因为有这么多的票数并且随机数生成器位于java,我消除了运气的可能性,因此,排名与可能性保持不变。

有人告诉我做一个更好的方法是进行选举,然后如果随机数落入一个候选人的可能性中,我必须给他第一名,然后再以剩下的任何可能性我必须确定第二名,然后再确定第三名,依此类推。等等。我知道答案必须是0.7 ..有谁知道我该怎么做?非常感谢。

这是我到目前为止的代码,这没有给我我应该有的答案,但我似乎找不到错误。

import java.util.*;

公共课程Lab4 {

public static void main(String[] args) {

    Random rd = new Random();

    int numElections = 50000000;
    int count = 0;

    ArrayList<String> ar2 = new ArrayList<String>();

    for(int i = 1; i <= numElections; i++)
    {
        double mh = (double)25/26 / 1.0951899766899766;     
        double pc = (double)1/10 / 1.0951899766899766;
        double sg = (double)1/66 / 1.0951899766899766;
        double lnr = (double)1/80 / 1.0951899766899766;
        double jf = (double)1/250 / 1.0951899766899766;
        double gd = (double)1/500 / 1.0951899766899766;

        double sumOdds = (mh + pc + sg + lnr + jf + gd);

        for(int j = 1; j <= 6; j++)
        {
            double randomValue = rd.nextDouble() * sumOdds;

            if(randomValue > 0 && randomValue <= mh)
            {
                ar2.add("mh");
                sumOdds -= mh;
                mh = 0;
            }
            else if(randomValue > 0 && randomValue <=  mh + pc)
            {
                ar2.add("pc");
                sumOdds -= pc;
                pc = 0;
            }
            else if(randomValue > 0 && randomValue <= mh + pc + sg)
            {
                ar2.add("sg");
                sumOdds-= sg;
                sg = 0;
            }
            else if(randomValue > 0 && randomValue <= mh + pc + sg + lnr)
            {
                ar2.add("lnr");
                sumOdds-= lnr;
                lnr = 0;
            }
            else if(randomValue > 0 && randomValue <= mh + pc + sg + lnr + jf)
            {
                ar2.add("jf");
                sumOdds-= jf;
                jf = 0;
            }
            else if(randomValue > 0 && randomValue <= mh + pc + sg + lnr + jf + gd)
            {
                ar2.add("gd");
                sumOdds-= gd;
                gd = 0;
            }   
        }

        if(ar2.get(3)  == "pc"|| ar2.get(4) == "pc" || ar2.get(5) == "pc")
        {
            if(ar2.get(3)  == "gd"|| ar2.get(4) == "gd" || ar2.get(5) == "gd")
            {
                if(ar2.get(3)  == "sg"|| ar2.get(4) == "sg" || ar2.get(5) == "sg")
                {
                    count++;
                }
            }
        }
        ar2.clear();

    }   

    System.out.println((double)count/numElections);


}   

}

1 个答案:

答案 0 :(得分:0)

给定候选人的几率要么是总投票的百分比,要么是X:Y-像10:1。您可以通过Y / X = 0.1将后者转换为前者。

您的模拟想法很棒。问题是,您如何根据随机数生成器进行选择

假设我们有一系列候选人,每个候选人都有正常的获胜机会。百分比将除以100-因此80%= 0.8,赔率格式X:Y将如上所示进行转换。

我们知道,候选人机会列表的总和为1.0。

使用https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#nextFloat--,我们可以生成一个介于0和1.0之间的数字。

到目前为止,保持所有概率的连续总和,在列表中向上查找nextFloat命中的候选人。

类似这样的东西

Random random = new Random();
Candidate[] candidates = ...;


// do this for each vote
float total = 0.0f;
int index = 0;
float randomVote = random.nextFloat();
while (total<randomVote && index<candidates.length) {
   total += candidates[index].getProbability();
   if (total<randomVote) { 
       // only increment to the next candidate if this one didn't win the vote
       index++;
   }
}

// at this point, the index is the candidate who won the vote