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.
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:
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):
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