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