优化问题|多车场的电动公交车调度问题:模型及Python调用CPLEX代码实现

作者简介:本人擅长运筹优化建模及算法设计,包括各类车辆路径问题、生产车间调度、二三维装箱问题,熟悉CPLEX和gurobi求解器

微信公众号:运筹优化与学习

问题描述

多车场的电动公交车调度问题(Multi Depot Electric Vehicle Scheduling Problem,  MDEVSP)可描述为:已知具有固定始末点,始末时间的车次集合,寻找一种车次任务安排方案,使得:

(1) 每辆公交车按顺序完成一系列车次;

(2) 每个车次仅完成一次;

(3) 执行所有车次的费用最小.

数据输入包括:车次集合、车辆集合、车场集合以及充电站集合。每个车次有特定的开始时间、结束时间、旅行距离。每辆车具有有限的行驶距离,必须从车场出发,最后返回初始车场。假设车辆放电量与行驶里程呈线性关系(放电量=行驶里程乘以百公里耗电量)。每辆车可以在任意的充电站进行完全或部分充电,且充电量与充电时间呈线性关系。

 模型构建

代码实现

定义模型变量及约束

def setup_constraints(mdl, Data, Time, Distance, M, g, r, Depot, V, R, T):
    # setup_variables
    arc = setup_arcs(Data, Time, R, T, V, Depot)
    A = [(i, j, k) for i in V for j in V for k in range(Data.depotNum)]
    H = [i for i in R]

    mdl.x = mdl.binary_var_dict(A, name='x')
    mdl.h = mdl.continuous_var_dict(H, lb=0, name='h')
    mdl.z = mdl.continuous_var_dict(V, lb=0, name='z')  # arrival time
    mdl.y = mdl.continuous_var_dict(V, lb=0, ub=capacity, name='y')  # remaining battery charge
    for i in V:
        for j in V:
            for k in range(Data.depotNum):
                if arc[i][j] == 0:
                    mdl.add_constraint(mdl.x[i, j, k] == 0)

    # (1) 每个车次只被服务一次
    for i in T:
        mdl.add_constraint(mdl.sum(mdl.x[i, j, k] for k in range(Data.depotNum)
                                   for j in Depot[1] + R + T) == 1)

    # (2) 同一个充电站每辆车最多只能充电一次
    for k in range(Data.depotNum):
        for i in R:
            mdl.add_constraint(mdl.sum(mdl.x[i, j, k] for j in R + T) <= 1)

    # (3)
    for index in range(Data.depotNum):
        i = Depot[0][index]
        mdl.add_constraint(mdl.sum(mdl.x[i, j, k] for k in range(Data.depotNum)
                                   for j in Depot[1] + R + T if index != k) == 0)

    # (4)
    for index in range(Data.depotNum):
        j = Depot[1][index]
        mdl.add_constraint(mdl.sum(mdl.x[i, j, k] for k in range(Data.depotNum) if index != k
                                   for i in Depot[0] + R + T) == 0)

    # (5)
    for k in range(Data.depotNum):
        for i in R + T:
            mdl.add_constraint(mdl.sum(mdl.x[i, j, k] for j in Depot[1] + R + T)
                               == mdl.sum(mdl.x[j, i, k] for j in Depot[0] + R + T))

    # (6) 车次节点在指定的开始时间开始服务
    mdl.add_constraints(mdl.z[i] == Time.readyTime[i] for i in T)

    # (7) 车场与充电站只在规定时间窗内服务
    mdl.add_constraints(Time.readyTime[i] <= mdl.z[i] for i in Depot[0] + Depot[1] + R)
    mdl.add_constraints(Time.dueTime[i] >= mdl.z[i] for i in Depot[0] + Depot[1] + R)

    # (8)
    for i in T:
        for j in V:
            mdl.add_constraint(mdl.z[i] + Time.consume[i] + Distance[i][j] -
                               M * (1 - mdl.sum(mdl.x[i, j, k] for k in range(Data.depotNum))) <= mdl.z[j])

    # (9)
    for i in R:
        for j in Depot[1] + T:
            mdl.add_constraint(mdl.z[i] + Distance[i][j] + g * mdl.h[i] -
                               M * (1 - mdl.sum(mdl.x[i, j, k] for k in range(Data.depotNum))) <= mdl.z[j])

    # (10)
    for i in Depot[0] + T:
        for j in Depot[1] + R + T:
            mdl.add_constraint(mdl.y[i] - Time.consume[i] - r * Distance[i][j] +
                               M * (1 - mdl.sum(mdl.x[i, j, k] for k in range(Data.depotNum))) >= mdl.y[j])

    # (11)
    for i in R:
        for j in R + T:
            mdl.add_constraint(mdl.y[i] + mdl.h[i] - r * Distance[i][j] +
                               M * (1 - mdl.sum(mdl.x[i, j, k] for k in range(Data.depotNum))) >= mdl.y[j])

    # (12)
    mdl.add_constraints(mdl.h[i] <= capacity - mdl.y[i] for i in R)

获取完整代码,请关注微信公众号:运筹优化与学习,联系我们

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eternal1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值