Распределить нагрузку на разные переменные равной стоимости в GLPK

#python #glpk

#python #glpk

Вопрос:

Возможно ли в GLPK распределить решение по нескольким переменным равной стоимости?

Давайте предположим, что у меня есть этот фрагмент кода в myprog:

 from pymprog import *

begin()

loads = var('loads', 3)
load_cost = par('load_cost', [10, 10, 10])

sum (loads[i] for i in range(len(loads))) >= 200

for i in range(len(loads)) :
   loads[i] <= 100

minimize (sum (load_cost[i] * loads[i] for i in range(len(loads))))

solve()
end()
  

Можно ли попросить решатель вернуть 66, 66, 66 для трех загрузок вместо 100, 100, 0?

Комментарии:

1. Вы думали о добавлении штрафного термина к вашей целевой функции, который наказывает за неравномерное распределение нагрузок? Если наличие линейной программы не является обязательным требованием, штраф по норме L2 для ваших нагрузок может выполнить эту работу. Кстати, ваш код приводит к синтаксической ошибке из-за отсутствия круглых скобок в строке, определяющей целевую функцию минимизации.

2. спасибо за исправление опечатки. Я использую библиотеку pymprog как библиотеку линейного программирования. Есть ли способ использовать это по-другому? Знаете ли вы другие библиотеки python для задач оптимизации?

Ответ №1:

Следующий фрагмент кода решает вашу проблему с использованием пакета оптимизации gekko. Это приводит к желаемому решению «66, 66, 66»:

 from gekko import GEKKO    
import numpy as np

#Initialize Model
m = GEKKO()

#initialize variables
x1,x2,x3 = [m.Var() for i in range(3)]
c1,c2,c3 = [m.Param(value=10) for i in range(3)]

#initial values
x1.value = 1
x2.value = 1
x3.value = 1


# lower bounds
x1.lower = 0
x2.lower = 0
x3.lower = 0


# upper bounds
x1.upper = 100
x2.upper = 100
x3.upper = 100


#Equations
m.Equation(x1 x2 x3>=200)

#Objective
m.Obj(x1*c1 x2*c2 x3*c3)

#Set global options
m.options.IMODE = 3 #steady state optimization

#Solve simulation
m.solve()

#Results
print('')
print('Results')
print('x1: '   str(x1.value))
print('x2: '   str(x2.value))
print('x3: '   str(x3.value))
  

Однако, если вы выберете разные начальные значения, решатель может найти другие решения с неравномерно распределенными нагрузками. Чтобы принудительно распределить нагрузку по нагрузкам, вам следует рассмотреть возможность изменения вашей целевой функции путем добавления термина наказания:

 m.Obj(x1*c1 x2*c2 x3*c3 x1*x1 x2*x2 x3*x3)
  

С помощью этой целевой функции результат всегда будет желаемым, независимо от того, какие начальные значения вы используете.

Комментарии:

1. Спасибо BGraf. Насколько стабилен GEKKO? Есть ли какие-либо отчеты о его производительности в других библиотеках оптимизации?

2. У меня не так много опыта использования gekko. Это просто самая простая библиотека, которая поддерживает квадратичные цели. pymprog предназначен только для линейных целей, насколько я знаю. Таким образом, он не поддерживает дополнительный штрафной срок.