Python Pyomo: ошибка домена переменных в Pyomo

Я хочу решить задачу целочисленного программирования, в которой переменные решения ограничены определенным набором.

Например, переменные решения xi должны быть выбраны в [2,5,7,10].

Для тестирования я написал код Python с помощью Pyomo следующим образом:

from pyomo.environ import *
model = AbstractModel()
model.X = Set(initialize=[2, 5, 7, 10])
model.x = Var(within=model.X)
model.obj = Objective(expr=model.x+1)
m = model.create_instance()
opt = SolverFactory("glpk")
results = opt.solve(m)

Когда эти коды выполняются, я получил сообщение об ошибке: «TypeError: недопустимый тип домена для переменной с именем 'x'. Переменная не является непрерывной, целочисленной или двоичной»

Вот мои вопросы:

  • В чем причина этой ошибки?
  • Как с этим бороться?
  • Есть ли другие инструменты оптимизации, которые могут справиться с подобными проблемами?

Спасибо за помощь!


person Pang    schedule 28.10.2016    source источник
comment
Используйте Var (внутри = целые числа, границы = (1,3))   -  person Gabe Hackebeil    schedule 28.10.2016
comment
Я не описал проблему четко. Исправили это. Я прочитал ответы, которые вы ответили на другие вопросы. Кажется, что вы автор Pyomo? Спасибо за вашу помощь. Как я могу решить эту проблему? @GabeHackebeil   -  person Pang    schedule 28.10.2016


Ответы (1)


  • В чем причина этой ошибки?

    Как указывает ошибка, линейные решатели смешанного целого числа, такие как GLPK, могут обрабатывать только непрерывные, двоичные и общие целочисленные переменные. Когда вы указываете

    model.X = Set(initialize=[2, 5, 7, 10])
    model.x = Var(within=model.X) 
    

    Вы пытаетесь создать дискретную категориальную переменную, которую Pyomo может представлять внутренне, но у нее нет способа передать ее конкретному решателю.

  • Как с этим бороться?

    Существует стандартная переформулировка с использованием набора двоичных переменных:

    model.X = Set(initialize=[2, 5, 7, 10])
    model.select_x = Var(model.X, domain=Binary)
    model.x = Var()
    def pick_one(m):
        return 1 == sum(m.selext_x[i] for i in m.X)
    model.pick_one = Constraint(rule=pick_one)
    def set_x(m):
        return m.x == sum(i*m.select_x[i] for i in m.X)
    model.set_x = Constraint(rule=set_x)
    
  • Есть ли другие инструменты оптимизации, которые могут справиться с подобными проблемами?

    Хотя есть некоторые решатели, которые могут обрабатывать дискретные категориальные переменные, вам, вероятно, лучше использовать приведенную выше формулировку.

person jsiirola    schedule 28.10.2016
comment
Большое спасибо. Вдохновленный вашим ответом на вопрос 2, я переформулировал исходную задачу, добавив ограничение SOS1 к переменной x и решив его с помощью инструмента оптимизации Gurobi. - person Pang; 29.10.2016