//This file contains the source code of the PAIR simulation as described in the paper: // //Westera, W. (2007) Peer-Allocated Instant Response (PAIR): Computational Allocation of Peer Tutors in Learning Communities, JOURNAL OF ARTIFICIAL SOCIETIES AND SOCIAL SIMULATION, http://jasss.soc.surrey.ac.uk/ // //The paper proposes a computational model for the allocation of fleeting peer tutors in a community of learners: a student’s call for support is evaluated by the model in order to allocate the most appropriate peer tutor. The PAIR-model has been implemented in Scilab-4.0, copyright (c) 1989-2006, Consortium Scilab (INRIA, ENPC) (http://www.scilab.org). This file contains 2 routines: //-One routine defines the curriculum and the student population //-One routine implements the simulation model //To run the simulation the textual code in this file should be loaded into the scilab editor and saved as *.sci file. //Download open source Scilab.-4.1 software at http://www.scilab.org/ //ONLY FEW PARAMETERS ARE DISPLAYED AS OUTPUT; YET ALL PARAMETERS ARE AVAILABLE FOR OUTPUT. JUST ENTER THE PARAMETER NAME INTO THE SCILAB CONSOLE. /////////////////////////////////////////////////////////////////////////////////// // CREATING A CURRICULUM AND STUDENT POPULATION //After running this module data should be saved in order to allow multiple simulations with //the same generated curriculum clear //Description of the domain Ndomain=20; //20 modules Domainload=300; //units of time to complete the whole course Nstudents=100 //number of students //Mprerequisite(i) is prior knowledge modules needed //default prior knowledge=0 clear Mprerequisite for i=1:Ndomain,Mprerequisite(i)=0; end; Mprerequisite; //Msize(i) module size; random trial in normal distribution clear Msize SDsize=1/3; //standard deviation module size for i=1:Ndomain, Msize(i)=grand(1,1,'nor',1,SDsize)*Domainload/Ndomain; end //the function grand(1,1,’nor’,1,SDsize) produces random number centered around value 1 Totalsize=sum(Msize); //calibrate for i=1:Ndomain, Msize(i)=Msize(i)*Domainload/Totalsize; end Msize;// Msize(i) yields size of module i //Mcomplexity(i) is complexity of module i; random trial in normal distribution SDcomplexity=1/6; clear Mcomplexity for i=1:Ndomain, Mcomplexity(i)=grand(1,1,'nor',1,SDcomplexity); end Mcomplexity; // Predrequest (i) is predisposition of student i for requesting support clear Predrequest; Sdpredrequest=1/6; for i=1:Nstudents, Predrequest(i)=grand(1,1,'nor',1,Sdpredrequest); end Predrequest; // Predspeed(i) denotes learning capabilities (speed of learning) of student i clear Predspeed SDpredspeed=1/6; for i=1:Nstudents, Predspeed(i)=grand(1,1,'nor',1,SDpredspeed); end Predspeed; // Predquality(i) denotes tutoring capabilities of student i; //no different support types implemented so far clear Predquality SDpredtutqual=1/6; for i=1:Nstudents, Predquality(i)=grand(1,1,'nor',1,SDpredtutqual); end Predquality; //Prior knowledge //Prior(i) prior knowledge fraction of student i // Priorperf(i,j): prior knowledge performance factor of student i in module j //1. calculate overall prior knowledge fraction for each student clear Prior f=0.10; Sdprior=f/6; for i=1:Nstudents, Prior(i)=grand(1,1,'nor',f,Sdprior); end //calibrate Y=sum(Prior)/Nstudents; Prior=f/Y*Prior; Prior; //2. random distribution of prior knowledge over domains for each student clear Priorperf for i = 1:Nstudents, for j = 1:Ndomain, Priorperf(i,j) = 2*Prior(i)*rand(1,1); end;end //Priorperf uncalibrated prior knowledge fractions of student i in domain j //calibrate Priorperf; Y=sum(Priorperf,'c')/Ndomain; for i=1:Nstudents, for j = 1:Ndomain, Priorperf(i,j) = 1/(1-Priorperf(i,j)*Prior(i)/Y(i));end, end //Timeavail(i) is lack of time of student i clear Timeavail Sdtime=1/6; for i=1:Nstudents, Timeavail(i)=grand(1,1,'nor',1,Sdtime); end Timeavail; // Moduleroutes(i,m) gives m-th module of student i //Moduleroute(m) the same for all students for m=1:Ndomain, Route(m)=m; end Moduleroute=samwr(Ndomain, 1, Route); //random sequence //initialise module routes for each student i clear Moduleroutes ////USE NEXT LINE FOR UNIFORM MODULE ROUTE //for i=1:Nstudents, for m = 1:Ndomain, Moduleroutes(i,m)=Moduleroute(m); end; end//fixed route //// ////USE NEXT LINE FOR PERSONALISED MODULE ROUTES for i=1:Nstudents, Route1=samwr(Ndomain, 1, Route); for m = 1:Ndomain, //// Moduleroutes(i,m)=Route1(m); end; end //random routes clear Route clear Route1 Moduleroutes; //(i,m)= is m-th module of student i for i=1:Nstudents, Modulecounter(i)=1; CM(i)=Moduleroute(1); end //Modulecounter(i) denotes the progress of student i in the moduleroute //CM(i) is current module of student i ///////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////// // SIMULATION FOR LEARNING PROGRESS AND TUTOR ALLOCATION // It requires well defined domain data as calculated above //SET INITIAL DATA Crossover1=1 //switches the cross-over filter, 0 = off, 1 is on Crossover2=1 //switches the cross-over filter, 0 = off, 1 is on Overload1=125 // Relfactor1=0 // toggles between relative and absolute overload: =1 if relative, 0 if absolute Overload2=125 // Relfactor2=0 // toggles between relative and absolute overload: =1 if relative, 0 if absolute Deadtime=2 // the time span that tutors are excluded after a support activity Timemax=200;//simulation time "running" //SET uniform Modulelack=1; clear Completemodule clear Competences clear Modulelack; clear Startmodule for i=1:Nstudents, for m = 1:Ndomain, Modulelack(i,m)=1; Startmodule(i,m)=0; Completemodule(i,m)=0; Competences(i,m)=0; end; end //Clear all support event data clear Eventquality; //the support quality as assigned by the receiver clear Eventselfquality; //the support quality as assigned by the provider clear Ntutoringtotal; // number of tutoring acts of student i clear Ntutoring1; // number of tutoring acts of student i at module m of type 1 clear Ntutoring2; // number of tutoring acts of student i at module m of type 2 clear Ntutoring3; // number of tutoring acts of student i at module m of type 3 clear Avselfscore1; //average self-assigned score of tutor i at module m of type 1 clear Avselfscore2; //average self-assigned score of tutor i at module m of type 2 clear Avselfscore3; //average self-assigned score of tutor i at module m of type 3 clear Avscore1; //average requester-assigned score of tutor i at module m of type 1 clear Avscore2; //average requester-assigned score of tutor i at module m of type 2 clear Avscore3; //average requester-assigned score of tutor i at module m of type 3 clear NrequestTotal; //number of requests of student i clear Nrequest1; //number of requests of student i at module m of type 1 clear Nrequest2; //number of requests of student i at module m of type 2 clear Nrequest3; //number of requests of student i at module m of type 3 clear Tutor; clear SCORE1 for i=1:Nstudents, Ntutoringtotal(i)=0; NrequestTotal(i)=0; Deficit(i)=0; end for i=1:Nstudents, for m = 1:Ndomain, Supportnumber(i,m)=0; AVselfscore(i,m)=0; end; end for i=1:7 Filter(i)=0; end clear FILTERROUTE clear proxfilter clear complfilter clear uniformfilter clear favourfilter clear Eventstart clear Eventmatch clear Finish;//students' finalisation times -all modules clear Route clear rundata clear Qualityfilter clear Economyfilter // START RUN Time=0; Threstrans=1.0; //module transition threshold; define progress clear Startmodule; for i=1:Nstudents, Finish(i)=0; Modulecounter(i)=1; CM(i)=Moduleroute(1); end for i=1:Nstudents, A=CM(i); Startmodule(i,A)=1; end Event=0;//Initialise support event index SDscore=1/6; Tutor(1)=0; //needed for temporary initiation Tdisplay=50;//needed as a console indicator during running for Time=1:Timemax //DISPLAY SIMULATION PROGRESS if Time==Tdisplay Time// displays time progress Tdisplay=Tdisplay+50; end // CALCULATE MODULE TRANSITION for i=1:Nstudents, A=CM(i); Moduletrans=(Time-Startmodule(i,A))/Msize(A)/Mcomplexity(A)*Predspeed(i)*Priorperf(i)*Timeavail(i)*Modulelack(i,A); //STOP CONDITION for learner i if (Modulecounter(i)<(Ndomain+1)); if Moduletrans>Threstrans Completemodule(i,A)=Time; Competences(i,A)=round(7*grand(1,1,'nor',1,SDscore)); if Competences(i,A)>10; Competences(i,A)=10;end Modulecounter(i)=Modulecounter(i)+1; if (Modulecounter(i)<(Ndomain+1)); A1=Modulecounter(i); B=Moduleroutes(i,A1); CM(i)=B; Startmodule(i,B)=Time; else //student has completed final module and will not call for support Startmodule(Ndomain+1)=Time; Finish(i)=Time; end end end //CREATE support request of student i at time T M=CM(i); // current module Eventtrigger=rand(1,1)* Predrequest(i)/Priorperf(i,M)/Predspeed(i); Eventthresh=0.6; if Finish(i)>0 //student(i) has completed all modules else if Eventtrigger>Eventthresh //create event Event=Event+1; Requester(Event)=i; NrequestTotal(i)=NrequestTotal(i)+1; Deficit(i)=Ntutoringtotal(i)-NrequestTotal(i);//nett overload Eventstart(Event)=Time; Eventend(Event)=Eventstart(Event)+5*round(rand(1,1)); Supporttype(Event)=round(5*rand(1,1));//create supporttype //ALLOCATE FILTERROUTE(Event)=0; proxfilter(Event)=0; complfilter(Event)=0; uniformfilter(Event)=0; favourfilter(Event)=0; // EXCLUDE RECENT PEER TUTORS TIMEREST=Deadtime; // minimum peer tutor dead time clear Excludedtutor Excludedtutor=[]; if Event>1 hist=Time-TIMEREST; if hist<=0 hist=0; end ev=find(Eventstart>hist); //contains the Events in recent history if ev~=[] Eventmax=min(ev);//earliest event to exclude inn=0; for ee=Eventmax:(Event-1) if Tutor(ee)==Nstudents+1 else if Tutor(ee)==0 else inn=inn+1; Excludedtutor(inn)=Tutor(ee);//correction artefact end end end end Excludedtutor=sort(Excludedtutor); else Excludedtutor=[]; end Excludedtutor; if (Nstudents-1-length(Excludedtutor))<0 NORM=1; else NUMB=(Nstudents-1-length(Excludedtutor));//defines upper limit of filtering power NORM=sqrt(NUMB);//defines upper limit of filtering power ANORM=NORM; if ANORM==0 NORM=1; end//exception end clear Match; clear candidates; //APPLY PROXIMITY FILTER clear minimum //determine earliest start time "minstart" of module M: scaling parameter minstart=Time; for LI=1:Nstudents if Startmodule(LI,M)==0 else if minstart>Startmodule(LI,M) minstart=Startmodule(LI,M); end end end //determine proximity score for LI=1:Nstudents SCORE(LI)=(Time-Startmodule(LI,M)+1)/(Time-minstart+1);///normalised quality score (proximity) if CM(LI)~=M SCORE(LI)=0; end clear X1 ///leave recent tutors alone (4 lines) X1=find(Excludedtutor==LI,1); if X1~=[] SCORE(LI)=0; end if Finish(LI)>0 SCORE(LI)=0;///exclude tutors that have completed all modules end end SCORE(i)=0;//exclude self clear SC; SC=sort(SCORE); // if SC(1)==0 QPROX=0; //"proximity filter failed" clear candidates candidates=[Nstudents+1]; //ALLOCATION OF TUTOR Nstudents+1 SIGNIFIES ALLOCATION OF TEACHER L=0; else clear nn; clear prevnn; for k=1:Nstudents //calculate filter cross-over point; note k<>student-id if SC(k)==0 break, end ind=k; nn=find(SC>=SC(k)); if length(nn)>=NORM break, end end if ind>1 //check previous cross-over point prevnn=find(SC>=SC(ind-1)); d1=abs((length(prevnn)-NORM)/NORM)-abs((length(nn)-NORM)/NORM);///RELATIVE DISTANCE if d1<0 ind=ind-1; end end CROSS=SC(ind); clear candidates candidates=[]; //SWITCH ON/OFF CROSS OVER BY SETTING CROSS TO 0 OR 1 if Crossover1==0 CROSS=0; candidates=find(SCORE>CROSS); else candidates=find(SCORE>=CROSS); end L=length(candidates); if L0 SCORE(LI)=0;///exclude tutors that have completed all modules end end SCORE(i)=0;//exclude self clear SC; SC=sort(SCORE); // if SC(1)==0 QCOMPL=0;//"completion filter failed" candidates=[Nstudents+1];//allocate teacher FILTERROUTE(Event)=1; L=0; else clear nn; clear prevnn; for k=1:Nstudents //calculate filter cross-over point; note k<>student-id if SC(k)==0 break, end ind=k; nn=find(SC>=SC(k)); if length(nn)>=NORM break, end end if ind>1 //check previous cross-over point prevnn=find(SC>=SC(ind-1)); d1=abs((length(prevnn)-NORM)/NORM)-abs((length(nn)-NORM)/NORM); //RELATIVE DISTANCE if d1<0 ind=ind-1; CROSS=SC(ind); end end CROSS=SC(ind); clear candidates candidates=[]; //SWITCH ON/OFF CROSS OVER BY SETTING CROSS=1 OR 0 if Crossover2==0 CROSS=0; candidates=find(SCORE>CROSS); else candidates=find(SCORE>=CROSS); end L=length(candidates); end if L==0 complfilter(Event)=0; FILTERROUTE(Event)=1; else complfilter(Event)=1; end end //END COMPLETION FILTER //CALCULATE QUALITY TRANSMISSION RATE //Started with NORM*NORM number candidatesin , ended with L candidates out //Filter quality factor=1 for optimum selection (SQRT(N)) if NORM==0 QQUALITY=-100;// when no input else clear pr pr=binomial(1/NORM,NUMB+3); QQUALITY=pr(L+1)/max(pr);//BINOMIAL FILTER PERFORMANCE //Filter quality transmission =1 for optimum selection (SQRT(N)) end LQOUT=L;//store qualityout candidates;// CONTAINS QUALITY PEERS ///ECONOMY FILTERS if L~=0 //////////APPLY FAVOUR FILTER RELFACTORF=Relfactor1;///=1 if relative, 0 if absolute Overload=Overload1; // number; to exclude peers with high deficits (high number of supports) Overloadtemp=Overload; for LI=1:Nstudents Match(LI)=0; end for k=1:L cand=candidates(k); ///IF RELATIVE if RELFACTORF==1; Overload=Overloadtemp/100*(Ntutoringtotal(cand)+1); end//AVOID INDEFINITE /// if (Overload+ NrequestTotal(cand))==0 Match(cand)=0; else Match(cand)=SCORE(cand)*(Overload- Ntutoringtotal(cand)+NrequestTotal(cand))/(Overload+ NrequestTotal(cand)); end end Maximum=max(Match); if Maximum>0 EconomyResult=find(Match==Maximum,L); //filter succeeded favourfilter(Event)=1; else EconomyResult=[]; //filter failed favourfilter(Event)=0; end // [Match Ntutoringtotal Deficit] // [EconomyResult] Numbertutors=length(EconomyResult); //Number of favour selected peers RELFACTORU=Relfactor2; OverloadU=Overload2;//absolute uniformity tolerance OverloadUtemp=OverloadU; if Numbertutors==0 ////APPLY UNIFORMITY FILTER LIKEWISE clear averagetutload clear tempa tempa= find(Tutor==Nstudents+1); averagetutload=(Event-length(tempa))/Nstudents; //average tutor load for LI=1:Nstudents Match(LI)=0; end for k=1:L ///IF RELATIVE if RELFACTORU==1; OverloadU=OverloadUtemp/100*(Ntutoringtotal(cand)+1); end//avoid indefinite /// cand=candidates(k); Match(cand)=SCORE(cand)*(OverloadU-Ntutoringtotal(cand)+averagetutload)/(OverloadU+averagetutload); if Deficit(cand)>OverloadU Match(cand)=0; "overload uniform"; end //EXCLUDE extreme supporters end Maximum=max(Match); // clear EconomyResult; if Maximum>0 EconomyResult=find(Match==Maximum,L); //filter succeeded uniformfilter(Event)=1; else EconomyResult=[]; //filter failed uniformfilter(Event)=0; end Numbertutors=length(EconomyResult); //Number of uniformity selected peers end else Numbertutors=0; EconomyResult=[]; uniformfilter(Event)=0; end //EconomyResult //CALCULATE ECONOMY FILTER TRANSMISSION //Started with LQOUT number candidates in , ended with Numbertutors candidates out //Filter economy transmission qfactor=1 for optimum selection (SQRT(N)) if LQOUT==0 QECONOMY=-100;//no input else clear pr pr=binomial(1/NORM,LQOUT+3); QECONOMY=pr(L+1)/max(pr);//BINOMIAL FILTER PERFORMANCE //Filter quality transmission =1 for optimum selection (SQRT(N)) end //FINAL Tutor allocation if Numbertutors==0 //ALLOCATION OF TEACHER //FILTERROUTE: SEE TABLE 1 IN PAPER MANUSCRIPT Tutor(Event)=Nstudents+1;//(AGAIN) if proxfilter(Event)==1 FILTERROUTE(Event)=6; end if complfilter(Event)==1 FILTERROUTE(Event)=11; end Maximum=0; elseif Numbertutors==1 then Tutor(Event)=EconomyResult(1); se=Tutor(Event); select [proxfilter(Event) complfilter(Event) favourfilter(Event) uniformfilter(Event)] case [1 0 1 0] then FILTERROUTE(Event)=2; case [1 0 0 1] then FILTERROUTE(Event)=4; case [0 1 1 0] then FILTERROUTE(Event)=7; case [0 1 0 1] then FILTERROUTE(Event)=9; end else //number of candidates L>1// random selection ind=1+floor(Numbertutors*(rand(1,1))); Tutor(Event)=EconomyResult(ind);//TUTOR ALLOCATION select [proxfilter(Event) complfilter(Event) favourfilter(Event) uniformfilter(Event)] case [1 0 1 0] then FILTERROUTE(Event)=3; case [1 0 0 1] then FILTERROUTE(Event)=4; case [0 1 1 0] then FILTERROUTE(Event)=5; case [0 1 0 1] then FILTERROUTE(Event)=10; end end ///END OF TUTOR ALLOCATION ROUTINE se=Tutor(Event); Qualityfilter(Event)=QQUALITY; Economyfilter(Event)=QECONOMY; Eventmatch(Event)=Maximum;///matching score of this events allocation TIJD=[Event i se]; if se