Search code examples
javasimulationanylogic

Anylogic: how to Batch agents with similar parameters?


I have an agent called products, and in this agent, I assigned a parameter called sp; in the simulation, I have the same agent with a different sp range from 1 to 5. I want to batch the agents with the same sp in the same batch, which is 10. So if I have 200 agents, 49 of them with sp equals 1, I would like to batch them in 5 batches (10,10,10,10,9), and sp equals 2 with another batch and so on.

I really appreciate any help you can provide.


Solution

  • There are a number of ways in which you can do this, but given the fact that you have non-consistent batches (i.e. you have batches of 10 and then the last one is 9) I would first put all the agents inside a wait block (or you can use a queue) and then programmatically control them

    Take the following small example

    enter image description here

    I wait until 200 of my "Product" agents arrive at the wait block and then I press the button "Check Batches" which calls the function batchReleaseCheck()

    Here is the code

    LinkedHashMap<Integer, List<Product>> productsWaiting = new LinkedHashMap<Integer, List<Product>>();
    for (int i = 0; i < wait.size(); i ++){
        Product product = wait.get(i);
        int sp = product.sp;
        if (!productsWaiting.containsKey(sp)) productsWaiting.put(sp, new ArrayList<Product>());
        productsWaiting.get(sp).add(product);
        
        //Check the batch size if sufficient we release it
        if (productsWaiting.get(sp).size() == batchSize) {
            for (Product p:productsWaiting.get(sp)) {
                wait.free(p);
            }
            return; // we exit the loop since we have released a batch
        } 
    }
    
    // If we get to the end of the loop we were not able to release any batch we now release each SP type regardless of their current batch size
    
    for (int i = 1; i < 6; i ++) {
        if (productsWaiting.get(i) == null) continue;
        for (Product p:productsWaiting.get(i)) {
            wait.free(p);
        }
        batch.set_batchSize(productsWaiting.get(i).size()); //Since the batch is less than the standard we need to change it to what ever we are releasing
        return; // we exit the loop since we have released a batch
    } 
    
    

    You create a map to store the products in a list based on their sp number. If at any time you find you have enough units to create a batch we stop and release them from the wait block.

    If we get to the end of the for loop and we did not have any sp number that had enough units to make up a whole batch we simple release what we have.

    In this example you will need to click the button every time to release a batch, alternatively you can add the batch check function call to the on release code of the batch object. This will all happen sequentially, but at the same time step

    enter image description here