描述:
在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定。陪审团是由法官从公众中挑选的。先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团。选m人的办法是:
控方和辩方会根据对候选人的喜欢程度,给所有候选人打分,分值从0到20。为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分和控方总 分的差的绝对值最小。如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案即可。最终选出的方案为陪审团方案。
#随机100个候选人,从中挑选10个陪审团
import random
p = [[]]
d = [[]]
for i in range(100): #在(20,110)范围内随机100个整数,将它们当作喜爱程度
p.append(random.randint(0,20))
for i in range(100): #在(20,110)范围内随机100个整数,将它们当作喜爱程度
d.append(random.randint(0,20))
print("prosecution:")
print(p)
print("defense:")
print(d)
result = []
f = [] #转移方程:f[i][j]=f[i-1][x]+d[k]+p[k];且x+p[k]-d[k]=j;{f[i-1][x]}满足条件的最大值
path = [] #记录i个人评审差为j,这种情况下的前一个人i-1是谁
n = 100
m = 10
if __name__ == '__main__':
for i in range(0, 30):
result.append([])
for i in range(0, 30):
f += [[]]
for j in range(0, 1000):
f[i] += [-1]
for i in range(0, 30):
path += [[]]
for j in range(0, 1000):
path[i] += [0]
minD = 20 * m #避免下标为负,所以推广到零以上
f[0][minD] = 0 #初始化条件
for j in range(0, m):
for k in range(0, minD*2 + 1):
if f[j][k] >= 0:
for i in range(1, n+1):
if (f[j][k]+p[i]+d[i]) > (f[j+1][k+p[i]-d[i]]):
temp1 = j
temp2 = k
while (temp1 > 0) and (path[temp1][temp2] != i):
temp2 = temp2 - p[path[temp1][temp2]] + d[path[temp1][temp2]]
temp1 = temp1 - 1
if temp1 == 0:
f[j + 1][k + p[i] - d[i]] = f[j][k] + p[i] + d[i]
path[j + 1][k + p[i] - d[i]] = i
i = minD
j = 0
k = 0
while (f[m][i + j] < 0) and (f[m][i - j] < 0):
j = j+1
if f[m][i + j] > f[m][i - j]:
k = i + j
else:
k = i - j
print("Best jury has value {} for prosecution and value {}for defence:".format((k - minD + f[m][k]) / 2, (minD - k + f[m][k]) / 2))
for i in range(1, m+1):
result[i] = path[m - i + 1][k]
a = result[i]
b = p[a] - d[a]
k = k - b
ans = []
for i in range(1, m+1):
if result[i] != []:
ans.append(result[i])
#print("{} ".format(result[i]))
ans = sorted(ans)
print(ans)