0

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.

Jaco-Ben Vosloo
  • 3,770
  • 2
  • 16
  • 33

1 Answers1

1

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

Jaco-Ben Vosloo
  • 3,770
  • 2
  • 16
  • 33
  • 1
    You should be able to call the command `freeAll()` on the wait block and they will all be released. You will just need to also set the batch size equal to the number of items in the wait block before releasing `batch.set_batchSize(wait.size());` – Jaco-Ben Vosloo Aug 25 '21 at 07:44
  • Hello Jaco, I have another question. How could I batch different batch sizes depending on the sp? For example, if sp = 1, the batch size is 20, and if sp = 2, the batch size is 7, and so on. The batch size is fixed without releases, so the last for loop is omitted. Thanks a lot, and I appreciate it. – Mohamed Youssef Aug 25 '21 at 13:56
  • You can set up a map where you can look up the SP number and get the corresponding batch size `LinkedHashMap` start a new question for a more detailed answer and example. Although this is standard Java ;-) – Jaco-Ben Vosloo Aug 26 '21 at 05:55
  • Thanks, Jaco. I had started a new question here [link](https://stackoverflow.com/q/68926259/11858606), and I tried the solution of Felipe in the second question, but it didn't work with me. I'm pretty new to Java; that's one of the reasons. I want to ask you to have a look at the other question if you could help. Thanks a lot. – Mohamed Youssef Aug 26 '21 at 06:09