#python #pyomo
#python #pyomo
Вопрос:
Я использую библиотеку pyomo для решения задачи коммивояжера (TSP), но возникает ошибка. Основная часть модели заключается в следующем:
model.set_I = range(lendist, 1) # The set related to the distance matrix
model.set_J = range(nStops, 1) # nStop is the number of cities and set_J is the related set.
model.trips = Var(model.set_I, domain=NonNegativeReals, bounds=(0, 1)) # trips is the decision variable
def obj_expression(model): # Objective function
return sum(model.dist[i]*model.trips[i] for i in model.set_I)
model.OBJ = Objective(rule=obj_expression)
# Constraint 1:
def constraint_1(model):
return sum(model.trips[i] for i in model.set_I) == nStops
model.constraint_1 = Constraint(rule=constraint_1)
# Constraint 2:
def constraint_2(model, j):
return sum(model.trips[whichIdxs[i, j]] for i in model.set_I) == 2
model.constraint_2 = Constraint(model.set_J, rule=constraint_2)
Результирующая ошибка выглядит следующим образом:
ОШИБКА: не удалось создать компонент ‘constraint_1’ из data= None:
ValueError: Invalid constraint expression. The constraint expression resolved to a trivial Boolean (False) instead of a Pyomo object. Please modify your rule to return Constraint. Infeasible instead of False.
Ошибка значения: недопустимое выражение ограничения. Выражение ограничения преобразовано в тривиальное логическое значение (False) вместо объекта Pyomo. Пожалуйста, измените свое правило, чтобы возвращать ограничение. Неосуществимо вместо False.
Ошибка, вызванная для ограничения constraint_1
Ограничение 1 имеет только индекс i, и сумма находится над ним. Следовательно, после определения правила нет индекса. Проблема здесь? Фактически, аналогичная ситуация справедлива для целевой функции, но в этом нет ошибки.
Ответ №1:
Каково значение lendist
?
Похоже, что model.set_I
пусто (что произойдет, если lendist>=1
). Когда Python суммирует по пустому итерируемому, он возвращает целочисленную константу 0
. Предполагая, что у вас есть nStops != 0
, тогда выражение вычисляется Python в constraint_1
функции, в результате чего оно возвращается False
(а не объект выражения Pyomo). Поскольку False
это недопустимое выражение Pyomo (и тривиально неосуществимо), Pyomo выдает ошибку.
Помните, что когда вы передаете два аргумента в range()
функцию Python, аргументы указывают начальное и конечное значения: range(start, end)
возвращает только целые числа, начинающиеся с start
до, но не включая end
.