segunda-feira, 24 de setembro de 2012

Cadeia de Markov


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:

Anônimo disse...

É isso ai.