python-3.x - 线性规划 - Google ortool - 错误的决策变量最终值

标签 python-3.x linear-programming or-tools network-flow

我正在尝试解决线性规划问题。以下是问题的具体情况:

我有一个网络流问题,已转换为线性规划问题。因此,所有流量约束,例如容量、流量守恒等,都必须强制执行。我的目标是最大限度地降低成本。

决策变量 - 我通过定义字典并在这 128 个位置中的每个位置添加决策变量来构建两个 8x8 矩阵。

约束 - 总共有 24 个约束,即: 1) 流程从源头开始。两个 8x8 矩阵都有 2 个约束。 2) 水流在水槽处结束。两个 8x8 矩阵都有 2 个约束。 3) 流量守恒有 12 个约束,两个矩阵各有 8 个。 4) 有 2 个约束来遵守容量约束,每个矩阵 1 个。 5)有6个约束以避免重复

所有变量都必须是二进制的。

目标 - 8x8 矩阵中的某些变量的总和需要最小化。

同样,所有变量都必须是二进制的。

我已经能够在 Google ORTOOLS 中编写解决方案,并且解决方案收敛并显示最小值。但是,当我查看变量时,有些变量具有非二进制值。另外,该解决方案是错误的(我有一个在 Excel 中运行的现有解决方案,它是正确的且不同)。

如果有人能指出我正确的方向,我将不胜感激。以下是用 Python 36 编写的代码。

    from ortools.linear_solver import pywraplp
import numpy as np

def configure_constraints(cfg, solver, variable_list):

    print(cfg)
    dest_convs = cfg['dest_convs']
    msize = cfg['lookback_win'] + 1 + 1
    rem_capacity = cfg['rem_caps']

    # Constraint 1 - Flow starts at the source
    for i in range(dest_convs):
        # print([(i, 0, c) for c in range(1, msize)])
        solver.Add(solver.Sum([variable_list[(i,0,c)] for c in range(1, msize)]) == 1)

    # Constraint 2 - Flow ends at the sink
    for i in range(dest_convs):
        # print([(i, r, msize - 1) for r in range(1, msize)])
        solver.Add(solver.Sum([variable_list[(i,r,msize - 1)] for r in range(1, msize)]) == 1)

    # Constraint 3 - Flow Conservation
    for i in range(dest_convs):
        for r in range(msize - 1):
            if r+1 == msize - 1:
                continue

            solver.Add(solver.Sum([variable_list[(i,rind, r+1)] for rind in range(r + 1)]) - solver.Sum([variable_list[(i,r+1, cind + 1)] for cind in range(r+1, msize - 1)]) == 0)
    #
    # # Constraint 4 - Capacity Constraint
    for i in range(dest_convs):
        solver.Add(solver.Sum([variable_list[(i, r, c)] for r in range(1, msize-1) for c in range(r+1, msize - 1)]) <= rem_capacity[i] - 1)

    #
    # # Constraint 5 - 1-vehicle, 1-conveyor
    dest_conv_list = []
    for i in range(dest_convs):
        dest_conv_list.append([])
        for r in range(1, msize - 1):
            dest_conv_list[i].append(sum([variable_list[(i,r,c)] for c in range(r+1, msize)]))

    for items in zip(*dest_conv_list):
        solver.Add(solver.Sum(items) == 1)



def configure_objective(solver, variable_list, cost_vars):
    # Objective
    solver.Minimize(solver.Sum([variable_list[items] for items in zip(*np.where(cost_vars))]))


def solve(solver):
    result_status = solver.Solve()
    return result_status

