PennController for IBEX › Forums › Support › Pseudorandomization with no two items of the same type in a row
Tagged: pseudorandomization
- This topic has 2 replies, 2 voices, and was last updated 1 year, 8 months ago by Dari.
-
AuthorPosts
-
January 10, 2023 at 7:52 am #9839DariParticipant
Hi everybody,
We need some advice on how to get a pseudorandomization that ensures that no two items directly follow each other.
In our experiment, we have three different sets of items A, B and C (24 each), one set of 24 fillers D (24) and 8 catch trials E. The items also serve as fillers for each other. We would like ensure that we never get AA, BB or CC (or more) in our sequence, but that it is at least ABA or ADA etc.
We tried to use “rshuffle” and “shuffle (randomize ())”:
Sequence(rshuffle("A", "B", "C", "D", "E"), SendResults(), "end")
This works in general, but it has the unwanted consequence that we have “static patterns” in our sequence that occur repeatedly in our sequence, like ABC in ABCDABCEABC.We also tried to use the function “RandomizeNoMoreThan()” (from this post) with n = 1, but it seems to get stuck in an endless loop whenever we have more than about 10 items in our csv files:
Sequence(randomizeNoMoreThan(anyOf("A", "B", "C", "D", "E", "F"),1)
However, logically, it should be possible to get a sequence where each type of stimulus occurs only once.Do you have any idea how we could a) avoid the static patterns in our sequence or b) change “RandomizeNoMoreThan” so that it works with n = 1 for more than 10 items?
Thanks a lot in advance!
DariJanuary 11, 2023 at 6:45 pm #9840JeremyKeymasterHi Dari,
The method used by the function in that post is too brute force to efficiently return a sequence every time the experiment is run
Use this instead:
function rnmt(toFill,fillFrom,n){ if (fillFrom.length<1) return toFill; let lst = toFill[toFill.length-1], nxt = fillFrom[0]; if (toFill.length>=n) { if (nxt.type == lst.type) { let lstN = 0; for (let i=toFill.length-1; i>=0 && toFill[i].type==lst.type; i--) lstN += 1; if (lstN>=n) { for (let i=0; i<fillFrom.length && nxt.type==lst.type; i++) { fillFrom = [...fillFrom.slice(1,),fillFrom[0]]; nxt = fillFrom[0]; } if (nxt.type==lst.type) return false; } } } return rnmt([...toFill,nxt],fillFrom.slice(1,),n); } function RandomizeNoMoreThan(predicate,n) { this.args = [predicate]; this.run = function(arrays) { let ret = false; while (!ret){ fisherYates(arrays[0]); ret = rnmt([],[...arrays[0]],n); } return ret }; } function randomizeNoMoreThan(predicate, n) { return new RandomizeNoMoreThan(predicate,n); }
Jeremy
January 12, 2023 at 3:22 am #9841DariParticipantHi Jeremy,
Thank you very much for the new function (which works perfectly) and for making our team very happy today! 🙂
All the best,
Dari -
AuthorPosts
- You must be logged in to reply to this topic.