question

Lorenz N avatar image
0 Likes"
Lorenz N asked Matthew Gillespie answered

How do you create a dynamic batch size with a min and max?

sample-batching-model.fsm

I have a system that I am trying to model in Flexsim HC with items. In this process I have lab samples that randomly enter the system. These get processed in a machine in batches. The max batch is 21. So the samples will wait until the batch sized is reached.

After a set amount of wait time, the samples will proceed forward. However, the machine has a minimum batch size that it can not go under, 14. Additional information is that the first machine only pulls on Mon and Wed at around 13:00. I do this by using a schedule. So there is a period before each scheduled pull that the queue can build up. So at that pull time 3 things could happen. Nothing, it pulls the 21 Batch, or the Max Wait Time has occured so it pulls 14 Batch.


Short version: How do I dynamically change the batch size from 21 to 14 after set Max Wait Time but then go back to the default 21 until such time is passed again?

FlexSim HC 5.3.10
batchbatchingbatch sizehealthcare hc 5queue batch size
capture.png (6.5 KiB)
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Matthew Gillespie avatar image
1 Like"
Matthew Gillespie answered

Here's a version of your model that I think is doing what you want: dynamicbatch.fsm

The code is a little complicated, but we have to make do with what we have in this old version of FlexSim. This would be significantly easier in FlexSim 19.2.

I assigned several labels to ItemQueuing1 and then reference those label values in the On Entry and On End Collecting triggers.

On Entry

The On Entry trigger does several things. When the first item of a batch enters it resets the batch size to be the object's max batch size. If the entering item is the last one needed for a minimum batch size it starts a max wait timer (which will call the On End Collecting trigger) and sets the time to be the max dwell time minus the amount of time the first item has been waiting. Finally, if the item entering is the last one needed for a full max batch it ends any waiting max wait time timers.

int curContent = content(current);
int maxBatch = getlabel(current, "MaxBatch");
int minBatch = getlabel(current, "MinBatch");

if (curContent == 1) {
	setlabel(current, "StartDwellTime", time());
	setvarnum(current, "batchsize", maxBatch);
}

else if(curContent == minBatch) {	
	double startTime = getlabel(current, "StartDwellTime");
	double maxDwell = getlabel(current, "MaxDwellTime");
	double dwellTime = time() - startTime;


	createevent(current, maxof(0, maxDwell - dwellTime), EVENT_ENDWAITTIME, "end max wait time", first(current));	
}

else if(curContent == maxBatch) {
	destroyeventsofobject(current, 0,EVENT_ENDWAITTIME);	
}

On End Collecting

This trigger updates the object's batchsize variable so that partial (less than the maximum size) can be released:

int minBatch = getlabel(current, "MinBatch");
int maxBatch = getlabel(current, "MaxBatch");

setvarnum(current, "batchsize", minof(maxBatch, maxof(batchsize, minBatch)));	

dynamicbatch.fsm (54.6 KiB)
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

tannerp avatar image
0 Likes"
tannerp answered Cliff King edited

Hi @Lorenz N,

Sorry for the delayed reply to your question. You can use the following code on a trigger however you deem most effective in your model to dynamically change the batch size. I don't quite know what your schedule is like, otherwise I would have updated your model. Hopefully this helps!

setvarnum(node("NameOfQueue",model()), "batchsize",21);
· 5
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Lorenz N avatar image Lorenz N commented ·

@Tanner Poulton This seems very helpful on putting it on a trigger. I have read other questions and documents mentioning this method. The piece that is missing would be the timing issue. From my limited understanding it would go somewhat like this. I have the general idea of the structure of the coding but not the actual language or script.

if(max(ListOfWaitTimesInQueue)>some_time_variable)
	then{
		setvarnum(node("NameOfQueue",model()), "batchsize",14);
	}
	else{
		setvarnum(node("NameOfQueue",model()), "batchsize",21);
	}<br>

From my understanding of triggers it only activates the script when that event happens. i.e. entering or leaving. Would OnReset run it every once in awhile? Or would I need to make some other location where I make a while loop and some how make it pause every X minutes before running again?

0 Likes 0 ·
tannerp avatar image tannerp Lorenz N commented ·

The structure of that code looks good. Unfortunately, OnReset would only run the script when the model is reset, but I'm sure we can find a good place for it somewhere in the model.

Maybe the better option would be to manually release a batch rather than temporarily change the batch size. That way, the batch is released using the proper algorithms at the correct time.

I'm not as familiar with Healthcare, but @Matthew Gillespie @Cliff King do you have ideas for a trigger location?

0 Likes 0 ·
Lorenz N avatar image Lorenz N tannerp commented ·

Now that I gave it some more thought my structure of the code needs to be different for my needs. This should not change the question though of where to put this trigger.

if(content(NameOfQueue)>=21)
    then{
        setvarnum(node("NameOfQueue",model()), "batchsize",21);
    }
    else{
        if(content("NameofQueue")<21 and content("NameofQueue")>=14  	and max(ListOfWaitTimesInQueue)>some_time_variable)
            then{
              setvarnum(node("NameOfQueue",model()), "batchsize",content(NameOfQueue));
            }
            else{
              setvarnum(node("NameOfQueue",model()), "batchsize",21);
            }    
    }
1 Like 1 ·
Show more comments