我有一个长度为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]])
}
)
答案 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长数组,所以我把它留了出去......它很容易被放回去