(reprise et modification du code donné en TD, code écrit par Arnaud Legrand disponible sur son site
N = 100
a = 0.1
b = (1-a)/(N-1)
K = 20
T = 10000
access = sample(c(1:N), T, prob=c(a,rep(b,N-1)), replace=TRUE)
head(access)
## [1] 60 92 70 58 93 57
cache = sample(c(1:N), K, prob=c(a,rep(b,N-1)), replace=FALSE) # Un cache initial
cacheTFront = cache
posA = c() ;
missA = c() ;
miss = c()
for(obj in access) {
if(obj %in% cache) {
pos = (1:K)[cache==obj];
if(pos != 1 ){
tmp = cache[pos]
cache[pos] = cache [pos-1]
cache[pos-1] = tmp
}
#cache = c(obj,cache[-pos])
miss=c(miss,0);
if(1 %in% cache) {
posA = c(posA,((1:K)[!is.na(cache) & cache==1]));
} else {
posA = c(posA,NA);
}
} else {
cache = c(cache[-K],obj)
miss=c(miss,1);
if(obj==1) {
missA=c(missA,1);
} else {
missA=c(missA,0);
}
}
}
head(cache)
## [1] 1 65 46 64 72 16
head(posA)
## [1] 7 6 6 6 6 6
head(miss)
## [1] 1 1 1 1 1 1
head(miss)
## [1] 1 1 1 1 1 1
plot(posA); lines(posA);
err = sd(miss)/sqrt(length(miss));
mean(miss)-2*err;
## [1] 0.7192008
mean(miss)+2*err
## [1] 0.7369992
on va considerer un élement e situé à la ième position du cache et soit p sa probabilité d’apparition dans access ( donc p = a si e = 1 sinon p = b )
la position de e dans le cache sera k avec une probabilité de p et sera i+1 avec une probabilité 1-p
Soit l’élement courant c qui est en position j
si j > i+1 : la position de e dans le cache sera i-1 avec un proba p et restera i autrement
si j <= i+1 : la position de e dans le cache sera i-1 avec une probabilité p et i+1 si j et en position i+1.
si i = 1 : la position de e restera 1 sauf si c est en deuxième position alors e sera en deuxième position ( avec une probabilité 1-p )
markov=matrix(rep(0,N*N),nrow=N);
markov[1,1] = 1-b;
markov[1,2] = b
for(i in 2:(N-1)) {
if(i<K){
markov[i,i-1] = a ;
markov[i,i+1] = b
markov[i,i]= 1-b-a
}
if(i>K){
markov[i,K] = a ;
markov[i,i]= 1-a ;
}
}
options(digits = 2)
E=head(eigen(t(markov)))
head(E$values)
## [1] 1.00 0.95 0.95 0.94 0.94 0.93
ssp=E$vectors[,1];
ssp = Re(ssp/(sum(ssp)))
options(digits=7);
ssp
## [1] 9.090909e-01 8.264463e-02 7.513148e-03 6.830135e-04 6.209213e-05
## [6] 5.644739e-06 5.131581e-07 4.665074e-08 4.240976e-09 3.855433e-10
## [11] 3.504939e-11 3.186308e-12 2.896644e-13 2.633311e-14 2.393906e-15
## [16] 2.176143e-16 1.976959e-17 1.783718e-18 1.486355e-19 1.351232e-21
## [21] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [26] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [31] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [36] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [41] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [46] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [51] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [56] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [61] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [66] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [71] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [76] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [81] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [86] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [91] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
## [96] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
puis on calucule la probabilité de A d’être dans le cache :
sum(ssp[1:K])
## [1] 1
On arrive a une probabilité très proche de 1.
missTFront=c()
missATFront=c()
posATFront=c();
for(obj in access) {
if(obj %in% cacheTFront) {
pos = (1:K)[cacheTFront==obj];
cacheTFront = c(obj,cacheTFront[-pos])
missTFront=c(missTFront,0);
missATFront=c(missATFront,0);
} else {
cacheTFront = c(obj,cacheTFront[-K])
missTFront=c(missTFront,1);
if(obj == 1) {
missATFront=c(missATFront,1);
} else {
missATFront=c(missATFront,0);
}
}
if(1 %in% cacheTFront) {
posATFront = c(posATFront, (1:K)[cacheTFront==1]);
} else {
posATFront = c(posATFront, NA);
}
}
sum(miss)
## [1] 7281
sum(missA)
## [1] 0
sum(missTFront)
## [1] 7357
sum(missATFront)
## [1] 90
On peut voir que le nombre de miss total est très proche, ce qui est normal car il y’a beacoup d’élément pour une taille de cache assez petite.
Pour les miss d’un élément fréquent ( a ) on voit que move ahead est bien plus efficace car l’élement à plus de chance de rester dans le cache et on peut voir que la position de A est souvent dans les premiers élement du cache pour le move ahead (voir au deussus )
sum(missATFront) - sum(missA)
## [1] 90
plot(posATFront); lines(posATFront)
plot(posA); lines(posA)
coef = 0.5
p = c()
pcurrent = coef
for (i in 1:N ){
p = c(p,pcurrent)
pcurrent = pcurrent*coef
}
head (p)
## [1] 0.500000 0.250000 0.125000 0.062500 0.031250 0.015625
sum(p)
## [1] 1
access = sample(c(1:N), T, prob=p, replace=TRUE)
cache = sample(c(1:N), K, prob=p, replace=FALSE) # Un cache initial
cacheTFront = cache
head (access)
## [1] 1 3 1 2 2 2
On réexecute les codes que je ne montre pas (même que plus haut)
le nombre d’objet manqué :
sum(missTFront)
## [1] 0
sum(miss)
## [1] 0
hist(access)
Idem pour l’objet a ( c’est le premier celui avec la plus grosse probailité d’apparition )
sum(missA)
## [1] 0
sum(missATFront)
## [1] 0
les deux modèles sont efficasses car les derniers élements n’ont quasiement aucune chance de sortir.
set.seed(42)
N = 10
ligne = matrix(rep(0,N*N),nrow=N)
for(i in 2:(N)){
ligne[i-1,i] = 1
ligne[i,i-1] = 1
}
ligne
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0 1 0 0 0 0 0 0 0 0
## [2,] 1 0 1 0 0 0 0 0 0 0
## [3,] 0 1 0 1 0 0 0 0 0 0
## [4,] 0 0 1 0 1 0 0 0 0 0
## [5,] 0 0 0 1 0 1 0 0 0 0
## [6,] 0 0 0 0 1 0 1 0 0 0
## [7,] 0 0 0 0 0 1 0 1 0 0
## [8,] 0 0 0 0 0 0 1 0 1 0
## [9,] 0 0 0 0 0 0 0 1 0 1
## [10,] 0 0 0 0 0 0 0 0 1 0
anneau = matrix(rep(0,N*N),nrow=N)
for(i in 2:(N)){
anneau[i-1,i] = 1
anneau[i,i-1] = 1
}
anneau[1,N] =1
anneau[N,1] = 1
anneau
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0 1 0 0 0 0 0 0 0 1
## [2,] 1 0 1 0 0 0 0 0 0 0
## [3,] 0 1 0 1 0 0 0 0 0 0
## [4,] 0 0 1 0 1 0 0 0 0 0
## [5,] 0 0 0 1 0 1 0 0 0 0
## [6,] 0 0 0 0 1 0 1 0 0 0
## [7,] 0 0 0 0 0 1 0 1 0 0
## [8,] 0 0 0 0 0 0 1 0 1 0
## [9,] 0 0 0 0 0 0 0 1 0 1
## [10,] 1 0 0 0 0 0 0 0 1 0
sucette = matrix(rep(0,N*N),nrow=N)
for(i in 2:(N)){
sucette[i-1,i] = 1
sucette[i,i-1] = 1
}
end_anneau = as.integer(0.8*N)
sucette[end_anneau,1] =1
sucette[1,end_anneau]= 1
sucette
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0 1 0 0 0 0 0 1 0 0
## [2,] 1 0 1 0 0 0 0 0 0 0
## [3,] 0 1 0 1 0 0 0 0 0 0
## [4,] 0 0 1 0 1 0 0 0 0 0
## [5,] 0 0 0 1 0 1 0 0 0 0
## [6,] 0 0 0 0 1 0 1 0 0 0
## [7,] 0 0 0 0 0 1 0 1 0 0
## [8,] 1 0 0 0 0 0 1 0 1 0
## [9,] 0 0 0 0 0 0 0 1 0 1
## [10,] 0 0 0 0 0 0 0 0 1 0
metho1 <- function (m,t ){
res = c(rep(0,N))
etat = round( runif(1,min=1,max = N) )
res[etat] = 1
for (i in 1:t){
num = sum(m[etat,])
alea = round(runif(1,min =1,max= num) ) #tire un nombre pour savoir quel sera l'état suivant
j = 1
tmp = 0
while(tmp<alea){
tmp= tmp+ m[etat,j]
j = j +1
}
etat = j-1 ;
res[etat] = res[etat] +1
}
res = res/t
return(res)
}
On va calculer la moyenne sur 100 marches alétoires différentes :
moyenne <- function (m,rep,t){
res= c(rep(0,N))
for(i in 1:rep){
res = res + metho1(m,t)
}
return(res/rep)
}
p = moyenne(ligne,500,100)
p
## [1] 0.05570 0.11286 0.11512 0.11502 0.11210 0.11114 0.11206 0.11114
## [9] 0.11010 0.05476
plot(p)
On arrive a voir clairement que les états intermédiaires sont équiprobable tandis que les deux extrémités sont deux fois moins probable cela est facilement explicable car il n’y qu’un seul lien vers les extrémités alors que tous les autres ont deux liens.
p = moyenne(anneau,500,100)
p
## [1] 0.10108 0.09896 0.09800 0.09720 0.09796 0.10212 0.10420 0.10310
## [9] 0.10414 0.10324
plot(p)
On voit que tous les états sont équiprobables, on peut voir que la différence de fréquence entre chaque état est très petite et se rapproche du 1/N
p = moyenne(sucette,500,100)
p
## [1] 0.07982 0.09240 0.10182 0.10942 0.11826 0.12586 0.13354 0.14272
## [9] 0.07160 0.03456
plot(p)
La encore c’est facilement explicable le dernier état en fin de queue possède qu’un seul lien donc est moins susceptible de tomber alors que l’état qui relie l’anneau à la queue a beaucoup de chance de sortir car possède 3 liens. De plus on voit que les états suivant dans l’anneau sont plus susceptible de sortir s’ils sont proche de la queue.
toMarkov <- function (init){
m = init
for(i in 1:N){
num = sum(m[i,])
m[i,] = m[i,]/num
}
return(m)
}
On vérifie que l’on obtient bien ce que l’on souhaite:
Mligne = toMarkov(ligne)
Manneau = toMarkov(anneau)
Msucette = toMarkov(sucette)
Mligne
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
## [2,] 0.5 0.0 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0
## [3,] 0.0 0.5 0.0 0.5 0.0 0.0 0.0 0.0 0.0 0.0
## [4,] 0.0 0.0 0.5 0.0 0.5 0.0 0.0 0.0 0.0 0.0
## [5,] 0.0 0.0 0.0 0.5 0.0 0.5 0.0 0.0 0.0 0.0
## [6,] 0.0 0.0 0.0 0.0 0.5 0.0 0.5 0.0 0.0 0.0
## [7,] 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.5 0.0 0.0
## [8,] 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.5 0.0
## [9,] 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.5
## [10,] 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0
Matrice de départ :
init = matrix(rep(1/N,N*N),nrow=N)
fonction permettant de simuler t déplacement :
deplacement <- function (m , t){
res = init
for (i in 1:t){
res = res %*% m
}
return(res)
}
options(digits=3)
depl = deplacement(ligne,1000)
depl
## [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [2,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [3,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [4,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [5,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [6,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [7,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [8,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [9,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [10,] 4.2e+281 8.07e+281 1.13e+282 1.36e+282 1.48e+282 1.48e+282 1.36e+282
## [,8] [,9] [,10]
## [1,] 1.13e+282 8.07e+281 4.2e+281
## [2,] 1.13e+282 8.07e+281 4.2e+281
## [3,] 1.13e+282 8.07e+281 4.2e+281
## [4,] 1.13e+282 8.07e+281 4.2e+281
## [5,] 1.13e+282 8.07e+281 4.2e+281
## [6,] 1.13e+282 8.07e+281 4.2e+281
## [7,] 1.13e+282 8.07e+281 4.2e+281
## [8,] 1.13e+282 8.07e+281 4.2e+281
## [9,] 1.13e+282 8.07e+281 4.2e+281
## [10,] 1.13e+282 8.07e+281 4.2e+281
plot(depl[1,])
On remaque une structure en cone, cela peut s’expliquer que comme les extrémités sont moins fréquents on va tendence à rester plus au centre.
options(digits=3)
depl = deplacement(anneau,1000)
depl
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [2,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [3,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [4,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [5,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [6,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [7,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [8,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [9,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [10,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [,7] [,8] [,9] [,10]
## [1,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [2,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [3,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [4,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [5,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [6,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [7,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [8,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [9,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
## [10,] 1.07e+300 1.07e+300 1.07e+300 1.07e+300
plot(depl[1,])
On voit que tous les étas sont parfaitement équiprobable.
options(digits=3)
depl = deplacement(sucette,930)
depl
## [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [2,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [3,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [4,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [5,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [6,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [7,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [8,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [9,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [10,] 9.23e+301 6.9e+301 6.23e+301 5.56e+301 6.23e+301 6.9e+301 9.23e+301
## [,8] [,9] [,10]
## [1,] 1.16e+302 7.44e+301 3.32e+301
## [2,] 1.16e+302 7.44e+301 3.32e+301
## [3,] 1.16e+302 7.44e+301 3.32e+301
## [4,] 1.16e+302 7.44e+301 3.32e+301
## [5,] 1.16e+302 7.44e+301 3.32e+301
## [6,] 1.16e+302 7.44e+301 3.32e+301
## [7,] 1.16e+302 7.44e+301 3.32e+301
## [8,] 1.16e+302 7.44e+301 3.32e+301
## [9,] 1.16e+302 7.44e+301 3.32e+301
## [10,] 1.16e+302 7.44e+301 3.32e+301
plot(depl[1,])
On remarque la même chose pour l’élement en fin de queue et celui relier à la queue et à l’anneau cependant l’état qui est à l’opposé de la queue ( l’état 4 ) est le moins susceptible de sortir dans l’anneau.
Fonction qui calcule pi :
pi <- function (m){
return( eigen(t(m)) )
}
pi(ligne)
## $values
## [1] 1.919 1.683 1.310 0.831 0.285 -0.285 -0.831 -1.310 -1.683 -1.919
##
## $vectors
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0.120 0.231 -0.322 0.388 0.422 0.422 0.388 -0.322 0.231 -0.120
## [2,] 0.231 0.388 -0.422 0.322 0.120 -0.120 -0.322 0.422 -0.388 0.231
## [3,] 0.322 0.422 -0.231 -0.120 -0.388 -0.388 -0.120 -0.231 0.422 -0.322
## [4,] 0.388 0.322 0.120 -0.422 -0.231 0.231 0.422 -0.120 -0.322 0.388
## [5,] 0.422 0.120 0.388 -0.231 0.322 0.322 -0.231 0.388 0.120 -0.422
## [6,] 0.422 -0.120 0.388 0.231 0.322 -0.322 -0.231 -0.388 0.120 0.422
## [7,] 0.388 -0.322 0.120 0.422 -0.231 -0.231 0.422 0.120 -0.322 -0.388
## [8,] 0.322 -0.422 -0.231 0.120 -0.388 0.388 -0.120 0.231 0.422 0.322
## [9,] 0.231 -0.388 -0.422 -0.322 0.120 0.120 -0.322 -0.422 -0.388 -0.231
## [10,] 0.120 -0.231 -0.322 -0.388 0.422 -0.422 0.388 0.322 0.231 0.120
Ce n’est pas ce qu’on attend ..
J’ai eu recours au paquet DTMCPack afin de calculer directement .
p = DTMCPack::statdistr(Mligne)
p
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0.0556 0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.0556
plot(p[1,])
p = DTMCPack::statdistr(Manneau)
p
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
on voit clairement que c’est équiprobable
p = DTMCPack::statdistr(Msucette)
p
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.15 0.1 0.05
plot(p[1,])
Pour savoir la probabilité on peut juste compter les liens.