First and foremost, the distribution of information and knowledge should have something to do with learning. So I start with an exponential learning curve, which is easy to implement.
Definitions
Loading some Packages for easier Data management and Presentation of Results
A Population (Pop) with several Agents defined by ID’s
A value to add to the Knowledge. could be a scalar or e vector with the same length as the Population. if not defined 0 is used to add
A value to multiplie (fac) the Knowledge. could be a scalar or e vector with the same length as the Population. if not defined 1 is used for the multiplikation
optional for future implementations a name (Typ) for the specific Knowledge
Hints
The add operation is always used first!
If the Knowledge is not defined before it will be generated with the start value (add) and the multiplication with the value (fac)
Code
update_Knowledge<-function(Pop=Pop,Typ=FALSE,add=0,fac=1){Kname<-"Knowledge"if(Typ!=FALSE){Kname<-paste(Kname, Typ, sep ="_")}if(Kname%in%colnames(Pop)){Pop<-Pop%>%mutate(!!Kname:=(.data[[Kname]]+add)*fac)}else{Pop<-set_Knowledge(Pop =Pop, K =add, Typ =Typ)Pop<-Pop%>%mutate(!!Kname:=.data[[Kname]]*fac)}return(Pop)}
Output
Population with the defined Knowledge
Code
add<-seq_len(nA)/20fac<-seq_len(nA)/10Pop<-update_Knowledge( Pop =Pop, add =add)Pop<-update_Knowledge( Pop =Pop, Typ ="A", fac =fac)Pop<-update_Knowledge( Pop =Pop, Typ ="B", add =add, fac =fac)Pop
A Population (Pop) with several Agents defined by ID’s and StudyTime
A Time (dT) that should added.
Hints
If StudyTime isn’t defined in Population it will be initialising with dT
Code
update_StudyTime<-function(Pop=Pop,dT=TimeToAdd){STname<-"StudyTime"if(STname%in%colnames(Pop)){Pop<-Pop%>%mutate(!!STname:=.data[[STname]]+dT)}else{Pop<-set_StudyTime(Pop =Pop, ST =dT)}return(Pop)}
A Population (Pop) with several Agents defined by ID’s
A colname from the Population which should followed ver Time
optional parameter Sum. Ich Sum = 1 a mean and median is calculated for each Time
Code
get_Timeline<-function(TL=Timeline,Time=0,Pop=Pop,Info=name,Sum=0){TLadd<-tibble( ID =Pop[["ID"]], Time =Time,!!Info:=Pop[[Info]])if(Sum==1){Sumname1<-paste(Info,"mean", sep ="_")Sumname2<-paste(Info,"median", sep ="_")TLadd<-TLadd%>%mutate(!!Sumname1:=mean(Pop[[Info]], na.rm =TRUE),!!Sumname2:=median(Pop[[Info]], na.rm =TRUE))}if(Time==0){TL<-TLadd}else{TL<-bind_rows(TL, TLadd)}return(TL)}
Output
A Timeline in a long format
Code
Timeline<-get_Timeline( TL =Timeline, Time =0, Pop =Pop, Info ="Knowledge", Sum =1)Timeline<-get_Timeline( TL =Timeline, Time =1, Pop =Pop, Info ="Knowledge", Sum =1)Timeline
A Population (Pop) with several Agents defined by ID’s and Knowledge
optional for future implementations a name (Typ) for the specific Knowledge
A value for the lLearnRate (LR). could be a scalar or e vector with the same length as the Population
A value for the StudyTime (ST). could be a scalar or e vector with the same length as the Population
Hints
If LearnRate isn’t given the values from the Population will be used, if this is missing in the Population 0 is used.
Code
learn<-function(Pop=Pop,Typ=FALSE,LR=FALSE,ST=StudyTime){Kname<-"Knowledge"if(Typ!=FALSE){Kname<-paste(Kname, Typ, sep ="_")}if(Kname%in%colnames(Pop)){K<-Pop[[Kname]]}if(LR==FALSE){if("LearnRate"%in%colnames(Pop)){LR<-Pop[["LearnRate"]]}}T0<-(1-K)^(1/-LR)# assumed time learnd allreadyK<-1-(T0+ST)^(-LR)# Knowledge after time learndPop<-set_Knowledge(Pop =Pop, Typ =Typ, K =K)Pop<-update_StudyTime(Pop =Pop, dT =ST)return(Pop)}
Output
Population with updated Knowledge
Code
Pop<-tibble( ID =ID)Pop<-set_Knowledge(Pop =Pop, K =0.1)Pop<-set_LearnRate(Pop =Pop, LR =1)Pop
plt_Timeline<-function(TL=Timeline){ggplot(data =TL, aes(x =Time))+geom_line(aes(y =Knowledge, group =ID, color ="Agents"), alpha =0.5, linetype ="solid")+geom_line(aes(y =Knowledge_mean, color ="Mean"), linetype ="solid")+geom_line(aes(y =Knowledge_median, color ="Median"), linetype ="dashed")+ggtitle("Timeline")+xlab("Number of itterations")+ylab("Knowledge")+scale_y_continuous( limits =c(0, 1), breaks =seq(0, 1, 0.2))+scale_color_manual( values =c("Agents"="grey", "Mean"="black", "Median"="black"), labels =c("Agents"="Agents", "Mean"="Mean", "Median"="Median"))+theme_light()+theme(legend.title =element_blank(), legend.position =c(1, 0), legend.justification =c(1, 0))}
Simulation
A learning process with fixed LearnRate
Needs
A Population (Pop) with several Agents defined by ID’s and Knowledge
optional for future implementations a name (Typ) for the specific Knowledge
A value for the learn rate (LR) greater than 0 and up to 1. could be a scalar or e vector with the same length as the Population
A value for the StudyTime (ST). could be a scalar or a vector with the same length as the Population
A number of itterations (STn)
Code
sim_learn<-function(Pop=Pop,Typ=FALSE,LR=LearnRate,ST=1,STn=Itterations){Kname<-"Knowledge"if(Typ!=FALSE){Kname<-paste(Kname, Typ, sep ="_")}Pop<-set_LearnRate( Pop =Pop, LR =LR)Pop<-set_StudyTime( Pop =Pop)TL<-get_Timeline( TL =TL, Time =0, Pop =Pop, Info =Kname, Sum =1)for(iin1:STn){Pop<-learn( Pop =Pop, LR =LR, ST =ST)TL<-get_Timeline( TL =TL, Time =i, Pop =Pop, Info =Kname, Sum =1)}Output<-list( Pop =Pop, TL =TL)return(Output)}
Output
A List with the new Population and a Timeline over the number of itterations
Code
nA=50# number of AgentsID=seq_len(nA)# ID of the AgentsK=(seq_len(nA)-1)/50# KnowledgePop<-tibble( ID =ID)Pop<-set_Knowledge( Pop =Pop, K =K)Pop
Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
3.5.0.
ℹ Please use the `legend.position.inside` argument of `theme()` instead.
---title: "Simple learningcurve"author: "Hubert Baechli"---# Simple learning curveFirst and foremost, the distribution of information and knowledge should have something to do with learning. So I start with an exponential learning curve, which is easy to implement.# DefinitionsLoading some Packages for easier Data management and Presentation of Results```{r}library(tidyverse) # set.seed(1)```## Population for testing the Functions```{r}nA =5# number of AgentsID =seq_len(nA) # ID of the AgentsPop <-tibble( ID = ID )Pop```# Functions## KnowledgeFunctions to set and update Knowledge### Set Knowledge#### Needs1. A Population (Pop) with several Agents defined by ID's2. A value for the Knowledge (K) between 0 and 1. could be a scalar or e vector with the same length as the Population3. optional for future implementations a name (Typ) for the specific Knowledge```{r}set_Knowledge <-function(Pop = Pop,Typ =FALSE,K = Knowledge) { Kname <-"Knowledge"if (Typ !=FALSE) { Kname <-paste(Kname, Typ, sep ="_") }if (Kname %in%colnames(Pop)) { Pop <- Pop %>%mutate(!!Kname := K) } else { Pop[[Kname]] <- K } Pop <- Pop %>%return(Pop)}```#### Output1. Population with the defined Knowledge```{r}K <-seq_len(nA)/5Pop <-set_Knowledge( Pop = Pop, K =0.5 )Pop <-set_Knowledge( Pop = Pop, Typ ="A", K = K )Pop```### Update Knowledge#### Needs1. A Population (Pop) with several Agents defined by ID's2. A value to add to the Knowledge. could be a scalar or e vector with the same length as the Population. if not defined 0 is used to add3. A value to multiplie (fac) the Knowledge. could be a scalar or e vector with the same length as the Population. if not defined 1 is used for the multiplikation4. optional for future implementations a name (Typ) for the specific Knowledge#### Hints- The add operation is always used first!- If the Knowledge is not defined before it will be generated with the start value (add) and the multiplication with the value (fac)```{r}update_Knowledge <-function(Pop = Pop,Typ =FALSE,add =0,fac =1) { Kname <-"Knowledge"if (Typ !=FALSE) { Kname <-paste(Kname, Typ, sep ="_") }if (Kname %in%colnames(Pop)) { Pop <- Pop %>%mutate( !!Kname := ( .data[[Kname]] + add ) * fac ) } else { Pop <-set_Knowledge(Pop = Pop, K = add, Typ = Typ) Pop <- Pop %>%mutate( !!Kname := .data[[Kname]] * fac ) }return(Pop)}```#### Output1. Population with the defined Knowledge```{r}add <-seq_len(nA)/20fac <-seq_len(nA)/10Pop <-update_Knowledge( Pop = Pop, add = add ) Pop <-update_Knowledge( Pop = Pop, Typ ="A", fac = fac ) Pop <-update_Knowledge( Pop = Pop, Typ ="B", add = add, fac = fac ) Pop```## LearnRateFunctions to set and update the learn rate### Set LearnRate#### Needs1. A Population (Pop) with several Agents defined by ID's2. A value for the learn rate (LR) greater than 0 and up to 1. could be a scalar or e vector with the same length as the Population#### Hints- LernRate 0 leads to Problems so it ist limited it to 1E-3```{r}set_LearnRate <-function(Pop = Pop,LR = LearnRate) { LRname <-"LearnRate" Pop <- Pop %>%mutate(!!LRname := LR,!!LRname :=pmax(.data[[LRname]],1E-3))return(Pop)}```#### Output1. Population with the defined learn rate```{r}LR <-seq_len(nA)/5Pop <-set_LearnRate( Pop = Pop, LR =1 ) Pop```## StudyTimeFunctions to set and update the StudyTime### Set StudyTime#### Needs1. A Population (Pop) with several Agents defined by ID's2. A value for the StudyTime (ST). could be a scalar or a vector with the same length as the Population#### Hints- If StudyTime isn't given the Population will be initializing with 0```{r}set_StudyTime <-function(Pop = Pop,ST =0) { STname <-"StudyTime" Pop <- Pop %>%mutate(!!STname := ST)return(Pop)}```#### Output1. Population with the defined StudyTime```{r}Pop <-set_StudyTime( Pop = Pop, ST =3) Pop```### Update StudyTime#### Needs1. A Population (Pop) with several Agents defined by ID's and StudyTime2. A Time (dT) that should added.#### Hints- If StudyTime isn't defined in Population it will be initialising with dT```{r}update_StudyTime <-function(Pop = Pop,dT = TimeToAdd) { STname <-"StudyTime"if (STname %in%colnames(Pop)) { Pop <- Pop %>%mutate( !!STname := .data[[STname]] + dT ) } else { Pop <-set_StudyTime(Pop = Pop, ST = dT ) }return(Pop)}```#### Output1. Population with the defined StudyTime```{r}Pop <-update_StudyTime( Pop = Pop, dT =1) Pop```## Timelinessaving Timelines during Simulations### Get Agents-Timelines#### Needs1. A containername for the Timeline2. A value for the Time3. A Population (Pop) with several Agents defined by ID's4. A colname from the Population which should followed ver Time5. optional parameter Sum. Ich Sum = 1 a mean and median is calculated for each Time```{r}get_Timeline <-function(TL = Timeline,Time =0,Pop = Pop,Info = name,Sum =0) { TLadd <-tibble( ID = Pop[["ID"]],Time = Time,!!Info := Pop[[Info]])if (Sum ==1) { Sumname1 <-paste(Info,"mean", sep ="_") Sumname2 <-paste(Info,"median", sep ="_") TLadd <- TLadd %>%mutate(!!Sumname1 :=mean(Pop[[Info]], na.rm =TRUE),!!Sumname2 :=median(Pop[[Info]], na.rm =TRUE)) }if (Time ==0) { TL <- TLadd } else { TL <-bind_rows(TL, TLadd) }return(TL) }```#### Output1. A Timeline in a long format```{r}Timeline <-get_Timeline( TL = Timeline, Time =0, Pop = Pop, Info ="Knowledge", Sum =1)Timeline <-get_Timeline( TL = Timeline, Time =1, Pop = Pop, Info ="Knowledge", Sum =1)Timeline```## **Learning**Learning with a exponential Lernrate#### Needs1. A Population (Pop) with several Agents defined by ID's and Knowledge2. optional for future implementations a name (Typ) for the specific Knowledge3. A value for the lLearnRate (LR). could be a scalar or e vector with the same length as the Population4. A value for the StudyTime (ST). could be a scalar or e vector with the same length as the Population#### Hints- If LearnRate isn't given the values from the Population will be used, if this is missing in the Population 0 is used.```{r}learn <-function(Pop = Pop,Typ =FALSE,LR =FALSE,ST = StudyTime) { Kname <-"Knowledge"if (Typ !=FALSE) { Kname <-paste(Kname, Typ, sep ="_") }if (Kname %in%colnames(Pop)) { K <- Pop[[Kname]] }if (LR ==FALSE) {if ("LearnRate"%in%colnames(Pop)) { LR <- Pop[["LearnRate"]] } } T0 <- ( 1- K )^( 1/-LR ) # assumed time learnd allready K <-1- ( T0 + ST )^( -LR ) # Knowledge after time learnd Pop <-set_Knowledge(Pop = Pop, Typ = Typ, K = K) Pop <-update_StudyTime(Pop = Pop, dT = ST)return(Pop)}```#### Output1. Population with updated Knowledge```{r}Pop <-tibble( ID = ID )Pop <-set_Knowledge(Pop = Pop, K =0.1)Pop <-set_LearnRate(Pop = Pop, LR =1)PopPop <-learn( Pop = Pop, ST =10)Pop```## **Plots**### Plot Timeline#### Needs1. A Timeline from get_Timeline```{r}plt_Timeline <-function(TL = Timeline) {ggplot(data = TL, aes(x = Time)) +geom_line(aes(y = Knowledge, group = ID, color ="Agents"), alpha =0.5,linetype ="solid") +geom_line(aes(y = Knowledge_mean, color ="Mean"),linetype ="solid") +geom_line(aes(y = Knowledge_median, color ="Median"),linetype ="dashed") +ggtitle("Timeline") +xlab("Number of itterations") +ylab("Knowledge") +scale_y_continuous(limits =c(0, 1),breaks =seq(0, 1, 0.2) ) +scale_color_manual(values =c("Agents"="grey", "Mean"="black", "Median"="black"),labels =c("Agents"="Agents", "Mean"="Mean", "Median"="Median") ) +theme_light() +theme(legend.title =element_blank(),legend.position =c(1, 0),legend.justification =c(1, 0))}```# **Simulation**A learning process with fixed LearnRate#### Needs1. A Population (Pop) with several Agents defined by ID's and Knowledge2. optional for future implementations a name (Typ) for the specific Knowledge3. A value for the learn rate (LR) greater than 0 and up to 1. could be a scalar or e vector with the same length as the Population4. A value for the StudyTime (ST). could be a scalar or a vector with the same length as the Population5. A number of itterations (STn)```{r}sim_learn <-function(Pop = Pop,Typ =FALSE,LR = LearnRate,ST =1,STn = Itterations) { Kname <-"Knowledge"if (Typ !=FALSE) { Kname <-paste(Kname, Typ, sep ="_") } Pop <-set_LearnRate( Pop = Pop, LR = LR) Pop <-set_StudyTime( Pop = Pop ) TL <-get_Timeline( TL =TL,Time =0,Pop = Pop,Info = Kname,Sum =1 )for(i in1:STn) { Pop <-learn( Pop = Pop,LR = LR,ST = ST) TL <-get_Timeline( TL =TL,Time = i,Pop = Pop,Info = Kname,Sum =1 ) } Output <-list( Pop = Pop,TL = TL)return(Output)}```#### Output1. A List with the new Population and a Timeline over the number of itterations```{r}nA =50# number of AgentsID =seq_len(nA) # ID of the AgentsK = (seq_len(nA)-1)/50# KnowledgePop <-tibble( ID = ID )Pop <-set_Knowledge( Pop = Pop, K = K )Popres <-sim_learn(Pop = Pop,LR =0.1,ST =1,STn =500)res$Popplt_Timeline(res$TL)```