Repast:初始化慢的原因

Repast: slow initialization reason

我发现初始化我的模型非常慢。需要 40 秒才能完成!

我的代码包含两个主要部分:1)一个CSV数据reader会先运行加载数据,读取和处理35000+行用时不到1秒(见下面的第一部分代码); 2) 随后初始化代理和边缘。特别是,边缘初始化将使用 CSV reader 中的加载数据(请参阅下面的第二部分代码)。

第一部分:CSVReader代码

public class DataReader {

    private String csvFile;
    private List<String> sub = new ArrayList<String>();
    private List<List> master = new ArrayList<List>();


    public void ReadFromCSV(String csvFile) {

        String line = "";
        String cvsSplitBy = ",";

        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
            System.out.println("Header " + br.readLine());
            while ((line = br.readLine()) != null) {

                // use comma as separator
                String[] list = line.split(cvsSplitBy);
//                System.out.println("the size is " + country[1]);
                for (int i = 0; i < list.length; i++) {
                    sub.add(list[i]);
                }
                List<String> temp = (List<String>) ((ArrayList<String>) sub).clone();
//                master.add(new ArrayList<String>(sub));
                master.add(temp);
                sub.removeAll(sub);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(master);
    }

    public List<List> getMaster() {
        return master;
    }

}

这是 CSVReader 使用的输入文件:

第二部分:边(路由)初始化代码。我怀疑是查询循环消耗了大部分时间进行初始化:

//      add route network
        Network<Object> net = (Network<Object>)context.getProjection("IntraCity Network");
        IndexedIterable<Object> local_hubs = context.getObjects(LocalHub.class);
        for (int i = 0; i <= CSV_reader_route.getMaster().size() - 1; i++) {
            String source = (String) CSV_reader_route.getMaster().get(i).get(0);
            String target = (String) CSV_reader_route.getMaster().get(i).get(3);
            double dist = Double.parseDouble((String) CSV_reader_route.getMaster().get(i).get(6));
            double time = Double.parseDouble((String) CSV_reader_route.getMaster().get(i).get(7));

            Object source_hub = null;
            Object target_hub = null;
            Query<Object> source_query = new PropertyEquals<Object>(context, "hub_code", source);
            for (Object o : source_query.query()) {
                if (o instanceof LocalHub) {
                    source_hub = (LocalHub) o;
                }
                if (o instanceof GatewayHub) {
                    source_hub = (GatewayHub) o;
                }
            }

            Query<Object> target_query = new PropertyEquals<Object>(context, "hub_code", target);
            for (Object o : target_query.query()) {
                if (o instanceof LocalHub) {
                    target_hub = (LocalHub) o;
                }
                if (o instanceof GatewayHub) {
                    target_hub = (GatewayHub) o;
                }
            }

            if (net.getEdge(source_hub, target_hub) == null) {
                Route this_route = (Route) net.addEdge(source_hub, target_hub);
                context.add(this_route);
                this_route.setDist(dist);
                this_route.setTime(time); }
            }



        }

更新:根据我的测试,我发现这条线会大大减慢初始化过程。

context.add(this_route);

没有这条线只用了 3 秒就完成了。使用这条线,模型花费了 20 秒! context.add() 的底层机制是什么?如何解决和改善这个问题?

当您将边缘添加到上下文中时,随着上下文中的搜索 space 变得更大,查询的计算成本会更高。因此,也许不将边缘添加到 csv reader 循环中的上下文会有所帮助。您可以像现在一样创建边缘,但将其添加到列表而不是上下文。然后当 reader 循环完成时遍历该列表并将边添加到上下文中。

如果这没有帮助,那么至少我们知道添加到我们可以尝试追踪的上下文中还有一个额外的副作用。