微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

寻求有关改进 AnyLogic 中的自定义函数的建议

如何解决寻求有关改进 AnyLogic 中的自定义函数的建议

我正在使用旁路距离估算大型城市网络中的最后一英里交付成本。我有超过 8000 个客户代理和 100 多个零售店代理使用经纬度坐标绘制在 GIS 地图中。每个客户都从最近的商店(按路线)接收交货。目标是为每个商店在这个网络中获得两个距离度量:

d0_bar:从商店到所有指定客户的平均距离
d1_bar:同一个店铺所有顾客之间的平均距离

我编写了一个带有简单 foreach 循环的启动函数,以根据路线距离将每个客户分配到一个商店(客户有一个参数,“customer.pStore”类型的商店)。该函数还依次将每个客户添加到商店代理的客户集合(“store.colCusts”;它是一个包含 Customer 类型元素的数组列表)。

接下来,我有一个函数,它遍历商店代理群体并计算上面的两个平均距离度量(d0_bar 和 d1_bar)并将结果写入一个 txt 文件(见下面的代码)。幸运的是,代码有效。然而,问题在于,对于如此庞大的数据集,通过 openstreetmap.org API 遍历所有客户/商店和检索距离的过程需要永远。它已经初始化(“请稍候...”)大约 12 个小时。我该怎么做才能使此代码更有效?或者,AnyLogic 中是否有更好的方法来为我网络中的每个商店获取这两个距离度量?

提前致谢。

    //for each store,record all customers assigned to it
    for (Store store : stores) 
        {
        distancesstore.print(store.storeCode + "," + store.colCusts.size() + "," + store.colCusts.size()*(store.colCusts.size()-1)/2 + ",");
    
    //calculates average distance from store j to customer nodes that belong to store j
        double sumFirstdistByStore = 0.0;
        int h = 0;
        while (h < store.colCusts.size())
            {
            sumFirstdistByStore += store.distanceByRoute(store.colCusts.get(h));
            h++;
            }
        distancesstore.print((sumFirstdistByStore/store.colCusts.size())/1609.34 + ",");
            
    //calculates average of distances between all customer nodes belonging to store j
        double custdistSumPerStore = 0.0;
        int loopLimit = store.colCusts.size();
        int i = 0;
        while (i < loopLimit - 1)
            {
            int j = 1;
            while (j < loopLimit)
                {
                custdistSumPerStore += store.colCusts.get(i).distanceByRoute(store.colCusts.get(j));
                j++;
                }
            i++;
            }   
        distancesstore.print((custdistSumPerStore/(loopLimit*(loopLimit-1)/2))/1609.34);
        distancesstore.println();
        }

解决方法

首先是一些简单的评论:

  1. 您是否尝试过为单个 distanceByRoute 调用计时?例如。您可以尝试运行 store.distanceByRoute(store.colCusts.get(0)); 来查看一次调用在您的系统上花费的时间吗?路由通常很慢,但最好知道速度限制是多少。
  2. 第一个简单的改变是使用 java 并行性。而不是使用这个:
    for (Store store : stores)
    { ...

使用这个:

    stores.parallelStream().forEach(store -> {
    ...
    });

这将使用 standard Java streams API 并行处理 stores 个条目。

  1. 它看起来也像第二个循环 - 计算客户之间的平均距离时不考虑镜像。也就是说距离 a->b 等于 b->a。因此,例如,4 个客户将需要 6 次计算:1->2、1->3、1->4、2->3、2->4、3->4。而在 4 个客户的情况下,您的第二个 while 循环将执行 9 次计算: i=0,j in {1,2,3}; i=1,3}; i=2,3},除非我误解了您的意图,否则这似乎是错误的。
  2. 通常,对于长时间运行的操作,最好包含一些 traceln 以显示相关时间的进度。

请查看上面并发布结果。有了更多信息,可能会进一步提高性能。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。