我有像
这样的对象const data = {
'Washington' : { ElectoralVotes : 12, RChance: 0 },
'Oregon': { ElectoralVotes: 7, RChance: 15 },
.
.
.
'Hawaii' : { ElectoralVotes: 4, RChance : 35 }
}
其中键值对如
'Washington' : { ElectoralVotes : 12, RChance: 0 }
意味着“华盛顿州有12张选举人票,而共和党候选人有0%的机会赢得该州。”从此我试图估计共和党获胜的机会。
我意识到有 2 ^ 51 状态的子集合,所以正确的方法,包括对普通计算机的太多计算,将是
total = 0;
For each array A in [ [], ['Washington'], ['Oreogon'], ... , ['Washington', 'Oregon', ..., 'Hawaii'] ]
If (sum of electoral votes of states in A) >= 270
p = multiply together chances of winning states in A
total += p;
然后total
是共和党获胜的机会。但是因为我不能这样做,所以我说我改为在 2 ^ 10 状态集合的随机集合上运行该程序。然后我会将total
乘以 2 ^ 41 来得到真值的近似值吗?
答案 0 :(得分:2)
您在问题中描述的解决方案的问题是需要考虑大量的指数状态子集。即使状态集相对较小(例如:50),这也会使解决方案变得不可行。但是,您可以使用时间O(NS)中的动态编程来解决此问题,其中N是选举投票的总数,S是州的数量。
从大小为N + 1的数组P开始。数组中的条目i将代表共和党人获得选举投票的概率。它的大小为N + 1,因为它们可以获得的投票数为0到N(包括0和N)。
启动数组初始化为0,除了第一个条目1.这描述了在计算中没有包含任何状态之后的概率:如果还没有包含任何状态,他们肯定会获得0张选票。
现在,对于一个新的州(华盛顿,比如说),我们可以更新数组以包含该状态。假设有k个选举人票,我们的候选人在那里获胜的概率是p。
让P2
成为新的概率数组。如果我< k,然后:
P2[i] = P[i] * (p - 1)
如果我> = k,那么:
P2[i] = P[i] * (p - 1) + P[i-k] * p
也就是说,候选人现在拥有选票的可能性是他们已经获得选票并且他们失去了华盛顿的可能性,以及他们以前获得ik选票的可能性(如果可能的话)并且他们赢得了华盛顿。
一旦我们包括了这样的所有州,他们赢得选举的概率就是他们在i投票的概率的总和,其中i> N / 2。
在伪代码中:
P[] = {1, 0, 0, ..., 0} // size N+1
for state of all_states {
P2 = new array of size N+1.
for i = 0, 1 ... N {
let p = state.RChance / 100.0
let k = state.ElectoralVotes
P2[i] = P[i] * (1 - p)
if i >= k {
P2[i] += P[i - k] * p
}
}
P = P2
}
win_probability = sum(P[i] for i = floor(N/2)+1 ... N)
原则上,可以通过更新P2
来避免P
数组,但是编码有点棘手(因为你必须向后迭代以避免更改以后需要读取的条目)。原则上,阵列P的大小可以是floor(N/2) + 2
,最后一个元素直接代表胜利概率。但同样,这使代码变得更加狡猾。