def configure_variables(cfg, solver):

    # identify variables for the objective function
    # print(cfg)
    nvehs = cfg['vehicles']
    dest_convs = cfg['dest_convs']
    color_vec = cfg['color_vec']
    cur_cars = cfg['cur_cars']
    msize = cfg['lookback_win'] + 1 + 1

    # objective_mat = np.zeros((msize, msize), dtype="int32")
    mat = [[[0] * msize for i in range(msize)] for j in range(dest_convs)]

    # source to vehicles
    for i in range(dest_convs):
        for j in range(nvehs):
            # print(color_vec[j], cur_cars[i])
            if color_vec[j] != cur_cars[i]:
                mat[i][0][j+1] = 1


    for h in range(dest_convs):
        for i in range(0, nvehs):
            for j in range(i+1, nvehs):
                # print(i+1,j+1)
                # print(color_vec[i+1], color_vec[j])
                if color_vec[i] != color_vec[j]:
                    mat[h][i+1][j + 1] = 1

    cost_vars = np.array(mat).reshape(dest_convs, msize, msize)
    print(np.array(mat).reshape(dest_convs,msize,msize))

    dvars = {}
    for i in range(dest_convs):
        for j in range(msize):
            for k in range(msize):
                dvars[i, j, k] = solver.BoolVar('x[%i,%i, %i]' % (i, j, k))


    return  dvars, cost_vars

def main(cfg, what):
    solver = pywraplp.Solver('SolveSimpleSystem', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)

    dvars_list, cost_vars = configure_variables(cfg, solver)

    configure_constraints(cfg, solver, dvars_list)
    configure_objective(solver, dvars_list, cost_vars)

    result_status = solve(solver)

    print('Number of Variables:', solver.NumVariables())
    print('Number of Constraints:', solver.NumConstraints())
    # print('Constraints:',     solver.)

    if result_status == solver.OPTIMAL:
        print('Solution Found.')
        # The problem has an optimal solution.
        print(('Problem solved in %f milliseconds' % solver.wall_time()))
        # The objective value of the solution.
        print(('Optimal objective value = %f' % solver.Objective().Value()))

        var_sum = 0
        for variable in dvars_list:
            print(('%s = %f' % (dvars_list[variable].name(), dvars_list[variable].solution_value())))
            var_sum += dvars_list[variable].solution_value()

        print(('Variable sum = %f' % var_sum))

        # The value of each variable in the solution.
    elif result_status == solver.INFEASIBLE:
        print('No solution found.')
    elif result_status == solver.POSSIBLE_OVERFLOW:
        print('Some inputs are too large and may cause an integer overflow.')


if __name__ == '__main__':
    cfg = {'vehicles': 6,
           'dest_convs': 2,
           'cur_cars':['B', 'R'],
           'rem_caps': [3,3],
           'lookback_win':6,
           'color_vec': ['W', 'W', 'B', 'B', 'R', 'B'],
           }

    main(cfg, 'cost')

最佳答案

参见:https://groups.google.com/forum/#!msg/or-tools-discuss/p5qVzZWIeIg/g77egaD-AAAJ

Glop is a pure LP. It will only solve the relaxation of the mip problem. So it is normal that the error checker tells you that the solution is not integral.

You can change GLOP_LINEAR_PROGRAMMING to BOP_INTEGER_PROGRAMMING if you program is purely boolean. Or you can stay with CBC

这就是为什么您应该使用:

  • pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING
  • pywraplp.Solver.BOP_INTEGER_PROGRAMMING
  • pywraplp.Solver.SAT_INTEGER_PROGRAMMING

而不是pywraplp.Solver.GLOP_LINEAR_PROGRAMMING

关于python-3.x - 线性规划 - Google ortool - 错误的决策变量最终值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59116520/

相关文章:

linear-programming - AMPL 中的非负偏差变量

c++ - 线性优化目标函数中的绝对值

python - 从数组中获取所需的列索引并将这些列添加到数据框中

python - python类构造函数中的缩进错误

python - 从文件中检索与文件中指定的给定区域相对应的数字

c++ - gurobi - 错误代码 = 10004 无法检索属性 'X'

algorithm - 您如何找到学生在类里面的最佳分配?

python - 导入错误: No module named 'llvmlite.llvmpy.ee'

python - OR 针对 Protocol Buffer 版本 3.5.1 编译的工具,与已安装的版本不兼容

python - 如何在 Google OR-Tools 中设置每条路线的最小位置?