- матрица решений NxM с двоичными переменными
< li>матрица весов T размером NxM - основным критерием является максимизация суммы выбранных весов (те, которым соответствует 1 место в матрице решений)
- при условии жесткого ограничения: каждая строка в матрице решений должна содержать ровно S записей, равных 1
Я определил модель в pyomo и попробовал решить ее с помощью разных решателей (couenne, ipopt, bonmin). Однако независимо от того, какой штрафной коэффициент я выбираю, результирующая матрица решений всегда одна и та же (как и в случае отсутствия штрафа). Целевое значение уменьшается при увеличении штрафного коэффициента, но решение не меняется.
(Я проверил, что лучшее решение действительно существует с помощью метаэвристики.)
Код: Выделить всё
def get_penalty(m):
total = 0
for day in range(M):
for i in range(N):
penalty = 0
for j in range(i + 1, N):
penalty += overlap_matrix[i, j] * m.x[i, day]
total += penalty
return total
def get_reward(m):
total = 0
for day in range(M):
reward = 0
for i in range(N):
reward += T[i, day] * m.x[i, day]
for j in range(i + 1, N):
reward -= overlap_matrix[i, j] * m.x[j, day]
total += reward
return total
def objective(m):
# main objective
total = sum(T[i, j] * m.x[i, j] for i in range(N) for j in range(M))
# secondary: reward or penalty
penalty = reward = 0
penalty = get_penalty(m) * penalty_w
reward = get_reward(m) * reward_w
obj = total
obj += (-penalty + reward)
return obj
model = pyo.ConcreteModel()
model.x = pyo.Var(range(N), range(M), within=pyo.Binary)
model.obj = pyo.Objective(rule = objective, sense = pyo.maximize)
# Constraint
def limit_constraint(model, i):
return sum(model.x[i, j] for j in range(M)) == S
model.limit = pyo.Constraint(range(N), rule=limit_constraint)
solver = pyo.SolverFactory('couenne')
result = solver.solve(model, tee = True)
Подробнее здесь: https://stackoverflow.com/questions/793 ... e-solution
Мобильная версия