AnyLogic多订单卡车配送建模技术问询:基于官方示例实现顺路最优配送及订单参数访问
解决AnyLogic多订单卡车按距离排序配送的问题
我来帮你搞定这个多订单按距离排序配送的问题,刚好在AnyLogic里做过类似的场景,一步步来拆解:
首先得先调整你卡车的变量类型——你现在把订单存在名为order的变量里,得把它改成**List<Order>类型**(而不是单个Order),这样才能装下批次里的多个订单。之前用send(batch.unit)的话,batch.unit其实是一个AgentGroup<Order>,你可以直接把它转成List,比如在卡车接收消息的代码里写:
this.order = batch.unit.asList();
接下来分两步解决你的核心需求:
1. 访问每个订单的client参数
既然order是List<Order>了,你可以通过遍历列表轻松获取每个订单的client参数。比如要打印所有订单的配送地点,代码可以这么写:
for(Order o : order){ traceln("当前订单配送地点:" + o.client); }
不管你是要拿坐标还是其他属性,都可以通过o.client.xxx的方式访问。
2. 实现“先最近后次近”的排序与依次配送逻辑
第一步:给订单列表按距离排序
在卡车准备出发前,先把订单列表按照当前位置到每个client的距离从小到大排序,代码如下:
// 按距离从小到大排序订单列表 Collections.sort(order, new Comparator<Order>() { public int compare(Order o1, Order o2) { // 计算当前卡车到两个订单配送点的距离 double dist1 = distance(getX(), getY(), o1.client.getX(), o1.client.getY()); double dist2 = distance(getX(), getY(), o2.client.getX(), o2.client.getY()); // 按距离升序排序 return Double.compare(dist1, dist2); } });
这段代码会自动把列表里的订单重新排列,最近的订单排在最前面。
第二步:依次前往每个配送地点
推荐用状态图来实现循环配送,逻辑更清晰好维护:
- 给卡车添加一个状态图,设置三个状态:
等待订单、配送中、完成配送 - 在
等待订单状态,当收到订单批次后,先执行上面的排序代码,然后切换到配送中状态 - 在
配送中状态,添加一个moveTo动作:- 目标位置选择
order.get(0).client(也就是当前列表里第一个订单的配送点) - 在
moveTo的完成时回调里,写这段代码:// 标记当前订单已完成(如果有需要的话) order.get(0).isDelivered = true; // 从列表里移除已完成的订单 order.remove(0); // 如果还有未完成的订单,继续配送;否则回到等待状态 if(order.size() > 0){ stayInState(); // 留在配送中状态,继续下一个订单 } else { changeState("完成配送"); // 这里还可以添加卡车返回仓库、释放资源等逻辑 }
- 目标位置选择
这样卡车就会依次前往排序后的每个配送点,直到所有订单都送完。
如果你不想用状态图,也可以用递归调用moveTo的方式,但状态图的方式更直观,后期改需求也更容易调整。
内容的提问来源于stack exchange,提问作者Yope




