Линпрог в scipy иногда неудобен, потому что:
Он всегда решает проблему минимизации, поэтому, если вы хотите максимизировать целевую функцию, вы должны сделать обходной путь , как в это решение , чтобы превратить его в задачу минимизации
уравнения, которые имеют> =, должны быть умножены на -1, чтобы стать <= </p>
Создаем вместе ограничения, такие как A_ub A_eq вместе, они разделяют матрицы, поэтому создайте и затем индивидуально
взгляните на документы , у них есть хороший пример как well
linprog реализует решатель для:
, поэтому, если вам нужно иметь форму уравнения A_lb x> = b_lb, вам нужно преобразовать его в форму (выражение) <= (значения), вы можете сделать это, умножив обе стороны на -1. Итак -A_lb x <= -b_lb </p>
ПЕРВЫЙ простое решение для решения вашей первоначальной проблемы
from scipy.optimize import linprog
import numpy as np
####defining the minimization problem
##### those are your inputs following scipy notation
a,b,c,d = 10.0,-3.0,10.0,4.666666666666666
c0, c1= a, b # this is your a and b 10x0 - 3x1 is the obj func to minimize
a_ub0, a_ub1= a, b # this is your a and b in "x0*a + b*x1"
b0_ub = 0 # this is your constraint in "x0*a + b*x1 >= 0"
a_eq0, a_eq1= 1, 1 # this is your "1" in "1*x0 + 1*y0"
b0_eq = 1 # this is your 1 constraint in "x0 + x1 = 1"
x0_bounds = (0, 1) # those are the bounds
x1_bounds = (0, 1)
C = [c0, c1] # you're minimizing so no need to multiply by -1 C
A_ub = [[-a_ub0, -a_ub1]] # but still need to invert the signal here
A_eq = [[a_eq0, a_eq1]]
b_ub = [b0_ub]
b_eq = [b0_eq]
res = linprog(C, A_ub=A_ub, b_ub=b_ub,
A_eq=A_eq, b_eq=b_eq,
bounds=[x0_bounds, x1_bounds])
minimization_objfunc_output = res['fun']
print(f'min value is {res["fun"]} with solutions x: {res["x"]}')
####defining your original problem
##### those are your inputs following scipy notation
a,b,c,d = 10.0,-3.0,10.0,4.666666666666666
c0, c1= c, d # this is your c and d
a_ub0, a_ub1= a, b # this is your a and b in "x0*a + b*x1"
b0_ub = 0 # this is your constraint in "x0*a + b*x1 >= 0"
a_eq0, a_eq1= 1, 1 # this is your "1" in "1*x0 + 1*y0"
b0_eq = 1 # this is your 1 constraint in "x0 + x1 = 1"
a_eq2, a_eq3= a, b # this is your "a" and b in "a*x0 + b*y0"
b1_eq = minimization_objfunc_output # this is your minimization constraint in "a*x0 + b* x1 = result of minimization"
x0_bounds = (0, 1) # those are the bounds
x1_bounds = (0, 1)
C = [-c0, -c1]
A_ub = [[-a_ub0, -a_ub1]]
A_eq = [[a_eq0, a_eq1],[a_eq2, a_eq3]]
b_ub = [b0_ub]
b_eq = [b0_eq, b1_eq]
res = linprog(C, A_ub=A_ub, b_ub=b_ub,
A_eq=A_eq, b_eq=b_eq,
bounds=[x0_bounds, x1_bounds])
print(f'max value is {res["fun"]} with solutions x: {res["x"]}')
ВЫХОД :
min value is 5.210942788380635e-12 with solutions x: [0.23076923 0.76923077]
max value is -5.897435897450446 with solutions x: [0.23076923 0.76923077]
ВТОРОЕ более универсальное c решение для адаптации любого определения проблемы к формату LinProg
from scipy.optimize import linprog
import numpy as np
##### Ideal generic inputs
def convertInputs_toLinProg(objective,
c,
A_GtE, b_GtE,
A_LtE, b_LtE,
A_Eq, b_Eq,
list_of_bounds):
A_GtE = -1 * A_GtE
b_GtE = -1 * b_GtE
if not (A_GtE is None) and not (A_LtE is None):
A_ub = np.vstack([A_GtE,A_GtE])
elif not (A_GtE is None) and (A_LtE is None):
A_ub = A_GtE
elif (A_GtE is None) and not (A_LtE is None):
A_ub = A_GtE
if objective == "maximize":
c = -1*c
return {
"c":c,
"A_ub": A_ub,
"A_eq": A_Eq,
"b_ub": b_GtE,
"b_eq": b_Eq,
"bounds": list_of_bounds
}
a,b,c,d = 10.0,-3.0,10.0,4.666666666666666
####defining the minimization problem here
##### those are your inputs following scipy notation
# objective function:
# 10*x0 - 3*x1
c = [a, b]
c = np.array(c)
# 10*x0 -3*x1 >= 0
A_greaterEq, b_greaterEq =[[a, b]], [0]
A_greaterEq, b_greaterEq =np.array(A_greaterEq), np.array(b_greaterEq)
# 1*x0 + 1*x1 = 1
A_equals, b_equals = [[1, 1]], [1]
A_equals, b_equals = np.array(A_equals), np.array(b_equals)
# bounds are exactly how you define them
x0_bounds, x1_bounds = (0, 1), (0, 1)
inputs = convertInputs_toLinProg(objective="minimize",
c=c,
A_GtE= A_greaterEq, b_GtE= b_greaterEq,
A_LtE= None, b_LtE= None,
A_Eq= A_equals, b_Eq= b_equals,
list_of_bounds=[x0_bounds, x1_bounds])
res = linprog(**inputs)
minimization_objfunc_output = res['fun']
print(f'min value is {res["fun"]} with solutions x: {res["x"]}')
##### generic definition of your problem
####defining your original problem
##### those are your inputs following scipy notation
# objective function:
# 1*x0 + 5*x1
a,b,c,d = 10.0,-3.0,10.0,4.666666666666666
c = [c,d]
c = np.array(c)
# 1*x0 -1*x1 >= 0
A_greaterEq, b_greaterEq =[[a, b]], [0]
A_greaterEq, b_greaterEq =np.array(A_greaterEq), np.array(b_greaterEq)
# 1*x0 + 1*x1 = 1
A_equals, b_equals = [[1, 1],[a, b]], [1,minimization_objfunc_output]
A_equals, b_equals = np.array(A_equals), np.array(b_equals)
# bounds are exactly how you define them
x0_bounds, x1_bounds = (0, 1), (0, 1)
inputs = convertInputs_toLinProg(objective="maximize",
c=c,
A_GtE= A_greaterEq, b_GtE= b_greaterEq,
A_LtE= None, b_LtE= None,
A_Eq= A_equals, b_Eq= b_equals,
list_of_bounds=[x0_bounds, x1_bounds])
res = linprog(**inputs)
print(f'max value is {res["fun"]} with solutions x: {res["x"]}')
ВЫХОД 2
min value is 5.210942788380635e-12 with solutions x: [0.23076923 0.76923077]
max value is 5.897435897450446 with solutions x: [0.23076923 0.76923077]