python调用gurobi求解最短路问题


最短路问题Shortest Path Problem

最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。
在这里插入图片描述
copytright@baidu


一、符号说明

符号说明
c i j c_{ij} cij弧ij上的权重,可以理解为距离,流量,时间等
x i j x_{ij} xij弧ij是否被选择通过,是binary变量
V V V图中的点集合

二、数学模型

min ⁡ ∑ ( i , j ) ∈ A c i j x i j ∑ ( j , i ) ∈ A x i j − ∑ ( i , j ) ∈ A x j i = b i , ∀ i ∈ V , b i = { − 1 , i f    i = s , 0 , i f    i ≠ s    a n d    i ≠ t , 1 , i f    i = t , \min \sum_{\left( i,j \right) \in A}{c_{ij}x_{ij}} \\ \sum_{\left( j,i \right) \in A}{x_{ij}}-\sum_{\left( i,j \right) \in A}{x_{ji}}=b_i,\forall i\in V, \\ b_i=\begin{cases} -1, if\,\,i=s,\\ 0, if\,\,i\ne s\,\,and\,\,i\ne t,\\ 1, if\,\,i=t,\\ \end{cases} min(i,j)Acijxij(j,i)Axij(i,j)Axji=bi,iV,bi=1,ifi=s,0,ifi=sandi=t,1,ifi=t,

三、python 调用gurobi求解

问题数据

这里我们使用距离矩阵来表示图。
在这里插入图片描述
copyright@https://jingyan.baidu.com/article/359911f58636ad57ff030645.html

代码

代码如下(示例):

# _*_coding:utf-8 _*_
from __future__ import print_function
from __future__ import division, print_function
from gurobipy import *
import numpy as np
import copy
import time

starttime = time.time()


#返回最优的路线
def reportMIP(model, Routes):
    if model.status == GRB.OPTIMAL:
        print("Best MIP Solution: ", model.objVal, "\n")
        var = model.getVars()
        for i in range(model.numVars):
            if (var[i].x > 0):
                print(var[i].varName, " = ", var[i].x)
                print("Optimal route:", Routes[i])


def getValue(var_dict, nodeNum):
    x_value = np.zeros([nodeNum, nodeNum])
    for key in var_dict.keys():
        a = key[0]
        b = key[1]
        x_value[a][b] = var_dict[key].x

    return x_value


def getRoute(x_value):
    x = copy.deepcopy(x_value)
    #     route_temp.append(0)
    previousPoint = 0
    route_temp = [previousPoint]
    count = 0
    while (count != len(x_value)-1):
        # print('previousPoint: ', previousPoint )
        if (x[previousPoint][count] > 0):
            previousPoint = count
            route_temp.append(previousPoint)
            count = 0
            continue
        else:
            count += 1
    route_temp.append(len(x_value)-1)
    return route_temp

if __name__ == "__main__":


    nodeNum =11

#距离矩阵
    cost =[[0,2,8,1,1000,1000,1000,1000,1000,1000,1000],[2,0,6,1000,1,1000,1000,1000,1000,1000,1000]
           ,[8,6,0,7,5,1,2,1000,1000,1000,1000],[1,1000,7,0,1000,1000,9,100,100,100,100],[100,1,5,100,0,3,100,2,100,100,100]
        ,[100,100,1,100,3,0,4,100,6,100,100],[100,100,2,9,100,4,0,100,3,1,100],[100,100,100,100,2,100,100,0,7,100,9]
        ,[100,100,100,100,100,6,3,7,0,1,2],[100,100,100,100,100,100,1,100,1,0,4],[100,100,100,100,100,100,100,100,9,2,4,0]]
    print("cost", cost)
    model = Model('TSP')

    # creat decision variables,决策变量
    X = {}
    for i in range(nodeNum):
        for j in range(nodeNum):
            if (i != j):
                X[i, j] = model.addVar(vtype=GRB.BINARY
                                       , name='x_' + str(i) + '_' + str(j)
                                       )

    # set objective function,目标函数

    obj = LinExpr(0)
    for key in X.keys():
        i = key[0]
        j = key[1]
        obj.addTerms(cost[key[0]][key[1]], X[key])

    model.setObjective(obj, GRB.MINIMIZE)

    # add constraints 出发点的流量约束

    lhs_1 =LinExpr(0)
    lhs_2 =LinExpr(0)
    for j in range(1, nodeNum-1):
        for i in range(0,nodeNum):
              if i == 0:
                lhs_1.addTerms(1, X[i, j])
    model.addConstr(lhs_1 == 1, name='visit_' + str(i)+"start")

    #终点的流量约束
    for i in range(1,nodeNum-1):
        for j in range(1, nodeNum):
              if j == nodeNum-1:
                  lhs_2.addTerms(1, X[i, j])
    model.addConstr(lhs_2 == 1, name='visit_' + str(j) + "end")

    #其余点的流量约束
    for j in range(1,nodeNum-1):
        lhs3 = LinExpr(0)
        for i in range(0, nodeNum-1):
            if i != j:
                lhs3.addTerms(1, X[i, j])
        for i in range(1, nodeNum):
            if i != j:
                lhs3.addTerms(-1, X[j, i])
        model.addConstr(lhs3 == 0, name='visit_' + str(j)+'balance_flow')

    model.write('modelshortestpath.lp')
    model.setParam(GRB.Param.MIPGap, 0)
    model.setParam(GRB.Param.TimeLimit, 60)
    model.optimize()
    # 可以输出求解的决策变量
    print(model.ObjVal)
    X_NEW={}
    for var in model.getVars():
        if (var.x > 0):
            print(var.varName, '\t', var.x)
            X_NEW[var.varName]=var.x

    x_value = getValue(X, nodeNum)
    route = getRoute(x_value)
    print('optimal route:', route)







结果展示

在这里插入图片描述

最短距离为13
最短路径为[0, 1, 4, 5, 2, 6, 9, 8, 10]

作者:王基光,清华大学,清华伯克利深圳学院(硕士在读)
刘兴禄,清华大学,清华伯克利深圳学院(博士在读)

  • 12
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值