如何在Google OR-Tools中正确添加取送货点?添加时遇异常
问题根源
你这报错的核心问题有俩:
- 节点重复使用:你要加的
{12,16}里,12已经是原有取送对{13,12}的送货点,16是原有取送对{16,14}的取货点。OR-Tools的取送货VRP规则很严格,每个节点只能归属于唯一的取送对,重复分配就会触发底层内存访问错误。 - 无空闲节点:现有的DistanceMatrix是17x17的,包含0到16共17个节点,其中0是仓库,剩下16个节点已经全部分成8组取送对,没有多余节点可供新增取送对使用。
正确添加取送对的两种方法
方法1:扩展节点和距离矩阵
如果确实要新增取送对,得先给DistanceMatrix添加新的节点行和列,再添加合法的取送对:
- 扩展距离矩阵:在原矩阵末尾新增行和列,对应新节点(比如17、18),填充这些新节点到所有已有节点的真实距离值。
- 添加新取送对:用新增的、未被使用的节点创建取送对,确保两个节点都没在其他取送对中出现过。
修改后的代码示例:
public class DataModel { // 扩展为19x19的距离矩阵,新增节点17、18的距离数据(示例值请替换为实际距离) public long[,] DistanceMatrix = { { 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662, 200, 300 }, { 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210, 250, 350 }, // 保留原有的15行数据,此处省略 { 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0, 400, 500 }, // 新增节点17的行:到所有节点的距离 { 200, 250, /* 其他节点的距离 */, 400, 0, 100 }, // 新增节点18的行:到所有节点的距离 { 300, 350, /* 其他节点的距离 */, 500, 100, 0 } }; public int[][] PickupsDeliveries = { new int[] { 1, 6 }, new int[] { 2, 10 }, new int[] { 4, 3 }, new int[] { 5, 9 }, new int[] { 7, 8 }, new int[] { 15, 11 }, new int[] { 13, 12 }, new int[] { 16, 14 }, // 新增取送对,使用刚添加的节点 new int[] { 17, 18 } }; public int VehicleNumber = 5; public int Depot = 0; }
方法2:调整现有取送对
如果不想新增节点,可以修改原有取送对,替换掉某一对来满足需求:
比如把原有的{16,14}换成你需要的{12,16},同时把原来和12配对的13改成和14配对,保证所有节点只出现一次:
public int[][] PickupsDeliveries = { new int[] { 1, 6 }, new int[] { 2, 10 }, new int[] { 4, 3 }, new int[] { 5, 9 }, new int[] { 7, 8 }, new int[] { 15, 11 }, new int[] { 13, 14 }, new int[] { 12, 16 } };
额外注意事项
- 取送对的顺序必须是
[取货点, 送货点],OR-Tools会自动添加「取货必须在送货之前完成」的约束,顺序错误会导致业务逻辑不符合预期。 - 所有取送对中的节点编号不能超出DistanceMatrix的索引范围,否则仍会触发错误。
内容的提问来源于stack exchange,提问作者DPTP
相关产品推荐
相关产品推荐

