【问题标题】:optimization doesn't respect constraint优化不尊重约束
【发布时间】:2019-08-29 02:22:06
【问题描述】:

我有一个优化问题,我正在使用 scipy 和最小化模块解决它。我使用 SLSQP 作为方法,因为它是唯一适合我的问题的方法。要优化的函数是一个以“x”作为百分比列表的成本函数。我有一些必须遵守的限制:

  • 首先,百分比的总和应为 1 (PercentSum(x)) 如您在代码中所见,此约束添加为“eg”(等于)。
  • 第二个约束是关于一个物理值,它必须小于“proberty1Max”。该约束被添加为“ineq”(不等)。所以如果'proberty1

您可以在下面看到我尝试的模型。问题是“约束”功能。我得到了解决方案,其中“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.好的,我了解到,如果输出为正(> 0),则接受不等式约束。过去我认为

  1. 约束怎么样。在我的实际解决方案中,我使用循环添加了一些约束。在这种情况下,最好为函数提供循环索引,并且在函数中该索引用于选择数组的元素。在我的示例中,“val”决定约束是否适用于 proberty1 或 property2。约束的意思是,有多少属性在孔混合中。所以我正在计算属性乘以 percentOfInput。 “prop”是所有对象的总和。

我认为可能与 cmets 中提到的问题 tux007 有关。 link to the issue 如果最初的猜测不是有效的解决方案,我认为优化器无法正常工作。 线性规划不适用于超定方程。我的问题没有唯一的解决方案,它是一个近似值。

【问题讨论】:

  • SLSQP 期望连续和可微分(平滑)函数。我认为你违反了这一点,这可能会导致问题。 (虽然你说maxtat是常量数据,这很奇怪)。
  • 嘿欧文,我刚刚更新了这个问题。我希望这是足够的信息。
  • conMax = [{'type': 'ineq', 'fun': MaxLimit(x)}] 您没有将可调用的MaxLimit 作为约束传递,而是MaxLimit(x) 返回的常量值。这是故意的吗?
  • 嘿迪翁,好点子!我更新了代码。这是一个总结......在实际代码中,我使用的是 lamda 函数,因为 MaxLimit() 有多个参数,并且我通过循环添加了一些约束。
  • 可能和这个bug有关github.com/stevengj/nlopt/issues/254

标签: python-3.x optimization scipy linear-programming minimization


【解决方案1】:

正如评论中提到的,我认为这是问题所在: Misleading output from....

如果你看看最新的变化,约束是不满足的,但算法说:“线搜索的正方向导数”

【讨论】:

    猜你喜欢
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多