python限定变量为整数_将scipy.optimize.minimize限制为整数
值
纸浆溶液
经过研究,我认为你的⽬标函数不是线性的。我在Pythonpulp库中重新创建了这个问题,但是pulp不喜欢我们⽤float
和'LpAffineExpression'分隔。This answer表明线性规划“不理解划分”,但该注释是在添加约束的上下⽂中,⽽不是在⽬标函数中。那条评论把我指向了“Mixed Integer Linear Fractional Programming (MILFP)”和Wikipedia。
如果它真的起作⽤了(也许有⼈能弄清楚原因),你可以⽤纸浆来做:import pulp
data = [(481.79, 5), (412.04, 4), (365.54, 3)] #, (375.88, 3), (379.75, 3), (632.92, 5), (127.89, 1), (835.71, 6), (200.21, 1)]
x = pulp.LpVariable.dicts('x', range(len(data)), lowBound=0, upBound=7, cat=pulp.LpInteger)
numerator = dict((i,tup[0]) for i,tup in enumerate(data))
denom_int = dict((i,tup[1]) for i,tup in enumerate(data))
problem = pulp.LpProblem('Mixed Integer Linear Programming', n=pulp.LpMinimize)
# objective function (doesn't work)
# TypeError: unsupported operand type(s) for /: 'float' and 'LpAffineExpression'
problem += sum([numerator[i] / (denom_int[i] + x[i]) for i in range(len(data))])
problem.solve()
for v in problem.variables():
print(v.name, "=", v.varValue)
使⽤scipy.optimize的强⼒解决⽅案
可以为函数中的每个x使⽤brute和slices的范围。如果函数中有3xs,那么ranges元组中也有3slices。所有这些的关键是将1的步骤⼤⼩添加到slice(start, stop,step)soslice(#, #, 1)。from scipy.optimize import brute
import itertools
def f(x):
return (481.79/(5+x[0]))+(412.04/(4+x[1]))+(365.54/(3+x[2]))
ranges = (slice(0, 9, 1),) * 3
result = brute(f, ranges, disp=True, finish=None)
print(result)
itertools解决⽅案
或者可以使⽤itertools⽣成所有组合:combinations = list(itertools.product(*[[0,1,2,3,4,5,6,7,8]]*3))
values = []
for combination in combinations:
values.append((combination, f(combination)))
best = [c for c,v in values if v == min([v for c,v in values])]
print(best)
注意:这是原始函数的缩⼩版本,例如。