scipy.optimize紧凑约束

时间:2016-09-30 18:12:53

标签: python optimization scipy

我有一个长度为9的np.array A,它是目标函数中的变量。

A =  [ a1, a2, a3,
       b1, b2, b3,
       c1, c2, c3], where a1...c3 are real numbers.
with constraints: a1 > a2, a2 > a3,
                  b1 > b2, b2 > b3,
                  c1 > c2, c2 > c3

有没有简单的方法来编写约束?目前我有以下代码,但随着数组大小变大,很难全部编写它们。

cons = (
        {'type':'ineq',
         'fun': lambda x : np.array([x[0]-x[1]])
        }
    ,
        {'type':'ineq',
         'fun': lambda x : np.array([x[1]-x[2]])
        }
    ,
        {'type':'ineq',
         'fun': lambda x : np.array([x[3]-x[4]])
        }    
    ,
        {'type':'ineq',
         'fun': lambda x : np.array([x[4]-x[5]])
        }   
    ,
        {'type':'ineq',
         'fun': lambda x : np.array([x[6]-x[7]])
        }    
    ,
        {'type':'ineq',
         'fun': lambda x : np.array([x[7]-x[8]])
        }    
   )

2 个答案:

答案 0 :(得分:1)

显然,您的约束是A的每一列应该(元素方式)大于或等于其右侧的列。

您可以按如下方式制定单个vector-outpur约束:

def cons_fun(x):
    A = x.reshape(3,3) # change "(3,3)" according to the dimensions of A

    return np.array([A[:,i]-A[:,i+1] for i in range(3-1)]).ravel() # change "3" accordingly

cons = ({'type':'ineq',
         'fun' : cons_fun},)

根据我对SLSQP的经验,矢量输出约束导致比提供多个标量输出约束更快的优化时间。

答案 1 :(得分:0)

我认为scipy喜欢这些函数的数字输出而不是布尔值,所以每个函数排除两个以上的输入...(自由度和所有这些)你可以做的就是写一个列表理解为你做功能......

cons = ({'type':'ineq', 'fun': lambda x: x[i] - x[i+1]} for i in range(len(A)-1))

我不确定为什么你需要将减法结果转换为1长数组,所以我把它留了出去......它很容易被放回去