如何解决给定一些约束,最小化两个列表元素的峰值差异
我想使用 scipy.optimize.minimize 方法最小化 list1[i] - list2[i] 的峰值差异。 list1 和 list2 中的元素是浮点数。
例如:
list1 = [50,50.5,52,53,55,55.5,56,57,60,61]
鉴于我有两个约束,如何最小化 list1[i] - list2[i]:
1. list2 = list1[0]
2. list2[i+1]-list2[i]
基本上list2中两个连续的元素之间的间隔不能超过1.5,list2的第一个元素就是list1的第一个元素。
也许除了 scipy.optimize.minimize 之外还有另一种方法,但我不知道该怎么做。 我认为 list2 的最佳值可能是: list2 = [50,54.5,58.5,60]
在这种情况下,峰值差为 1.5。 但也许算法会找到一个更优的解决方案,其中 list1 和 list2 的元素之间的差异更小。
这是我尝试过但失败的方法:
import numpy as np
from scipy.optimize import minimize
list1 = [50,61]
list2 = [list1[0]]
#Define objective
def peakDifference(*args):
global list2
peak_error = []
for list1_i,list2_i in zip(list1,list2):
peak_error.append(list1_i-list2_i)
return max(peak_error)
peak_error = peakDifference()
#Define constraints
def constraint1(*args):
for x in range(len(list2) - 1):
return list2[x+1] - list2[x] - 1.5
con1 = {'type': 'ineq','fun': constraint1}
#Optimize
sol = minimize(peakDifference,list2,constraints=con1)
Traceback (most recent call last): File "C:/Users/JumpStart/PycharmProjects/anglesimulation/venv/asdfgh.py",line 27,in <module>
sol = minimize(peakDifference,constraints=con1) File "C:\Users\JumpStart\anaconda3\lib\site-packages\scipy\optimize\_minimize.py",line 625,in minimize
return _minimize_slsqp(fun,x0,args,jac,bounds,File "C:\Users\JumpStart\anaconda3\lib\site-packages\scipy\optimize\slsqp.py",line 412,in _minimize_slsqp
a = _eval_con_normals(x,cons,la,n,m,meq,mieq) File "C:\Users\JumpStart\anaconda3\lib\site-packages\scipy\optimize\slsqp.py",line 486,in _eval_con_normals
a_ieq = vstack([con['jac'](x,*con['args']) File "C:\Users\JumpStart\anaconda3\lib\site-packages\scipy\optimize\slsqp.py",in <listcomp>
a_ieq = vstack([con['jac'](x,line 284,in cjac
return approx_derivative(fun,x,method='2-point',File "C:\Users\JumpStart\anaconda3\lib\site-packages\scipy\optimize\_numdiff.py",line 426,in approx_derivative
return _dense_difference(fun_wrapped,f0,h,line 497,in _dense_difference
df = fun(x) - f0 TypeError: unsupported operand type(s) for -: 'nonetype' and 'nonetype'
Process finished with exit code 1
解决方法
自然语言处理模型
这是 NLP 模型的“工作”版本。该模型无法通过这种方式可靠地求解,因为它是不可微的。
import numpy as np
from scipy.optimize import minimize
list1 = np.array([50,50.5,52,53,55,55.5,56,57,60,61])
list1_0 = list1[0]
n = len(list1)
# our x variable will have one element less (first element is fixed)
list1x = np.delete(list1,0) # version with 1st element dropped
nx = len(list1x)
# objective function
# minimize the the maximum difference
# Notes:
# - x excludes first element (they are the same by definition)
# - this is non-differentiable so likely to be non-optimal
def maxDifference(x):
return np.max(np.abs(list1x - x))
# n-1 constraints
def constraint1(x):
return 1.5 - np.diff(np.insert(x,list1_0),1)
con1 = {'type': 'ineq','fun': constraint1}
#Optimize
x = 55*np.ones(nx) # initial value
sol = minimize(maxDifference,x,constraints=con1)
sol
# optimal is: x = [51.25,51.25,52.75,54.25,54.75,56.25,57.75,59.25,60.25]
# obj = 0.75
结果是:
fun: 5.0
jac: array([0.,0.,0.])
message: 'Optimization terminated successfully'
nfev: 20
nit: 2
njev: 2
status: 0
success: True
x: array([51.5,53.,54.5,55.,56. ])
这不是最优的:目标是 5(而不是 0.75)。
LP 模型
LP 模型将找到经过验证的最佳解决方案。那可靠得多。例如:
import pulp as lp
list1 = [50,61]
n = len(list1)
model = pulp.LpProblem("Min_difference",pulp.LpMinimize)
x = lp.LpVariable.dicts("x",(i for i in range(n)))
z = lp.LpVariable("z")
# objective
model += z
# constraints
for i in range(n):
model += z >= x[i]-list1[i]
model += z >= list1[i]-x[i]
for i in range(n-1):
model += x[i+1] - x[i] <= 1.5
model += x[0] == list1[0]
model.solve()
print(lp.LpStatus[model.status])
print("obj:",z.varValue)
print([x[i].varValue for i in range(n)])
这表明:
Optimal
obj: 0.75
[50.0,53.75,55.25,56.75,60.25]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。