0

Using AnyLogic service block, I try to seize a resource set using a custom resource choice condition. My criteria for deciding which set to seize is a boolean parameter of the agent. Using the answers from this question I implemented the following code to seize the needed resource:

ResourcePool t_pool = (ResourcePool)pool;
// resource selection condition
if ( (t_pool == resourcePool1) && (agent.bool) ||
     (t_pool == resourcePool2) && (!agent.bool)){
    return true;
}
else {
    return false;
}

This works fine for alternative sets of one resource, however when my sets are composed of more than one resourcePool, the block is unable to seize the set.

For instance with two sets {commonResourcePool, resourcePool1} and {commonResourcePool, resourcePool2}, I checked the local variable pool and it only takes the value of the commonResourcePool. Switching the order of the pools did not help.

A solution I found was to use Seize/release blocks to manage the commonResourcePool. Would anyone have a more elegant solution, to access both pools using a local variable, chosing the one it selects for instance, or chosing directly one of the resource sets?

(I use AnyLogic PLE 8.4.0)

Expected result: seize the intended set according to the boolean value. Result obtained: not set is seized and the agent is blocked. Things I tried: Switch the order of pools in the set. Resulted in the same outcome: only the commonResourcePool is checked by local variable pool.

Modifications of the code : I tried to create a new set each time the block is reached, however I was not unable to create the set (ResourceSet does not exist). Code I tried looked like this:

    // create the two resource sets
    ResourceSet resourceSet1 = new ResourceSet();
    ResourceSet resourceSet2 = new ResourceSet();

    // customize the resource choice based on the agent parameter bool
    if (agent.bool.par_cancer) {
        resourceSet1.add(commonResourcePool);
        resourceSet1.add(resourcePool1);
        customizeResourceChoice(resourceSet1);
    } else if (!agent.bool) {
        resourceSet2.add(commonResourcePool);
        resourceSet2.add(resourcePool2);
        customizeResourceChoice(resourceSet2);
    } else {
        // handle invalid agent parameter value
    }

Thank you, Best regards

EDIT: Here is the dummy model created to reproduce the problem (the same problem appears with the original model). The function is called in this section of the service block. The code contained in the function is here. Sorry for not including these screenshots in the original post.

EDIT 2: The resource set settings.

  • Can you share screenshots of your model and where you're writing your code? It's hard to follow what you're currently doing and what the desired logic is – mczandrea Apr 05 '23 at 10:33
  • I edited the post to add several screenshots showing how this problem occurs. I hope it helps. – Jules Le Lay Apr 05 '23 at 13:13
  • Did you add the resource pools to the 'Resource sets' section of your Service block? You can only choose resources from a specific pool, if the Service (or Seize) block has the pool listed. Also, is your logic "if agent.bool is true, then use commonResourcePool or resourcePool1, else use commonResourcePool or resourcePool2"? Then your code could be much simpler, but I just want to make sure I understand your issue correctly – mczandrea Apr 05 '23 at 13:29
  • Also there's a typo in your `fct_resourceChoice`, I think you meant to write `resourcePool2` in the second row of your `if` condition :) – mczandrea Apr 05 '23 at 13:36
  • Indeed, it's a typo, it's corrected (and it didn't change the problem I'm having). – Jules Le Lay Apr 05 '23 at 13:47
  • Yes, I added the two resource sets in the service block. I would like to seize a resource from each of the pools of the set. For instance, if the boolean represents the nature of a product, I would like to seize a worker with a machine if bool is true, and if it is false, 1 worker and another machine. I add a screenshot of the resource set in the question. – Jules Le Lay Apr 05 '23 at 13:56

1 Answers1

0

I can see two solutions. The easier would be to have two different service blocks and a SelectOutput before them to choose which block to use, based on the value of agent.bool, somewhat like this: enter image description here

If you can't use separate Service blocks for some reason, then you need to set the resource sets programmatically. You need to call your function at the 'Resource sets' section of the block (You don't need to use the 'Customize resource choice' section in this case): enter image description here

The function selectResourceSet(boolean getType1) needs to return with type ResourcePool[][]. In this case the function body is the following, where getType1 is the boolean argument the function takes:

ResourcePool[][] choice = {{resourcePool2, commonResourcePool}};
if (getType1) choice[0][0] = resourcePool1;
return choice;

This only works if you need to seize 1-1 unit from each set, but I hope this helps you get to the correct solution

mczandrea
  • 463
  • 3
  • 12
  • Thank you very much, it helps a lot. As I need to seize 1 unit from each pool, I will implement the second solution you proposed. I did not know how to set the resource sets programmatically, thank you for sharing this solution and for you helpful comments. – Jules Le Lay Apr 06 '23 at 09:16