我有一个包含大约 22 个约束函数的优化。我尝试将其转换为单个约束函数,但优化器花费了 10 倍的时间。有什么办法可以降低速度吗
以下是原始约束函数。我只包含了 2 个,但大约有 22 个,每个都有不等式约束的硬编码值。这些参数是优化器正在寻找的值,优化器正在寻找大约 50 个值。例如,对于第一个约束,它基本上表示,前 2 个参数值相加不得超过 129:
def MaxConstraint000(parameters):
_count = np.sum(parameters[0:2])
return (129 - _count)
def MaxConstraint001(parameters):
_count = np.sum(parameters[2:5])
return (2571 - _count)
_Constraints = ({'type': 'ineq', 'fun': MaxConstraint000}
, {'type': 'ineq', 'fun': MaxConstraint001})
为了简化我的代码,而不是预先确定参数的位置,我尝试了这样的方法,其中我提供了一个键值,该键值提取参数值的索引位置以及常量值 [129、2571 等。 ..] 来自数据框。 DFData 的行数与参数数相同。该约束与第一个约束相同,只是我提供了一个 keyValue,它允许我查找最大值以及索引位置。
def MaxConstraint(parameters, keyValue):
_parameters= np.array(parameters)
_index = np.where(DFData['KeyValues'].values == keyValue)[0]
_count = np.sum(_parameters[_index])
_target = DFMaxValues.loc[[keyValue], ['MaxValue']].values[0][0]
return (_target - _count )
_Constraints = ({'type': 'ineq', 'fun': MaxConstraint, 'args': ('keyValue1', )}
, {'type': 'ineq', 'fun': MaxConstraint, 'args': ('keyValue2', )}
这会导致执行时间延长 10 倍。如何使其速度降至与第一个速度大致相同?我更喜欢第二种实现,因为我可以只更新字典或 CSV 文件,而不是进入每个约束并更改 MaxValue。此外,如果数据行混合,我就没有硬编码的索引值。
谢谢!
全套约束:
def MaxConstraint000(parameters):
_count = np.sum(parameters[0:2])
return (129 - _count)
def MaxConstraint001(parameters):
_count = np.sum(parameters[2:5])
return (2571 - _count)
def MaxConstraint002(parameters):
_count = np.sum(parameters[5:8])
return (3857 - _count)
def MaxConstraint003(parameters):
_count = np.sum(parameters[8:10])
return (823 - _count)
def MaxConstraint004(parameters):
_count = np.sum(parameters[10:13])
return (823 - _count)
def MaxConstraint005(parameters):
_count = np.sum(parameters[13:16])
return (3857 - _count)
def MaxConstraint006(parameters):
_count = np.sum(parameters[16:21])
return (4714 - _count)
def MaxConstraint007(parameters):
_count = np.sum(parameters[21:25])
return (3429 - _count)
def MaxConstraint008(parameters):
_count = np.sum(parameters[25:28])
return (3429 - _count)
def MaxConstraint009(parameters):
_count = np.sum(parameters[28:30])
return (3429 - _count)
def MaxConstraint010(parameters):
_count = np.sum(parameters[30:33])
return (2914 - _count)
def MaxConstraint011(parameters):
_count = np.sum(parameters[33:38])
return (6000 - _count)
def MaxConstraint012(parameters):
_count = np.sum(parameters[38:43])
return (6000 - _count)
def MaxConstraint013(parameters):
_count = np.sum(parameters[43:45])
return (429 - _count)
def MaxConstraint014(parameters):
_count = np.sum(parameters[45:47])
return (1457 - _count)
def MaxConstraint015(parameters):
_count = np.sum(parameters[47:51])
return (4286 - _count)
def MaxConstraint016(parameters):
_count = np.sum(parameters[51:53])
return (2143 - _count)
def MaxConstraint017(parameters):
_count = np.sum(parameters[53:57])
return (4286 - _count)
def MaxConstraint018(parameters):
_count = np.sum(parameters[57:64])
return (2143 - _count)
def MaxConstraint019(parameters):
_count = np.sum(parameters[64:67])
return (2571 - _count)
def MaxConstraint020(parameters):
_count = np.sum(parameters[67:72])
return (1714 - _count)
def MaxConstraint021(parameters):
_count = np.sum(parameters[72:75])
return (4286 - _count)
_Bounds = ((0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000), (0, 10000)
, (0, 10000), (0, 10000), (0, 10000))
_Constraints = ({'type': 'ineq', 'fun': MaxConstraint000}
, {'type': 'ineq', 'fun': MaxConstraint001}
, {'type': 'ineq', 'fun': MaxConstraint002}
, {'type': 'ineq', 'fun': MaxConstraint003}
, {'type': 'ineq', 'fun': MaxConstraint004}
, {'type': 'ineq', 'fun': MaxConstraint005}
, {'type': 'ineq', 'fun': MaxConstraint006}
, {'type': 'ineq', 'fun': MaxConstraint007}
, {'type': 'ineq', 'fun': MaxConstraint008}
, {'type': 'ineq', 'fun': MaxConstraint009}
, {'type': 'ineq', 'fun': MaxConstraint010}
, {'type': 'ineq', 'fun': MaxConstraint011}
, {'type': 'ineq', 'fun': MaxConstraint012}
, {'type': 'ineq', 'fun': MaxConstraint013}
, {'type': 'ineq', 'fun': MaxConstraint014}
, {'type': 'ineq', 'fun': MaxConstraint015}
, {'type': 'ineq', 'fun': MaxConstraint016}
, {'type': 'ineq', 'fun': MaxConstraint017}
, {'type': 'ineq', 'fun': MaxConstraint018}
, {'type': 'ineq', 'fun': MaxConstraint019}
, {'type': 'ineq', 'fun': MaxConstraint020}
, {'type': 'ineq', 'fun': MaxConstraint021}
)
############# Solve Optim Problem ###############
_OptimResultsConstraint = scipy_opt.minimize(ObjectiveFunction
, x0 = [10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000,
10000, 10000, 10000] # starting guesses
, method = 'trust-constr' # trust-constr, SLSQP
, options = {'maxiter': 1000000000}
, bounds = _Bounds
, constraints = _Constraints)
你的多重限制实际上只是一种限制。最紧凑的表示方式是一个稀疏 CSR 数组:
import numpy as np
from scipy.optimize import LinearConstraint
import scipy.sparse
A = scipy.sparse.csr_array(
(
np.ones(75), # data
np.arange(75), # indices
(
0, 2, 5, 8, 10, 13, 16, 21, 25, 28,
30, 33, 38, 43, 45, 47, 51, 53, 57,
64, 67, 72, 75,
),
),
)
constraint = LinearConstraint(
A=A,
ub=(
129, 2571, 3857, 823, 823, 3857, 4714, 3429, 3429, 3429,
2914, 6000, 6000, 429, 1457, 4286, 2143, 4286, 2143, 2571,
1714, 4286,
),
)