在计算总统结果时,我的逻辑错误在哪里?

时间:2016-07-11 06:56:03

标签: javascript algorithm statistics precision statistics-bootstrap

让我解释一下我要做的事情。我有像

这样的数据
const dataByState = {
    'Washington' : { ElectoralVotes : 12, RChance: 54, DChance: 46 },
    'Oregon': { ElectoralVotes: 7, RChance: 51, DChance: 49 }, 
     .
     .
     .
    'Hawaii' : { ElectoralVotes: 4, RChance : 40, DChance: 60 }
}; 

其中一个上述键值对如

'Hawaii' : { ElectoralVotes: 4, RChance : 40, DChance: 60 }

意味着“在拥有4张选举人票的夏威夷州,共和党候选人获胜的几率为40%,民主党候选人获胜的几率为60%”。我最终要做的是计算每位候选人赢得大选的机会。在一个完美的世界中如何做到这一点

  1. 遍历所有2^51个状态组合
  2. 对于每个组合c,其组合选举投票大于或等于270,将其添加到国家/地区的集合C
  3. 对于共和党候选人,总结在C中赢得每个国家组合的可能性;称该值为r。这是他/她获胜的机会。民主党的机会是1 - r
  4. 但由于我无法完成所有2^51,我正在做的是选择一些N小于51并执行

    1. 查找状态<{1}}的随机2^N组合,其选举总票数总和大于或等于270;将此组合称为C
    2. 对于共和党候选人,总结在C中赢得每个国家组合的可能性;称该值为r r 乘以2^(51-N)。这大约是他/她获胜的机会。民主党的机会是1 - r
    3. 无论如何,这似乎并没有起作用,我想知道我的逻辑是否错误(我从3年前的大学以来没有统计数据)或者我是否遇到了四舍五入的错误。当我在每个州都有机会的时候,我获得了近100%的共和党胜利(即美国再次获胜),这是错误的,因为它应该计算到大约50/50。

      代码转储:https://jsfiddle.net/pqhnwek9/

1 个答案:

答案 0 :(得分:0)

共和党胜利的概率是

dispatch_async(anotherQueue, ^{
    [self doSomething:&error];
});

正如您所观察到的,计算整个总和是不可行的。因此,您选择某个子集probRepVict = 0 for(combination in combinations) { if(combination is republican victory) { probRepVict += proability of combination } } 来尝试估计此概率。

C

在最后一个陈述中,我们假设胜利的概率与子集的大小成线性关系。

我认为脚本中的几个地方出现了错误:

(1)当生成随机数时,您可能无法获得足够多的随机性。例如,如果有54个状态,那么您将超出安全整数范围。一些实现可能会给你更少的随机性位(它在Node中确实破坏了,它只给出了32位)。因此我建议添加一个函数

N = number of combination // 2^51
n = size of C
probRepVictEstimate = 0
for(combination in C) {
    if(combination is republican victory) {
        probRepVictEstimate += proability of combination
    }
}

probRepVictEstimate *= N/n

更换

function getRandom() {
    // Generate 32 random bits                                                  
    var s = Math.floor(Math.random()*Math.pow(2, 32)).toString(2)
    return new Array(32 - s.length + 1).join("0") + s
}

使用const rand = Math.floor(Math.random() * Math.pow(2,states.length)); ,并将const rand = getRandom() + getRandom();替换为

getCombo

(2)您需要计算共和党的胜负两者,以便能够估计概率。因此,您无法添加组合的补码(顺便说一句,const getCombo = (i) => { let combo = []; for(var j = 0; j < states.length; ++j) if(i[j] == "0") combo.push(states[j]); return combo; } 是按位运算,因此将操作数转换为32位整数,因此您的代码无法按预期工作)。因此,您的代码应简化为:

~

(3)您应该... if(!winningCombos.hasOwnProperty(rand)) { const stateCombo = getCombo(rand); if(hasSufficientVotes(stateCombo)) { winningCombos[rand] = stateCombo; ++wins; } ++count; } ... 缩放repubChanceSumN/nN = Math.pow(2, 51)。请注意,n = limit应远大于limit

通过这些修改,代码可以正确预测winningCombos.length概率。请参阅此修改后的fiddle。 让我们希望我们以更现实的概率获得更加乐观的未来前景。