question

Justin Brozzo avatar image
3 Likes"
Justin Brozzo asked Jeff Nordgren commented

How do I sort through two queues before a combiner searching for matching item types. Making sure that the matches are available in both queues before allowing one to take its position at the combiner?

I am attempting to create a solution, where Queue9 and Queue6 will be searched would be searched making sure the match is available in both queues before one object assumes the position at the combiner.

Thank you

FlexSim 16.1.1
combinerqueue contentsort
· 3
5 |100000

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

Matt Long avatar image
1 Like"
Matt Long answered

If you don't mind a bit of code, the attached model matchingitemtypes.fsm uses the Pull logic on the combiner to pull two matching itemtypes from Queue6 and Queue9. When an item enters either of the queue's, the Pull Requirement is called. The code will check the opposite queue to see if there is a matching itemtype. If it finds one, it stores off the itemtype on a label and then pulls the item. This then causes the combiner to call the Pull Requirement on all of the waiting items. We then use the matchedItemType label to find the item we matched previously.

Here's what the code looks like in the Combiner's Pull Requirement:

  1. /**Matching Itemtypes*/
  2. int matchedItemType = getlabel(current, "matchedItemType");
  3. if (matchedItemType >= 0) {
  4. //We previously matched an item so pull the matching itemtype from the other queue
  5. if (getitemtype(item) == matchedItemType) {
  6. setlabel(current, "matchedItemType", -1);
  7. return 1;
  8. }
  9. return 0;
  10. }
  11.  
  12.  
  13. int type = getitemtype(item);
  14. //Search the opposite queue for the same itemtype
  15. int otherPort = port % 2 + 1; //Grab the other port rank so we look at the other queue
  16. treenode queue = inobject(current, otherPort);
  17. for (int i = 1; i <= content(queue); i++) {
  18. if (getitemtype(rank(queue, i)) == type) {
  19. //Found a matching itemtype, save the itemtype on a label
  20. setlabel(current, "matchedItemType", type);
  21. //Now pull the item that just entered the original queue
  22. return 1;
  23. }
  24. }
  25. //No matches, pull nothing
  26. return 0;

5 |100000

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

Joerg Vogel avatar image
2 Likes"
Joerg Vogel answered Joerg Vogel edited

Without testing it, I think a global list would do it. The two queues push their items to the list and the pull requirement of the combiner pulls the matching itemtypes from the list. The global list contains a variable of the queue the items stay, if you don't want to evaluate this information out of the item's reference.

5 |100000

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

Adrian Haws avatar image
0 Likes"
Adrian Haws answered Adrian Haws edited

Hi Justin,

This isn't the simplest thing to accomplish, but I created a sample model for a roundabout way to do this since the combiner really can't handle this kind of logic.

What I did is to first sort all flowitems that come through your first two queues by their itemtypes by sending each to a separate queue. Then the queue for each itemtype makes batches of two and sends the batch to one queue. This is the final queue before the combiner and has a max content of 2. This queue also makes batches of two. I made two connections from the final queue to the combiner so that it can join them. Even though it's not quite the same visually (and you'd have to add as many queues as you have itemtypes), it's probably the easiest way to perform this logic.

You will also want to set up the pull requirement in the final queue so that it doesn't always pull from the same queue. In this case I used the option "Round Robin If Available." Then a bit of code is necessary to make sure that the two flowitems are pulled from the same queue. Enter this in the OnEntry trigger of that queue:

  1. if (content(current) == 1) {
  2. for (int index = 1; index <= nrip(current); index++) {
  3. if (port != index) {
  4. closeoutput(inobject(current, index));
  5. }
  6. }
  7. }

Then in the OnExit trigger of the same queue enter the following:

  1. if (content(current) == 1) {
  2. for (int index = 1; index <= nrip(current); index++) {
  3. openoutput(inobject(current, index));
  4. }
  5. }


combiner-1.fsm (16.7 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.