Gurobi+Python 求解经典网络流问题

网络流问题介绍:

网络流是指在图中给定源点和汇点的前提下,通过网络中的边传输流量,使得从源点到汇点的流量最大(或最小)的问题。在网络中,每一条边都有一个容量(表示能够通过该边的最大流量),每个点都有一个出入流量的平衡限制。网络流问题的基本特点是将问题转化为图模型,用图论算法解决,如最大流算法、最小割算法、最大权闭合子图等。

网络流问题可以用于许多实际问题的建模,如物流配送问题、交通流量优化问题、电力网络问题等。最大流问题是最基础和常见的网络流问题,例如在一个污染源通过河流将污染物排放到下游地区,但是在不同的时间段污染物的流量不同,如何安排排放时间和量以使得下游受污染的程度最小。求解此问题就可以利用最大流算法,将河流视为一个网络,求解从污染源到下游地区的最大流量,以此来安排污染物的排放时间和量。

在实际应用中,由于复杂度的限制,网络流问题往往需要通过一些优化方法来求解。常见的优化方法有增广路算法、最小费用最大流算法、最大流最小费用算法等。

经典网络流问题:

  1. 最大流问题:在一张有向图中,给定源点和汇点,每条边都有一个容量限制,求从源点到汇点的最大流量。

  2. 最小割问题:在一张有向图中,给定源点和汇点,每条边都有一个容量限制,将图中的点分成两个集合S和T,要求源点在S中,汇点在T中,且S和T之间的割的容量最小。

  3. 二分图最大匹配问题:给定一张二分图,求其中的一个最大匹配,即选择最多的边,使得每个节点最多与一个节点匹配。

  4. 最大权闭合子图问题:给定一张有向图,每个节点有一个权值,求一个点集S,使得S中的点能够到达所有其他点,并且S中节点权值之和最大。

  5. 最大流最小花费问题:在一张有向图中,给定源点和汇点,每条边都有一个容量和一个费用,求从源点到汇点的最大流同时满足最小费用。

代码实现:

经典网络流问题(最大流最小花费问题)

给定源点汇点及线路费用:有一些供应商节点(i)及需求节点(j),已知每个供应商产量(Pi),用户需求量(Di),以及每条路径运输成本(Cij)

目标:最小化运输成本

注意:约束条件中不能含有np矩阵,需出现矩阵时增加变量声明

import gurobipy as gp
from gurobipy import *
import numpy as np

# 原始数据
N_i = 3        # 供应节点数
N_j = 4        # 需求节点数
C_ij = np.array([[0.0755, 0.0655, 0.0498, 0.0585],
                [0.0276, 0.0163, 0.0960, 0.0224],
                [0.0680, 0.0119, 0.0340, 0.0751]
                ])       # 各线路费用
P_min = np.array([100,50,30])        # 最小出力
P_max = np.array([450,350,500])       # 最大出力
demand = np.array([217,150,145,244])    # 负荷需求

# 模型建立
m = gp.Model("网络流问题")

# 变量声明
x = m.addVars(N_i, N_j, vtype=GRB.CONTINUOUS, lb=0, name="x")    # 运输方式
u = m.addVars(N_i,vtype=GRB.BINARY,name="u")    # 每个供应商是否出力


# 设置目标函数
m.setObjective(quicksum(C_ij[i,j]*x[i,j] for i in range(N_i) for j in range(N_j)), GRB.MINIMIZE)

# 添加约束
# 输出约束,若 P 不等于 0,则每个 P 在 P_max 与 P_min 之间
m.addConstrs((quicksum(x[i, j] for j in range(N_j)) >= P_min[i] * u[i] for i in range(N_i)), name="con1")
m.addConstrs((quicksum(x[i, j] for j in range(N_j)) <= P_max[i] * u[i] for i in range(N_i)), name="con2")
# 负荷约束
m.addConstrs((quicksum(x[i, j] for i in range(N_i)) >= demand[j] for j in range(N_j)), name="con3")



# 模型求解
m.optimize()

# 输出
m.getVars()
x_c = np.zeros([N_i , N_j], dtype=float)
for j in range(N_j):
    for i in range(N_i):
        x_c[i,j] = x[i,j].x


print('x_c is',x_c)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用GurobiPython求解双目标线性规划的示例代码: ```python import gurobipy as gp # 创建模型 model = gp.Model('bilevel_problem') # 创建变量 x1 = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='x1') x2 = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='x2') y1 = model.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='y1') y2 = model.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='y2') # 创建约束条件 constr1 = model.addConstr(2*x1 + x2 <= y1, name='constr1') constr2 = model.addConstr(x1 + 2*x2 <= y2, name='constr2') # 定义目标函数 model.setObjective(y1 + y2, gp.GRB.MINIMIZE) # 创建子问题 submodel1 = gp.Model('subproblem1') submodel2 = gp.Model('subproblem2') # 创建子问题变量 subx1 = submodel1.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx1') subx2 = submodel1.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx2') suby1 = submodel1.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='suby1') submodel1.update() subx1 = submodel2.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx1') subx2 = submodel2.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx2') suby2 = submodel2.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='suby2') submodel2.update() # 创建子问题约束条件 subconstr1 = submodel1.addConstr(2*subx1 + subx2 <= suby1, name='subconstr1') submodel1.setObjective(suby1, gp.GRB.MAXIMIZE) subconstr2 = submodel2.addConstr(subx1 + 2*subx2 <= suby2, name='subconstr2') submodel2.setObjective(suby2, gp.GRB.MAXIMIZE) # 添加双层问题约束条件 model.addConstr(suby1 <= y1, name='subconstr1') model.addConstr(suby2 <= y2, name='subconstr2') # 求解模型 model.optimize() # 输出结果 print('x1=', x1.x) print('x2=', x2.x) print('y1=', y1.x) print('y2=', y2.x) ``` 在上面的代码中,我们定义了四个变量和两个约束条件,然后为目标函数设置了两个目标。接下来,我们创建了两个子问题,并分别定义了它们的变量和约束条件。然后,我们将子问题的解添加到双层问题的约束条件中,并使用 `optimize()` 方法求解模型。最后,我们输出了模型的解。 需要注意的是,双目标线性规划具有较高的计算复杂度和较多的局限性,需要根据具体问题进行调整和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值