package Ġmodels . pred ator Pre y . discrete Event Model Ċ Ċ import Ġde sel by . std . extensions . next Po isson Ċ import Ġmodels . pred ator Pre y . Params Ċ import Ġorg . apache . commons . math 3 . random . M ers enne Tw ister Ċ import Ġjava . util .* Ċ import Ġkotlin . collections . ArrayList Ċ import Ġkotlin . math . max Ċ Ċ open Ġclass ĠSimulation Ġ{ Ċ // ĠĠĠ Ġcompanion Ġobject Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġconst Ġval ĠGR ID SIZE Ġ= Ġ 3 Ċ // ĠĠĠĠĠĠĠ Ġconst Ġval ĠGR ID SIZ ES Q Ġ= ĠGR ID SIZE * ĠGR ID SIZE Ċ // ĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠEvent ( val Ġtime : ĠDouble , Ġval Ġagent : ĠAgent ) Ġ: ĠComparable < Event > Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcompare To ( other : ĠEvent ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtime . compareTo ( other . time ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġif ( dt Ġ== Ġ 0 ) Ġ{ Ċ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTODO (" dist ingu ish Ġequal Ġtime Ġevents ") Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġd pos Ġ= Ġagent . id . compareTo ( other . agent . id ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( d pos Ġ== Ġ 0 ) Ġreturn Ġ( agent Ġis ĠPred ator ). compareTo ( other . agent Ġis ĠPred ator ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġd pos Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdt ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġposition Index : ĠArray < ArrayList < Agent >> ĊĠĠĠ Ġval Ġevent Queue Ġ= ĠTree Set < Event >() ĊĠĠĠ Ġvar Ġtime Ġ= Ġ 0 . 0 ĊĠĠĠ Ġval Ġrand Ġ= ĠM ers enne Tw ister () ĊĠĠĠ Ġval Ġparams : ĠParams ĊĠĠĠ Ġval Ġagents : ĠSequence < Agent > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġevent Queue . as Sequence (). map Ġ{ Ġit . agent Ġ} Ċ Ċ // ĠĠĠ Ġconstructor () Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġposition Index Ġ= ĠArray ( GRID SIZ ES Q ) Ġ{ ArrayList < Agent >() } Ċ // ĠĠĠĠĠĠĠ Ġgp (" set Ġlin etype Ġ 1 Ġlc Ġ' red '") Ċ // ĠĠĠĠĠĠĠ Ġgp (" set Ġlin etype Ġ 2 Ġlc Ġ' blue '") Ċ // ĠĠĠ Ġ} Ċ // Ċ // ĠĠĠ Ġconstructor ( n Pred ator : ĠInt , Ġn Pre y : ĠInt ) Ġ: Ġthis () Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġfor ( i Ġin Ġ 1 .. n Pred ator ) Ġ Ġadd ( Pred ator ( rand . nextInt ( GRID SIZE ), Ġrand . nextInt ( GRID SIZE ))) Ċ // ĠĠĠĠĠĠĠ Ġfor ( i Ġin Ġ 1 .. n Pre y ) ĠĠĠĠĠ Ġadd ( Pre y ( rand . nextInt ( GRID SIZE ), Ġrand . nextInt ( GRID SIZE ))) Ċ // ĠĠĠ Ġ} ĊĊĠĠĠ Ġconstructor ( params : ĠParams ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . params Ġ= Ġparams ĊĠĠĠĠĠĠĠ Ġposition Index Ġ= ĠArray ( params . GRID SIZ ES Q ) Ġ{ ArrayList < Agent >() } ĊĠĠĠĠĠĠĠ Ġval Ġn Pred ator Ġ= Ġrand . next Po isson ( params . lambda Pred Ġ* Ġparams . GRID SIZ ES Q ) ĊĠĠĠĠĠĠĠ Ġval Ġn Pre y Ġ= Ġrand . next Po isson ( params . lambda Pre y Ġ* Ġparams . GRID SIZ ES Q ) ĊĠĠĠĠĠĠĠ Ġfor ( i Ġin Ġ 1 .. n Pred ator ) Ġ Ġadd ( Pred ator ( rand . nextInt ( params . GRID SIZE ), Ġrand . nextInt ( params . GRID SIZE ), Ġparams . GRID SIZE )) ĊĠĠĠĠĠĠĠ Ġfor ( i Ġin Ġ 1 .. n Pre y ) ĠĠĠĠĠ Ġadd ( Pre y ( rand . nextInt ( params . GRID SIZE ), Ġrand . nextInt ( params . GRID SIZE ), Ġparams . GRID SIZE )) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġschedule ( event : ĠEvent ) Ġ= Ġevent Queue . add ( event ) ĊĊĠĠĠ Ġfun Ġschedule ( time : ĠDouble , Ġagent : ĠAgent ): ĠEvent Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Ġ= ĠEvent ( time , Ġagent ) ĊĠĠĠĠĠĠĠ Ġevent Queue . add ( event ) ĊĠĠĠĠĠĠĠ Ġreturn Ġevent ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove ( event : ĠEvent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġevent Queue . remove ( event ) Ċ // ĠĠĠĠĠĠĠ Ġevent . agent . next Event Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġnext Event () Ġ= Ġevent Queue . poll First () ĊĊĠĠĠ Ġfun Ġagents At ( i : ĠInt , Ġj : ĠInt ) Ġ= Ġagents At (( i + params . GRID SIZE ). rem ( params . GRID SIZE )+( j + params . GRID SIZE ). rem ( params . GRID SIZE )* params . GRID SIZE ) ĊĊĠĠĠ Ġfun Ġagents At ( id : ĠInt ) Ġ= Ġposition Index [ id ] ĊĊĠĠĠ Ġfun Ġcount ( agent : ĠAgent ) Ġ= Ġagents At ( agent . id ). count Ġ{ Ġit :: class Ġ== Ġagent :: class } ĊĊĠĠĠ Ġfun Ġadd ( agent : ĠAgent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġagents At ( agent . id ). add ( agent ) ĊĠĠĠĠĠĠĠ Ġagent . schedule Next Event ( this ) ĊĠĠĠĠĠĠĠ Ġre Schedule ( agent . sphere Of In fluence ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove ( agent Ġ: ĠAgent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġremoved OK Ġ= Ġagents At ( agent . id ). remove ( agent ) ĊĠĠĠĠĠĠĠ Ġif (! removed OK ) Ġprintln (" problems Ġremoving ") ĊĠĠĠĠĠĠĠ Ġagent . next Event ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremove ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġre Schedule ( agent . sphere Of In fluence ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġre Schedule ( sphere Of In fluence : ĠList < Int >) Ġ{ ĊĠĠĠĠĠĠĠ Ġsphere Of In fluence . forEach Ġ{ Ġinflu enced Position Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġagents At ( in flu enced Position ). forEach Ġ{ Ġinflu enced Agent Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinflu enced Agent . next Event ?. let Ġ{ Ġremove ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinflu enced Agent . schedule Next Event ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġis Cons istent (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġconsistent Ġ= Ġtrue Ċ // ĠĠĠĠĠĠĠ Ġposition Index . forEach Ġ{ Ġ( pos , Ġagents ) Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġagents . forEach Ġ{ Ġagent Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( agent . id Ġ!= Ġpos ) Ġprintln (" position Ġindex Ġis Ġinconsistent !") Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġevent Queue . forEach Ġ{ Ġevent Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( position Index [ event . agent . id ]?. contains ( event . agent ) Ġ!= Ġtrue ) Ġprintln (" agent Ġin Ġevent Ġqueue Ġis Ġnot Ġin Ġposition Ġindex ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( event . agent . next Event Ġ!== Ġevent ) Ġprintln (" agent Ġnext Event Ġis Ġnot Ġconsistent ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġconsistent ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġaverage Multiplicity (): ĠDouble Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġposition Index . as Sequence (). flatMap Ġ{ Ġagents Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpreds = Ġagents . as Sequence (). count Ġ{ Ġit Ġis ĠPred ator Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpre y Ġ= Ġagents . as Sequence (). count Ġ{ Ġit Ġis ĠPre y Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsequence Of ( preds , Ġpre y ) ĊĠĠĠĠĠĠĠ Ġ}. filter Ġ{ it Ġ!= Ġ 0 }. average () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġmultip licity (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġposition Index . as Sequence (). map Ġ{ Ġagents Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpreds = Ġagents . as Sequence (). count Ġ{ Ġit Ġis ĠPred ator Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpre y Ġ= Ġagents . as Sequence (). count Ġ{ Ġit Ġis ĠPre y Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax ( preds , pre y ) ĊĠĠĠĠĠĠĠ Ġ}. max () ?: 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpred ator Multiplicity (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġposition Index . as Sequence (). map Ġ{ Ġagents Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġagents . as Sequence (). count Ġ{ Ġit Ġis ĠPred ator Ġ} ĊĠĠĠĠĠĠĠ Ġ}. max () ?: 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpre y Multiplicity (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġposition Index . as Sequence (). map Ġ{ Ġagents Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġagents . as Sequence (). count Ġ{ Ġit Ġis ĠPre y Ġ} ĊĠĠĠĠĠĠĠ Ġ}. max () ?: 0 ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġn Agents () Ġ= Ġevent Queue . size ĊĊĠĠĠ Ġfun Ġsimulate ( T : ĠDouble ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠendTime Ġ= Ġtime Ġ+ ĠT ĊĠĠĠĠĠĠĠ Ġwhile ( time Ġ< ĠendTime ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Ġ= Ġnext Event () ?: return ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( event . time Ġ< ĠendTime ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime Ġ= Ġevent . time ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent . agent . execute Event ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime Ġ= ĠendTime ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent Queue . add ( event ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġreturns Ġa Ġmap Ġof Ġagent Ġto Ġnumber Ob served ĊĠĠĠ Ġfun Ġobserve ( p Ob serve : ĠDouble ) Ġ: ĠOb servation Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġagents Ġ= ĠOb servation () ĊĠĠĠĠĠĠĠ Ġevent Queue . forEach Ġ{ Ġ(_, agent ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcopied Agent Ġ= Ġagent . copy () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġagents . real . merge ( copied Agent , Ġ 1 , Int :: plus ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( rand . next Double () Ġ< Ġp Ob serve ) Ġagents . observed . merge ( copied Agent , Ġ 1 , Int :: plus ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġagents ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġreturns Ġa Ġlist Ġof Ġobservations . ĊĠĠĠ Ġ// ĠEach Ġmember Ġis Ġa Ġmap Ġfrom Ġagent Ġto Ġnumber Ġobserved ĊĠĠĠ Ġfun Ġgenerate Ob servations ( p Ob serve : ĠDouble , Ġn Ob servations : ĠInt , Ġobservation Interval : ĠDouble ): ĠList < Observation > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġobservations Ġ= ĠArrayList < Observation >() ĊĠĠĠĠĠĠĠ Ġfor ( i Ġin Ġ 1 .. n Ob servations ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsimulate ( observation Interval ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobservations . add ( observe ( p Ob serve )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġobservations ĊĠĠĠ Ġ} Ċ }