A cadeia de Markov é ferramenta que modela uma grande variedade de situações recorrentes em biologia, economia, química, engenharia e física envolvendo processos estocásticos . Nesses experimentos, a predição do estado seguinte depende apenas do estado atual. Esta propriedade é chamada de memória markoviana (ou falta de memória).
Considere a seguinte distribuição de probabilidade de uma população na zona urbana e zona rural:
vo = [0.6 0.4]
Este vetor indica que 60% da população vive na zona urbana e 40% da população vive na zona rural.
O próximo estado pode ser encontrado aplicando uma matriz de transição (matriz estocástica) é uma matriz quadrada com duas características:
1) todas as entradas são não negativas
2) todas as colunas tem soma igual a 1.
Por ano, 5% da população sai da zona urbana para a zona rural e 3% da população sai da zona rural para a zona urbana.
sai urbana rural
P = [ .95 0.03]urbana
[ .05 0.97]rural
chega
Podemos calcular a nova distribuição da população aplicando a matriz de transição:
Pvo = [0.95 0.03][0.6] = [0.582]
[0.05 0.97][0.4] [0.418]
A cadeia de Markov é a sequência de vetores de distribuição de probabilidade v0,v1,v2,..., com uma matriz de transição da seguinte maneira:
$v_{1} = Pv_0$
$v_2 = Pv_1$
$v_3 = Pv_2$
...
$v_n = Pv_{n-1}$
$v_n = P^{n} v_0$
Matriz de transição estacionária
A cadeia de Markov pode ser utilizada para encontrar . A matriz $P^{k}$ é a matriz de transição em k passos. A matriz $P^{k}$ converge para uma matriz estacionária. No nosso algoritmo, vamos considerar
um valor de k suficientemente grande para obter a matriz estacionária.
Primeiramente, temos a função que aloca uma matriz quadrada dinamicamente (alocam), a função multiplica que faz a multiplicação entre duas matrizes (a e b) devolvendo uma matriz c e a função que executa a exponenciação rápida de uma matriz $A^{n}$
double ** alocam(int n){
int i;
double ** p = (double **)malloc(n*sizeof(double *));
for(i=0;i<n;i++)
p[i] = (double *) malloc(n*sizeof(double));
return p;
}
void multiplica(double **a, double **b, double **c, int n){
int i,j,k;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
c[i][j] = 0.0;
for(k=0;k<n;k++){
c[i][j] += a[i][k]*b[k][j];
}
}
}
}
void exp(double **a, double **b,int n, int m){
int i,j;
double ** c = alocam(n);
if(m==0){
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i==j) b[i][j] = 1.0;
else b[i][j] = 0.0;
}else if(m==1){
for(i=0;i<n;i++)
for(j=0;j<n;j++)
b[i][j] = a[i][j];
}else if(m%2==0){
exp(a,c,n,m/2);
multiplica(c,c,b,n);
}else if(m%2==1){
exp(a,c,n,m-1);
multiplica(c,a,b,n);
}
free(c);
}
Agora, precisamos apenas inicializar a matriz de transição e depois calcular $A^n$ para n suficientemente grande.int main(){
int n,s,b,c;
int i,j,k;
double *v0;
double *vf;
m = alocam(2);
r = alocam(2);
v0 = aloca(2);
vf = aloca(2);
m[0][0] = 0.95;
m[0][1] = 0.03;
m[1][0] = 0.05;
m[1][1] = 0.97;
v0[0] = 0.4;
v0[1] = 0.6;
printf("Matriz Inicial\n");
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%lf ",m[i][j]);
}
printf("\n");
}
printf("\n");
exp(m,r,2,10000);
printf("Matriz Estacionaria\n");
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%lf ",r[i][j]);
}
printf("\n");
}
printf("\n");
free(m);
free(r);
}
Matriz Inicial
0.950000 0.030000
0.050000 0.970000
Matriz Estacionaria
0.375000 0.375000
0.625000 0.625000
Podemos concluir que a longo prazo, a população urbana será 37,5% e a população rural será 62,5% considerando a manutenção dessas taxas.
Outra maneira de encontrar o estado estacionário da cadeia de Markov é resolver a seguinte equação:
Px = x
Px-x=0
Px-Ix=0
(P-I)x=0
Você pode resolver os seguintes problemas com essa ideia:
http://br.spoj.pl/problems/VAMPIROS/
http://www.urionlinejudge.com.br/urionlinejudge/problems/view/1227
Um comentário:
É isso ai.
Postar um comentário