Python 3.x 线性规划-Google ortools-决策变量最终值不正确

Python 3.x 线性规划-Google ortools-决策变量最终值不正确,python-3.x,linear-programming,or-tools,network-flow,Python 3.x,Linear Programming,Or Tools,Network Flow,我想解决一个线性规划问题。以下是问题的规格: 我有一个网络流问题,它被转化为一个线性规划问题。因此,必须实施所有流量限制,如容量、流量守恒等。我的目标是把成本降到最低 决策变量-我通过定义一个字典并在这128个位置中的每个位置添加决策变量,构建了两个8x8矩阵 约束-总共有24个约束,即: 1) 流从源开始。两个8x8矩阵的2个约束条件。 2) 水流在水槽处结束。两个8x8矩阵的2个约束条件。 3) 流量守恒有12个约束条件,两个矩阵各有8个约束条件。 4) 容量约束有2个约束,每个矩阵1个。

我想解决一个线性规划问题。以下是问题的规格:

我有一个网络流问题,它被转化为一个线性规划问题。因此,必须实施所有流量限制,如容量、流量守恒等。我的目标是把成本降到最低

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

约束-总共有24个约束,即: 1) 流从源开始。两个8x8矩阵的2个约束条件。 2) 水流在水槽处结束。两个8x8矩阵的2个约束条件。 3) 流量守恒有12个约束条件,两个矩阵各有8个约束条件。 4) 容量约束有2个约束,每个矩阵1个。 5) 有6个限制条件可避免重复

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

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

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

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

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

    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')
来自ortools.linear\u解算器导入pywraplp
将numpy作为np导入
def配置_约束(cfg、解算器、变量_列表):
打印(cfg)
dest_convs=cfg['dest_convs']
msize=cfg['lookback\u win']+1+1
rem_容量=cfg['rem_caps']
#约束1-流从源开始
对于范围内的i(目标转换):
#打印([(i,0,c)表示范围(1,msize)])
solver.Add(solver.Sum([variable_list[(i,0,c)]用于范围(1,msize)]中的c)==1)
#约束2-流在水槽处结束
对于范围内的i(目标转换):
#打印([(i,r,msize-1)用于范围(1,msize)]内的r)
solver.Add(solver.Sum([variable_list[(i,r,msize-1)],用于范围(1,msize)]中的r)==1)
#约束3-流量守恒
对于范围内的i(目标转换):
对于范围内的r(msize-1):
如果r+1==msize-1:
持续
solver.Add(solver.Sum([variable_list[(i,rind,r+1)]用于范围(r+1)]中的外皮)-solver.Sum([variable_list[(i,r+1,cind+1)]用于范围(r+1,msize-1)]==0)
#
##约束4-容量约束
对于范围内的i(目标转换):
求解器添加(求解器求和([variable_list[(i,r,c)],用于范围内的r(1,msize-1),用于范围内的c(r+1,msize-1)])参见:

Glop是一个纯LP。它只会解决mip问题的松弛。因此,错误检查器告诉您解决方案不是整数是正常的

如果您的程序是纯布尔的,您可以将GLOP_线性规划更改为BOP_整数规划。 或者你可以留在CBC

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

  • pywraplp.Solver.CBC\u混合整数规划
  • pywraplp.Solver.BOP\u INTEGER\u编程
  • pywraplp.Solver.SAT\u INTEGER\u编程

代替
pywraplp.Solver.GLOP\u线性规划

所有变量都必须是二进制的
,这样你就不会有线性规划问题。试试CP-SATI我不确定这是不是问题。我已经用LP单纯形法在Excel中解决了同样的问题。还会有其他问题吗?使用
pywraplp.Solver.CBC\u MIXED\u INTEGER_编程
pywraplp.Solver.BOP_INTEGER_编程
我不熟悉excel,但如果您确定使用了纯单纯形法(不是混合整数解算器)并获得了有效的解决方案,那么您的问题很可能是一个完全单模约束矩阵的问题(当你说“网络流”问题时,我会想到这一点)。在这种情况下,Glop也必须起作用(可能有一些隐藏的原因它不起作用;例如,由于选择了一些不常见的配置->IP+非IP解算器,变量失去了0-1的性质;一些常见解算器意外地需要显式边界).现在,对于具有布尔或整数变量的线性规划,除了BOP_整数规划外,还可以使用SAT_整数规划。