2016-10-28 5 views
0

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

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

Для тестирования я написал код питона, используя 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: Invalid тип домена для переменной с именем„х“ . Переменный не является непрерывным, целым числом, или двоичным»

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

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

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

+0

Использование Var (в пределах = Целые числа, границы = (1,3)) –

+0

Я не описал проблему четко. Исправьте это. Я прочитал ответы, на которые вы ответили на другие вопросы. Кажется, что вы автор Пиомо? Очень благодарен вам за помощь. Как я могу справиться с этой проблемой? @GabeHackebeil – Pang

ответ

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

    Как показывает ошибка, смешанные целые линейные решатели, такие как 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) 
    
  • Есть ли какие-либо другие инструменты оптимизации, которые могут обрабатывать этот тип проблем?

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

+0

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