Python 具有整数解的线性系统约束优化
我对解决以下优化问题和获得最低正整数系数感兴趣:Python 具有整数解的线性系统约束优化,python,matrix,optimization,Python,Matrix,Optimization,我对解决以下优化问题和获得最低正整数系数感兴趣: min(x1 + x2 + x3) s.t. 2x1 – 2x3 = 0 2x2 – x3 = 0 由于方程的数量与变量的数量不匹配,我还添加了x1=1的约束。使用中的文档,我对代码进行了如下调整: mat = np.array([[2,0,-2],[0,2,-1]]) def create_data_model(mat): num_rows, num_vars =mat.shape data = {} data['c
min(x1 + x2 + x3)
s.t.
2x1 – 2x3 = 0
2x2 – x3 = 0
由于方程的数量与变量的数量不匹配,我还添加了x1=1
的约束。使用中的文档,我对代码进行了如下调整:
mat = np.array([[2,0,-2],[0,2,-1]])
def create_data_model(mat):
num_rows, num_vars =mat.shape
data = {}
data['constraint_coeffs'] = [
[2, 0, -2],
[0, 2, -1],
[1, 0, 0],
]
data['bounds'] = [0, 0, 1]
data['obj_coeffs'] = [1, 1, 1]
data['num_vars'] = num_vars
offset = np.max((num_rows, num_vars))-np.min((num_rows, num_vars))
data['num_constraints'] = num_rows+offset
return data
data=create_data_model(mat)
infinity = solver.infinity()
x = {}
for j in range(data['num_vars']):
x[j] = solver.IntVar(0, infinity, 'x[%i]' % j)
print('Number of variables =', solver.NumVariables())
for i in range(data['num_constraints']):
constraint = solver.RowConstraint(0, data['bounds'][i], '')
for j in range(data['num_vars']):
constraint.SetCoefficient(x[j], data['constraint_coeffs'][i][j])
print('Number of constraints =', solver.NumConstraints())
objective = solver.Objective()
for j in range(data['num_vars']):
objective.SetCoefficient(x[j], data['obj_coeffs'][j])
objective.SetMinimization()
if status == pywraplp.Solver.OPTIMAL:
for j in range(data['num_vars']):
print(x[j].name(), ' = ', x[j].solution_value())
print()
print('Problem solved in %f milliseconds' % solver.wall_time())
print('Problem solved in %d iterations' % solver.iterations())
print('Problem solved in %d branch-and-bound nodes' % solver.nodes())
else:
print('The problem does not have an optimal solution.')
denoms=[x[0].solution_value().as_integer_ratio()[1], x[1].solution_value().as_integer_ratio()[1],
x[2].solution_value().as_integer_ratio()[1]]
scaling_factor=lcmm(*denoms) #a method to get the least common multiple
coeff=[scaling_factor*x[0].solution_value(), scaling_factor*x[1].solution_value(),
scaling_factor*x[2].solution_value()]
这将返回[1,0.5,1]作为最佳解决方案,在缩放后变为[2,1,2]
(1) 在我的实现中,解算器没有找到最优解。为什么呢
(2) 有没有更简单的方法来获得最小正整数解?我在代码中看到了一些问题 用这句话:
x[j] = solver.IntVar(0.0, infinity, 'x[%i]' % j)
您是说优化器必须生成整数。但是,您的示例的答案是x2为0.5,因此无法给出最佳解决方案。尝试:
x[j] = solver.NumVar(0.0, infinity, 'x[%i]' % j)
允许浮动。然后你可以把它乘以整数
另一个问题是,使用以下选项设置每个约束:
constraint = solver.Constraint(0, data['bounds'][i], '')
这意味着此表达式的下限为0,上限为数据结构中的
bound
值。然而,对于第三个约束,这就像说0我认为下面的代码将给出解决方案,我们要做的唯一技巧是将上限和下限设置在.5到无穷大之间。这可能不是完美的代码,但我用这段代码得到了你的答案
from scipy.optimize import minimize
obj_fun = lambda x: (x[0]+ x[1]+ x[2])
constraint = ({'type': 'eq', 'fun': lambda x: 2*x[0] - 2*x[2]},
{'type': 'eq', 'fun': lambda x: 2*x[1]-x[2]})
bound = ((.5, None), (.5, None),(.5,None))
res = minimize(obj_fun, (2, 0,0), method='SLSQP', bounds=bound,
constraints=constraint)
res
抱歉,我打错了第一个约束条件。上面的一个只是一个示例,我想将此方法扩展到其他方法。虽然代数在纸上很简单,但如果变量的数量和方程的数量以前都不知道,如何通过编程实现这一点。@user2657817发现了问题,现在正在编辑。@user2657817查看这是否有效。这将返回一个错误,即“目标函数必须返回标量”。此外,为了帮助推广此方法,如何调整此代码以避免显式写出每个约束。我更新了答案以满足您的需要。
from scipy.optimize import minimize
obj_fun = lambda x: (x[0]+ x[1]+ x[2])
constraint = ({'type': 'eq', 'fun': lambda x: 2*x[0] - 2*x[2]},
{'type': 'eq', 'fun': lambda x: 2*x[1]-x[2]})
bound = ((.5, None), (.5, None),(.5,None))
res = minimize(obj_fun, (2, 0,0), method='SLSQP', bounds=bound,
constraints=constraint)
res