说我有两种颜色的棒棒糖,每种颜色有五种棒棒糖(总共十种),我想在朋友中分发这些颜色。我们每个人都提交一些排名偏好:
Ben:1 - 橙色,2 - 绿色,3 - 红色
乔:1 - 绿色,2 - 蓝色,3 - 红色 蒂姆:1 - 橙色,2 - 红色,3 - 蓝色 等我能用什么软件来“模仿”我们必须做出的全部牺牲? (例如,让所有人尽可能接近他们的第一选择)
答案 0 :(得分:0)
这个问题缺乏一个好的模型。客观/损失的不同表述将导致完全不同的行为/解决方案。
这是一种混合整数编程方法(因为你的问题已经是np-hard):
import math
import numpy as np
from cvxpy import *
# PROBLEM
# -------
# colors = orange, green, red, blue
n_colors = 4
n_lollies_per_color = 5
n_lollies = n_colors * n_lollies_per_color
prefs = np.asarray([[0, 1, 2, 3],
[1, 3, 2, 0],
[0, 2, 3, 1]])
n_persons = prefs.shape[0]
n_lollies_per_person = n_lollies / n_persons
# SOLVER
# ------
per_person_per_lolly_satisfaction_vector = np.asarray([[n_colors -1 - np.where(prefs[p, :] == c)[0]
for c in range(n_colors)]
for p in range(n_persons)]).reshape((3,4))
# Decision-vars
X = Int(n_persons, n_colors)
# Constraints
constraints = []
# non-zero lollies
constraints.append(X >= 0)
# exactly n_lollies_per_color are distributed
for c in range(n_colors):
constraints.append(sum_entries(X[:,c]) == n_lollies_per_color)
# Objective
objective = Maximize(sum_entries(mul_elemwise(np.square(per_person_per_lolly_satisfaction_vector), X)))
problem = Problem(objective, constraints)
problem.solve(verbose=False)
print(problem.value)
print(np.round(X.value)) # Rows -> persons; Columns -> amount of lollies they got
129.9999999837688
[[ 1. 0. 0. 0.]
[ 0. 5. 0. 5.]
[ 4. 0. 5. 0.]]
只需添加这些约束:
# lower and upper bound on lollies received -> at most 1 lolly less than everyone else
for p in range(n_persons):
constraints.append(sum_entries(X[p, :]) >= math.floor(n_lollies_per_person))
constraints.append(sum_entries(X[p, :]) <= math.ceil(n_lollies_per_person))
119.99999984107899
[[ 5. 0. 0. 1.]
[-0. 5. 0. 2.]
[ 0. 0. 5. 2.]]