方法
这是一个简单的整数编程方法,在 python 中使用cvxpy实现。
代码
import numpy as np
from cvxpy import *
""" INPUT """
N_ATTENDEES = 6
N_ROLES = 5
ATTENDEE_CAN_TAKE_MULTIPLE_ROLES = False # Modelling-decision
A_ROLES = np.array([[1,1,0,0,0],
[0,0,0,0,1],
[0,1,0,0,0],
[1,1,0,0,0],
[1,0,0,0,0],
[0,1,1,1,0]], dtype=bool)
W_ROLES = np.array([[0,0,0,1,0],
[0,0,1,1,0],
[1,0,0,1,1],
[0,0,0,0,0],
[0,0,1,0,1],
[0,0,0,0,1]], dtype=bool)
U_ROLES = np.ones((N_ATTENDEES, N_ROLES), dtype=bool) - A_ROLES - W_ROLES
""" Variables """
X = Bool(N_ATTENDEES, N_ROLES) # 1 -> attendee takes role
""" Constraints """
constraints = []
# (1) All roles assigned to exactly one attendee
for r in range(N_ROLES):
constraints.append(sum_entries(X[:, r]) == 1)
# (2) Forbidden roles
constraints.append(X <= (1-U_ROLES))
# (3) optional: max one role per attendee
if not ATTENDEE_CAN_TAKE_MULTIPLE_ROLES:
for a in range(N_ATTENDEES):
constraints.append(sum_entries(X[a, :]) <= 1)
""" Objective """
objective = Maximize(sum_entries(mul_elemwise(A_ROLES, X)))
""" Solve """
problem = Problem(objective, constraints)
problem.solve()
""" Output """
print(problem.status, problem.value)
print('assignments: \n' + str(np.array(np.round(X.value), dtype=int))) # pretty-printing of ASSIGNMENTS
print('a-roles taken: \n' + str(np.array(np.round(mul_elemwise(A_ROLES, X).value), dtype=int))) # pretty-printing of hitted A-roles
输出
('optimal', 4.000000000087978)
assignments:
[[1 0 0 0 0]
[0 0 0 0 1]
[0 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]]
a-roles taken:
[[1 0 0 0 0]
[0 0 0 0 1]
[0 0 0 0 0]
[0 1 0 0 0]
[0 0 0 0 0]
[0 0 0 1 0]]
在坚持线性规划(在实践和理论中具有较低的计算复杂性)的同时实施一种方法,采用@user29970 提到的一些想法,尽管我对其中一些描述有点怀疑。
我也很懒,MIP 方法至少在数值稳定性方面更好。