Я решаю проблему оптимального потока мощности постоянного тока и пытаюсь найти наиболее эффективный способ повторения ограничения в Pyomo.
Ниже представлена структура данных, где i и k — узлы, соединенные через ответвление, а X — реактивное сопротивление, свойство ответвления.
Ограничение, с которым у меня возникают проблемы, заключается в следующем:
Там, где символы «дельта» и «р» являются переменными в ограничении, каждый узел имеет единственное значение дельты и р. Что в основном делает это ограничение, так это то, что оно гарантирует, что все мощности, поступающие в узел i от всех подключенных узлов k, равны существующему значению мощности в том же узле.
Вот пример для i=1 и i=2, итераций ограничения.
Поэтому я пытаюсь найти наиболее эффективный способ указать это ограничение в pyomo, где вместо нескольких итераций ограничений, написанных следующим образом:
def P1_rule(modelo):
return modelo.p[0]-L[0]== ((modelo.d[0]-modelo.d[1])/0.1)+((modelo.d[0]-modelo.d[2])/0.1)
model.P1 = Constraint(rule=P1_rule)
def P2_rule(modelo):
return modelo.p[1]-L[1]==((modelo.d[1]-modelo.d[0])/0.1)+((modelo.d[1]-modelo.d[2])/0.1)
model.P2 = Constraint(rule=P2_rule)
def P3_rule(modelo):
return modelo.p[2]-L[2] ==((modelo.d[2]-modelo.d[0])/0.1)+((modelo.d[2]-modelo.d[1])/0.1)
model.P3 = Constraint(rule=P3_rule)
Мне нужна одна такая строка, чтобы ее можно было легко обобщить в огромной сети:
def P3_rule(modelo):
return modelo.p[i] ==((modelo.d[i]-modelo.d[k])/X[k])
model.P3 = Constraint(rule=P3_rule)
Я придумал способ, который включает реструктуризацию данных и создание новых массивов индексов и т. д. Я хотел бы посмотреть, могу ли я применить ограничение, используя данные, сохраняющие ту же структуру и более напрямую.
Итак, я понял, как это сделать. Лучший способ, о котором я не знал, что это возможно, - это сделать оператор if внутри суммирования, поэтому в основном сделайте полную условную итерацию внутри суммирования. В приведенном ниже коде G — это список узлов, а «От» и «Кому» — столбцы номеров ветвей в таблице данных FullBranch.
def Try_rule(mod,g):
return mod.p[g] - L[g] == sum((mod.d[i-1]-mod.d[k-1])/FullBranch.loc[x,"X"] for x,(i,k) in enumerate(zip(FullBranch["From"], FullBranch["To"])) if i == g+1)
model.Try = Constraint(G,rule=Try_rule)
@EArwa, это было давно, я думаю, что определил наборы со списками, начинающимися с 0. тогда как ключи словаря данных филиала начинались с 1. Вот почему другие переменные, в которых есть i, индексируются с [i-1 ]
Выглядит хорошо. Зачем вы добавляете условие '''if i==g+1'''?