Python调用vrplib库解析具有VRPLIB标准格式的CVRP实例数据


什么是VRPLIB标准格式?

CVRPLIB的测试数据为了方便不同平台,不同代码的测试和迁移,针对CVRP问题具有标准的数据格式——VRPLIB格式,它是一种存放CVRP问题数据的经典形式。

以CVRP标准测试数据 Set-F 中的 F-n45-k4 为例,这份实例文件下有两部分,一部分是输入数据,另一部分是输出的路径方案。

输入数据 .vrp 格式

F-n45-k4 实例数据如下,通过冒号分隔了键值对。

  1. NAME: 文件名
  2. COMMENT: 数据说明
  3. TYPE: 数据的问题类型
  4. DIMENSION: 节点数
  5. EDGE_WEIGHT_TYPE: 基于节点坐标距离取权值的方式(EUC_2D:双精度距离,不进行四舍五入)
  6. CAPACITY: 车辆的容量

以上键值对可以通过冒号进行扩展。而对于数据存储部分,则以_SECTION 结尾的单词进行提示。

  1. NODE_COORD_SECTION: 每行数据代表一个节点的坐标信息,依次存放了节点的索引信息、x坐标、y坐标;
  2. DEMAND_SECTION: 每行数据代表一个节点的坐标信息,依次存放了节点的索引信息、节点的需求量;
  3. DEPOT_SECTION: 指明 depot 节点的索引信息,一般索引值为 1 的都表示 depot 点。

最后用 EOF(End of File ) 收尾。

NAME : F-n45-k4
COMMENT : (Fisher: problem 10, No of trucks: 4, Optimal value: 724)
TYPE : CVRP
DIMENSION : 45
EDGE_WEIGHT_TYPE : EUC_2D
CAPACITY : 2010
NODE_COORD_SECTION
1 0 0
...
45 24 -19 
DEMAND_SECTION
1 0
...
45 42
DEPOT_SECTION
 1
 -1
EOF

输出方案 .sol 格式

以 F-n45-k4 实例数据的输出方案为例,方案中用 Route # 打头作为新的一条车辆路径。最后一行是方案的成本。

注意,路径方案中默认省略了出发点的索引,其中的序号是上面输入数据的索引号加1,例如这里的节点1,表示第1个客户节点,即上面输入数据中索引值为“2”的节点。

Route #1: 43 44 28 33 29 27 6 5 7 35 3 4 14 13 12 11 18 17 10 
Route #2: 42 30 41 32 31 34 40 39 36 38 37 
Route #3: 24 9 15 1 2 16 
Route #4: 20 21 25 26 23 22 19 8 
Cost 724

Python调用vrplib库解析VRPLIB格式文件

vrplib 是一个专门用于处理带容量车辆路径问题 (CVRP) 实例的 Python 包。它最主要的特点是可以解析和编写VRPLIB标准格式的数据,以及从CVRPLIB上下载标准测试数据。它依赖于numpy库,且要求python 3.8+ 的解释器版本。

1. 安装并引入 vrplib

通过清华源安装 vrplib 库:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple vrplib

在代码开头引入:

import vrplib

2. 利用vrplib库下载标准数据集

vrplib 还有一个常用的功能就是能从 CVRPLIB 上下载相应的文件,并将数据文件存放在指定的 path 路径下。

