优化不尊重约束
optimization doesn't respect constraint
我有一个优化问题,我正在用 scipy 和最小化模块解决它。我使用 SLSQP 作为方法,因为它是唯一适合我的问题的方法。要优化的函数是一个以 'x' 作为百分比列表的成本函数。我有一些必须遵守的限制条件:
- 首先,百分比的总和应该是 1 (PercentSum(x)) 这个约束被添加为 'eg' (等于),正如你在代码中看到的那样。
- 第二个约束条件是物理值必须小于 'proberty1Max '。此约束添加为 'ineq'(不等)。所以如果 'proberty1 < proberty1Max ' 函数应该大于 0。否则函数应该是 0。函数是可微的。
下面你可以看到我尝试的模型。问题是 'constrain' 函数。我得到解决方案,其中 'prop' 的总和大于 'probertyMax'.
import numpy as np
from scipy.optimize import minimize
class objects:
def __init__(self, percentOfInput, min, max, cost, proberty1, proberty2):
self.percentOfInput = percentOfInput
self.min = min
self.max = max
self.cost = cost
self.proberty1 = proberty1
self.proberty2 = proberty2
class data:
def __init__(self):
self.objectList = list()
self.objectList.append(objects(10, 0, 20, 200, 2, 7))
self.objectList.append(objects(20, 5, 30, 230, 4, 2))
self.objectList.append(objects(30, 10, 40, 270, 5, 9))
self.objectList.append(objects(15, 0, 30, 120, 2, 2))
self.objectList.append(objects(25, 10, 40, 160, 3, 5))
self.proberty1Max = 1
self.proberty2Max = 6
D = data()
def optiFunction(x):
for index, obj in enumerate(D.objectList):
obj.percentOfInput = x[1]
costSum = 0
for obj in D.objectList:
costSum += obj.cost * obj.percentOfInput
return costSum
def PercentSum(x):
y = np.sum(x) -100
return y
def constraint(x, val):
for index, obj in enumerate(D.objectList):
obj.percentOfInput = x[1]
prop = 0
if val == 1:
for obj in D.objectList:
prop += obj.proberty1 * obj.percentOfInput
return D.proberty1Max -prop
else:
for obj in D.objectList:
prop += obj.proberty2 * obj.percentOfInput
return D.proberty2Max -prop
def checkConstrainOK(cons, x):
for con in cons:
y = con['fun'](x)
if con['type'] == 'eq' and y != 0:
print("eq constrain not respected y= ", y)
return False
elif con['type'] == 'ineq' and y <0:
print("ineq constrain not respected y= ", y)
return False
return True
initialGuess = []
b = []
for obj in D.objectList:
initialGuess.append(obj.percentOfInput)
b.append((obj.min, obj.max))
bnds = tuple(b)
cons = list()
cons.append({'type': 'eq', 'fun': PercentSum})
cons.append({'type': 'ineq', 'fun': lambda x, val=1 :constraint(x, val) })
cons.append({'type': 'ineq', 'fun': lambda x, val=2 :constraint(x, val) })
solution = minimize(optiFunction,initialGuess,method='SLSQP',\
bounds=bnds,constraints=cons,options={'eps':0.001,'disp':True})
print('status ' + str(solution.status))
print('message ' + str(solution.message))
checkConstrainOK(cons, solution.x)
没有办法找到解决方案,但输出是这样的:
Positive directional derivative for linesearch (Exit mode 8)
Current function value: 4900.000012746761
Iterations: 7
Function evaluations: 21
Gradient evaluations: 3
status 8
message Positive directional derivative for linesearch
我错在哪里?在这种情况下,它以模式 8 结束,因为示例非常小。对于更大的数据,算法以模式 0 结束。但我认为它应该以无法保持约束的提示结束。
proberty1Max 设置为 4 或 1 都没有关系。但如果设置为 1,则无法找到有效的解决方案。
PS: 这道题我改了很多...现在代码可以执行了
编辑:
1.Okay,我了解到,如果输出为正(>0),则接受不等约束。过去我认为 <0 也会被接受。因此,约束函数现在稍微短了一些。
- 约束呢。在我的实际解决方案中,我使用循环添加了一些约束。在这种情况下,最好为函数提供循环索引,并且在函数中该索引用于选择数组的元素。在我这里的示例中,"val" 决定约束是针对 proberty1 还是 属性2。约束的意思是,孔混合中有多少 属性。所以我正在计算 属性 乘以 percentOfInput。 "prop" 是所有对象的总和。
我认为这可能与评论中提到的问题 tux007 有关。 link to the issue
如果最初的猜测不是有效的解决方案,我认为优化器无法正常工作。
线性规划不适用于超定方程。我的问题没有唯一的解决方案,它是一个近似值。
如评论中所述,我认为这是问题所在:
Misleading output from....
如果你看一下最新的变化,约束不满足,但算法说:"Positive directional derivative for linesearch"
我有一个优化问题,我正在用 scipy 和最小化模块解决它。我使用 SLSQP 作为方法,因为它是唯一适合我的问题的方法。要优化的函数是一个以 'x' 作为百分比列表的成本函数。我有一些必须遵守的限制条件:
- 首先,百分比的总和应该是 1 (PercentSum(x)) 这个约束被添加为 'eg' (等于),正如你在代码中看到的那样。
- 第二个约束条件是物理值必须小于 'proberty1Max '。此约束添加为 'ineq'(不等)。所以如果 'proberty1 < proberty1Max ' 函数应该大于 0。否则函数应该是 0。函数是可微的。
下面你可以看到我尝试的模型。问题是 'constrain' 函数。我得到解决方案,其中 'prop' 的总和大于 'probertyMax'.
import numpy as np
from scipy.optimize import minimize
class objects:
def __init__(self, percentOfInput, min, max, cost, proberty1, proberty2):
self.percentOfInput = percentOfInput
self.min = min
self.max = max
self.cost = cost
self.proberty1 = proberty1
self.proberty2 = proberty2
class data:
def __init__(self):
self.objectList = list()
self.objectList.append(objects(10, 0, 20, 200, 2, 7))
self.objectList.append(objects(20, 5, 30, 230, 4, 2))
self.objectList.append(objects(30, 10, 40, 270, 5, 9))
self.objectList.append(objects(15, 0, 30, 120, 2, 2))
self.objectList.append(objects(25, 10, 40, 160, 3, 5))
self.proberty1Max = 1
self.proberty2Max = 6
D = data()
def optiFunction(x):
for index, obj in enumerate(D.objectList):
obj.percentOfInput = x[1]
costSum = 0
for obj in D.objectList:
costSum += obj.cost * obj.percentOfInput
return costSum
def PercentSum(x):
y = np.sum(x) -100
return y
def constraint(x, val):
for index, obj in enumerate(D.objectList):
obj.percentOfInput = x[1]
prop = 0
if val == 1:
for obj in D.objectList:
prop += obj.proberty1 * obj.percentOfInput
return D.proberty1Max -prop
else:
for obj in D.objectList:
prop += obj.proberty2 * obj.percentOfInput
return D.proberty2Max -prop
def checkConstrainOK(cons, x):
for con in cons:
y = con['fun'](x)
if con['type'] == 'eq' and y != 0:
print("eq constrain not respected y= ", y)
return False
elif con['type'] == 'ineq' and y <0:
print("ineq constrain not respected y= ", y)
return False
return True
initialGuess = []
b = []
for obj in D.objectList:
initialGuess.append(obj.percentOfInput)
b.append((obj.min, obj.max))
bnds = tuple(b)
cons = list()
cons.append({'type': 'eq', 'fun': PercentSum})
cons.append({'type': 'ineq', 'fun': lambda x, val=1 :constraint(x, val) })
cons.append({'type': 'ineq', 'fun': lambda x, val=2 :constraint(x, val) })
solution = minimize(optiFunction,initialGuess,method='SLSQP',\
bounds=bnds,constraints=cons,options={'eps':0.001,'disp':True})
print('status ' + str(solution.status))
print('message ' + str(solution.message))
checkConstrainOK(cons, solution.x)
没有办法找到解决方案,但输出是这样的:
Positive directional derivative for linesearch (Exit mode 8)
Current function value: 4900.000012746761
Iterations: 7
Function evaluations: 21
Gradient evaluations: 3
status 8
message Positive directional derivative for linesearch
我错在哪里?在这种情况下,它以模式 8 结束,因为示例非常小。对于更大的数据,算法以模式 0 结束。但我认为它应该以无法保持约束的提示结束。
proberty1Max 设置为 4 或 1 都没有关系。但如果设置为 1,则无法找到有效的解决方案。
PS: 这道题我改了很多...现在代码可以执行了
编辑: 1.Okay,我了解到,如果输出为正(>0),则接受不等约束。过去我认为 <0 也会被接受。因此,约束函数现在稍微短了一些。
- 约束呢。在我的实际解决方案中,我使用循环添加了一些约束。在这种情况下,最好为函数提供循环索引,并且在函数中该索引用于选择数组的元素。在我这里的示例中,"val" 决定约束是针对 proberty1 还是 属性2。约束的意思是,孔混合中有多少 属性。所以我正在计算 属性 乘以 percentOfInput。 "prop" 是所有对象的总和。
我认为这可能与评论中提到的问题 tux007 有关。 link to the issue 如果最初的猜测不是有效的解决方案,我认为优化器无法正常工作。 线性规划不适用于超定方程。我的问题没有唯一的解决方案,它是一个近似值。
如评论中所述,我认为这是问题所在: Misleading output from....
如果你看一下最新的变化,约束不满足,但算法说:"Positive directional derivative for linesearch"