Добавление критериев к целевой функции не меняет решение.Python

Программы на Python
Ответить
Anonymous
 Добавление критериев к целевой функции не меняет решение.

Сообщение Anonymous »

У меня есть проблема MINLP, которую можно описать следующим образом:
  • матрица решений NxM с двоичными переменными
    < li>матрица весов T размером NxM
  • основным критерием является максимизация суммы выбранных весов (те, которым соответствует 1 место в матрице решений)
  • при условии жесткого ограничения: каждая строка в матрице решений должна содержать ровно S записей, равных 1
Вышеупомянутое решение легко решить; однако я хочу ввести штраф, который зависит от каждой пары единиц в каждом столбце, которая «перекрывается». Существует перекрытие_матрица[N][N], которая определяет значения штрафов для каждой пары, а общее значение штрафа (умноженное на вес штрафа) уменьшает общее целевое значение. Поскольку я не могу запросить переменные pyomo, я умножаю значение штрафа на переменную решения модели для всех пар.
Я определил модель в 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»