vrplib.download_instance("F-n45-k4", path)
vrplib.download_solution("F-n45-k4", path")

3. 解析相应的数据文件

通过下面两行代码即可解析.vrp数据文件和.sol数据文件,并会自动打印解析的内容,我们来看下。

instance = vrplib.read_instance("F-n45-k4.vrp")
solution = vrplib.read_solution("F-n45-k4.sol")

以下是解析了.vrp 数据文件得到的内容,是一个包含所有解析数据的字典,同时会根据权重计算方式,将坐标信息转化为节点之间的运输权值(成本)。

{'name': 'F-n45-k4', 
'comment': '(Fisher: problem 10, No of trucks: 4, Optimal value: 724)', 
'type': 'CVRP', 
'dimension': 45, 
'edge_weight_type': 'EUC_2D', 
'capacity': 2010, 
'node_coord': array([[ 0.00e+00,  0.00e+00],
       [ 3.00e+00,  5.00e+00],
       ...
       [ 2.40e+01, -1.80e+01],
       [ 2.40e+01, -1.90e+01]]), 
'demand': array([0, .... 42]), 
'depot': array([0]), 
'edge_weight': array([[ 0. ,  5.83095189,  9.34077085, ..., 28.0713377 ,
        30.        , 30.61045573],
       [ 5.83095189,  0.        ,  4.03112887, ..., 25.96150997,
        31.144823  , 31.89043744],
       [ 9.34077085,  4.03112887,  0.        , ..., 27.77138815,
        34.51448971, 35.30226622],
       ...,
       [28.0713377 , 25.96150997, 27.77138815, ...,  0.        ,
        16.4924225 , 17.4642492 ],
       [30.        , 31.144823  , 34.51448971, ..., 16.4924225 ,
         0.        ,  1.        ],
       [30.61045573, 31.89043744, 35.30226622, ..., 17.4642492 ,
         1.        ,  0.        ]])}

而解析了.sol 数据文件得到的内容如下,是一个包含了路径信息,以及方案成本的字典。

{'routes': [[43, 44, 28, 33, 29, 27, 6, 5, 7, 35, 3, 4, 14, 13, 12, 11, 18, 17, 10], [42, 30, 41, 32, 31, 34, 40, 39, 36, 38, 37], [24, 9, 
15, 1, 2, 16], [20, 21, 25, 26, 23, 22, 19, 8]], 
'cost': 724}

4. 解析 Solomon 数据集中的 txt 文件

前面文章中提到,solomon数据集也是经典的CVRP数据集,但是它的输入数据文件是txt文件,是否也可以用vrplib 进行解析呢?答案是可以的。

instance = vrplib.read_instance("C101.txt", instance_format="solomon")

具体的返回内容与.vrp文件的返回内容类似。

利用vrplib库将数据编写为VRPLIB格式文件

假设现在我们是有了数据字典,想将它转化为VRPLIB格式文件,以方便测试其他标准CVRP数据的代码能够直接用来测试我们的数据,这时候就可以用到vrplib的转写功能,具体如下:

## 转写 vrp 数据
instance_loc = "instance.vrp"
instance_data = {
    "NAME": "instance",
    "TYPE": "CVRP",
    "VEHICLES": 2,
    "DIMENSION": 1,
    "CAPACITY": 1,
    "EDGE_WEIGHT_TYPE": "EUC_2D",
    "NODE_COORD_SECTION": [[250, 250], [500, 500]],
    "DEMAND_SECTION": [1, 1],
    "DEPOT_SECTION": [1],
}
vrplib.write_instance(instance_loc, instance_data)

# 转写 sol 方案数据
solution_loc = "solution.sol"
routes = [[1], [2, 3], [4, 5, 6]]
solution_data = {"Cost": 42, "Vehicle types": [1, 2, 3]}
vrplib.write_solution(solution_loc, routes, solution_data)

分别会得到的一个名为 instance.vrp 文件,和一个名为 solution.sol 文件

NAME: instance
TYPE: CVRP
VEHICLES: 2
DIMENSION: 1
CAPACITY: 1
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1	250	250
2	500	500
DEMAND_SECTION
1	1
2	1
DEPOT_SECTION
1
EOF
Route #1: 1
Route #2: 2 3
Route #3: 4 5 6
Cost: 42
Vehicle types: [1, 2, 3]
  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lins号丹

小小鼓励,满满动力~

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

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

打赏作者

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

抵扣说明:

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

余额充值