Repast:查询一个代理集,统计while循环中的代理数



我想实现这样的逻辑:

while (count loading_docks with [status == "free"] > 0 and trucks with [status == "free" and type == "20'" and capacity < 1000] > 0) {
match a truck satisfying above 3 condidtions to a free dock for unloading cargo;
}

可以看出,查询需要在while循环中重复调用和更新,第二个查询由3个条件组成(AndQuery((方法不容易(。

这在Netlogo中很容易实现。在就餐中,什么是合适且更短的方式?

UPDATE-首次尝试

public void match_dock() {

for (Truck t: this.getTruck_queue()) {
if (this.Count_freeDock() > 0) {
Query<Object> fit_dock = new AndQuery(
new PropertyEquals(context, "status", 1), 
new PropertyGreaterThanEquals(context, "max_veh", t.getTruck_type()));
double min = 10000; 
Dock match = null;
for(Object o: fit_dock.query()) {
if (((Dock)o).getMax_veh() < min) {
match = (Dock)o;
}
}
match.setStatus(2);
match.getServe_list().add(t.getReq_id());
t.setServe_dock(match.getId());
//              if (t.getServe_dock() != -1) {
//                  this.getTruck_queue().remove(t);
//              }
}
}
}

public int Count_freeDock() {
List<Dock> free_list = new ArrayList<Dock>();
Query<Object> free_dock = new PropertyEquals<Object>(context, "status", 1);
for (Object o : free_dock.query()) {
if (o instanceof Dock) {
free_list.add((Dock)o);
}
}
return free_list.size();
} 

有三个问题需要解决:

1( 对特定代理集的查询必须考虑三个条件;AndQuery只包含两个条件。是否存在允许同时考虑两个以上条件的查询方法?

当前问题:

Query<Object> pre_fit = new AndQuery(
new PropertyEquals(context, "status", 1), 
new PropertyGreaterThanEquals(context, "max_veh", t.getTruck_type()));
Query<Object> fit_dock = new AndQuery(pre_fit, new PropertyEquals(context, "ops_type", 3));

两个条件的初始组合工作良好,查询速度快。然而,当我添加第三个条件"ops_type"时,查询速度变得非常慢。背后的原因是什么?或者这是构成三个条件的正确方法吗?

2( 除了编写自定义计数函数(如示例所示(之外,是否还有更简单的方法来查询特定代理集的大小(计数(?

3( 将查询到的代理集添加(或复制(到列表中进行相关列表操作的最短方法是什么?

更新整个代码块:

public void match_dock() {
Iterator<Truck> truck_list = this.getTruck_queue().iterator();
while(truck_list.hasNext() && this.Count_freeDock() > 0) {
Truck t = truck_list.next();
//              Query<Object> pre_fit = new AndQuery(
//                                          new PropertyEquals(context, "status", 1), 
//                                          new PropertyGreaterThanEquals(context, "max_veh", t.getTruck_type()));
//              Query<Object> ops_fit = new OrQuery<>(
//                                          new PropertyEquals(context, "ops_type", 3), 
//                                          new PropertyEquals(context, "ops_type", this.getOps_type(t.getOps_type())));
//              Query<Object> fit_dock = new AndQuery(pre_fit, new PropertyEquals(context, "ops_type", 3));
//              Query<Object> fit_dock = new AndQuery(pre_fit, ops_fit);
Query<Object> pre_fit = new AndQuery(
new PropertyEquals(context, "status", 1), 
new PropertyGreaterThanEquals(context, "max_veh", t.getTruck_type()));
Query<Object> q = new PropertyEquals(context, "ops_type", 3);

double min = 10000; 
Dock match = null;
for (Object o : q.query(pre_fit.query())) {
//              for(Object o: fit_dock.query()) {
if (((Dock)o).getMax_veh() < min) {
match = (Dock)o;
}
}
try {
match.setStatus(2);
match.getServe_list().add(t.getReq_id());
t.setServe_dock(match.getId());
if (t.getServe_dock() != -1) {
System.out.println("truck id " + t.getReq_id() + "serve dock: " + t.getServe_dock());
t.setIndock_tm(this.getTick());
truck_list.remove();
}
}
catch (Exception e){
//                  System.out.println("No fit dock found");
}           
}
}

public int Count_freeDock() {
List<Dock> free_list = new ArrayList<Dock>();
Query<Object> free_dock = new PropertyEquals<Object>(context, "status", 1);
for (Object o : free_dock.query()) {
if (o instanceof Dock) {
free_list.add((Dock)o);
}
}
//      System.out.println("free trucks: " + free_list.size());
return free_list.size();
}

5/5更新

为了更好地检测,我已将查询移到while循环之外。我发现速度慢可能主要是由于使用了"PropertyGreaterThanEquals"。不管查询的字段是int还是double。

  1. 使用"PropertyGreaterThanEquals"进行查询时,无论查询的字段是int还是double,查询运行速度都非常慢。但是,它返回正确的结果
  2. 当您使用"PropertyEquals"进行查询时,无论查询的字段是int还是double,查询都会在不到一秒钟的时间内运行。但是,它返回的结果是不正确的,因为它需要考虑">="。

    public void match_dock() {
    System.out.println("current tick is: " + this.getTick());
    Iterator<Truck> truck_list = this.getTruck_queue().iterator();
    Query<Object> pre_fit = new AndQuery(
    new PropertyEquals(context, "status", 1), 
    new PropertyGreaterThanEquals(context, "max_veh", 30));
    //new PropertyEquals(context, "max_veh", 30));
    Query<Object> q = new PropertyEquals(context, "hv_spd", 240);
    
    for (Object o : q.query(pre_fit.query())) {
    if (o instanceof Dock) {
    System.out.println("this object is: " + ((Dock)o).getId());
    }
    }
    

    }

对于1,您可以尝试链接查询,如下所示:

Query<Object> pre_fit = new AndQuery(
new PropertyEquals(context, "status", 1), 
new PropertyGreaterThanEquals(context, "max_veh", t.getTruck_type()));
Query<Object> q = new PropertyEquals(context, "ops_type", 3);
for (Object o : q.query(pre_fit.query())) { ...

我认为这可能比嵌入AndQuery更快,但我不完全确定。

对于2,我认为Query生成的一些Iterable实际上是Java集。您可以尝试强制转换为其中一个,然后调用size((。如果它不是一个集合,那么您实际上必须进行迭代,因为查询筛选条件实际上是作为迭代的一部分应用的。

对于3,我认为有一些Java方法可以实现这一点。CCD_ 1以及Collections中的一些方法。

最新更新