Производительность создания ограничений Pyomo

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

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

def flows(model, et, t):
return pyo.quicksum(model.in_flow[:, et, t], 
                    linear=True,
                    start=pyo.quicksum(model.out_flow[:, et, t], 
                                       linear=True)
                    ) == 0

model.add_component("flows", 
                    pyo.Constraint(model.energy_type, 
                                   model.t, 
                                   rule=flows)
                   )

Однако это все еще занимает 65% времени на настройку моей модели.

Я разбил его на вложенный цикл for, чтобы посмотреть, кто тратит время:

for t in model.t:
    for et in model.energy_type:
        e = model.in_flow[:, et, t]
        f = model.out_flow[:, et, t]
        es = pyo.quicksum(e)
        fs = pyo.quicksum(f)

Это занимает примерно такое же время выполнения, и «все» оно потрачено на последние две строки. Объединение быстрых сумм и установка линейного флага дает некоторые незначительные улучшения, но ничего существенного. В общем коде PyPSA по-прежнему используется старый генератор выражений coopr3, поэтому он больше не работает . Я также не мог понять, как это будет использоваться.

Есть предложения, как улучшить производительность генерации моделей?


person Florian K.    schedule 09.09.2019    source источник


Ответы (1)


Оказывается, проблема была в ломтиках.

def flows(model, et, t):
    vars = [model.in_flow[obj, et, t] for obj in model.objects_index]
    vars.extend([model.out_flow[obj, et, t] for obj in model.objects_index])
    return pyo.quicksum(vars) == 0

Эта переработка правила ограничения ускорила создание моей модели примерно на 60%. Я нашел еще два места, где я сделал аналогичную переформулировку. Сейчас я снизился со 120 до 7 с до 7.

person Florian K.    schedule 09.09.2019
comment
Не могли бы вы взглянуть на stackoverflow.com / questions / 51269351 / есть ли способ улучшить скорость? - person janicebaratheon; 10.09.2019
comment
@janicebaratheon Я посмотрел, но я не думаю, что что-то можно сделать, кроме, возможно, создания выражения вручную, как в коде PyPSA сверху. - person Florian K.; 10.09.2019