Repast: запрос набора операторов и подсчет количества агентов в цикле while - PullRequest
0 голосов
/ 02 мая 2020

Я хочу получить логи c, например:

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;
}

, как видно, запрос должен быть повторно вызван и обновлен в то время как l oop, а второй запрос состоит из 3 условий (что нелегко с методом AndQuery ()).

Это очень легко реализовать в Netlo go. Каков подходящий и более короткий способ достижения в repast?

ОБНОВЛЕНИЕ - первоначальная попытка

    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, который позволяет рассматривать более двух условий одновременно?

текущая проблема:

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

Я переместил запрос за пределы, в то время как l oop для лучшего обнаружения. Я обнаружил, что медленная скорость может быть в значительной степени из-за использования «PropertyGreaterThanEquals». независимо от того, является ли запрашиваемое поле целым или двойным.

  1. , когда вы выполняете запрос с использованием «PropertyGreaterThanEquals», запрос выполняется очень медленно, независимо от того, является ли запрашиваемое поле целым или двойным. Тем не менее, он возвращает правильный результат.
  2. при запросе с использованием PropertyEquals запрос выполняется менее чем за одну секунду, независимо от того, является ли запрашиваемое поле целым или двойным. однако он возвращает неверный результат, так как ему необходимо учитывать "> =".

    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 Ответ

1 голос
/ 04 мая 2020

Для 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, я думаю, что некоторые из повторяющихся элементов, создаваемых запросом, на самом деле являются Java множествами. Вы можете попробовать привести к одному из них, а затем вызвать size (). Если это не набор, то вам действительно придется выполнять итерацию, поскольку условия фильтра запросов фактически применяются как часть итерации.

Для 3, я думаю, для этого есть несколько Java методов. new ArrayList(Iterable) и некоторые методы в коллекциях.

...