2012-05-03 3 views
13

Мне интересен простой алгоритм фильтрации частиц, приведенный здесь: http://www.aiqus.com/upfiles/PFAlgo.png Кажется очень простым, но я понятия не имею, как это сделать практически. Любая идея о том, как ее реализовать (чтобы лучше понять, как это работает)?Реализация последовательного метода monte carlo (фильтры частиц)

Edit: Это отличный пример, который объясняет, как это работает: http://www.aiqus.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo-method-implementation?page=1#39950

Я попытался реализовать в C++: http://pastebin.com/M1q1HcN4, но я уверен, обратите внимание, если я это правильно , Можете ли вы проверить, хорошо ли я это понял, или есть некоторые недоразумения в соответствии с моим кодом?

#include <iostream> 
#include <vector> 
#include <boost/random/mersenne_twister.hpp> 
#include <boost/random/uniform_01.hpp> 
#include <boost/random/uniform_int_distribution.hpp> 

using namespace std; 
using namespace boost; 

double uniform_generator(void); 

#define N 4 // number of particles 

#define evolutionProba_A_A 1.0/3.0 // P(X_t = A | X_t-1 = A) 
#define evolutionProba_A_B 1.0/3.0 // P(X_t = A | X_t-1 = B) 
#define evolutionProba_B_B 2.0/3.0 // P(X_t = B | X_t-1 = B) 
#define evolutionProba_B_A 2.0/3.0 // P(X_t = B | X_t-1 = A) 

#define observationProba_A_A 4.0/5.0 // P(Y_t = A | X_t = A) 
#define observationProba_A_B 1.0/5.0 // P(Y_t = A | X_t = B) 
#define observationProba_B_B 4.0/5.0 // P(Y_t = B | X_t = B) 
#define observationProba_B_A 1.0/5.0 // P(Y_t = A | X_t = A) 

/// =========================================================================== 

typedef struct distrib { float PA; float PB; } Distribution; 

typedef struct particle 
{ 
    Distribution distribution; // e.g. <0.5, 0.5> 
    char state; // e.g. 'A' or 'B' 
    float weight; // e.g. 0.8 
} 
Particle; 

/// =========================================================================== 

int main() 
{ 
    vector<char> Y; // data observations 
    Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); 
    Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); 
    Y.push_back('A'); Y.push_back('B'); Y.push_back('B'); Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); 

    vector< vector<Particle> > Xall; // vector of all particles from time 0 to t 

    /// Step (1) Initialisation 
    vector<Particle> X; // a vector of N particles 
    for(int i = 0; i < N; ++i) 
    { 
     Particle x; 

     // sample particle Xi from initial distribution 
     x.distribution.PA = 0.5; x.distribution.PB = 0.5; 
     float r = uniform_generator(); 
     if(r <= x.distribution.PA) x.state = 'A'; // r <= 0.5 
     if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; // 0.5 < r <= 1 

     X.push_back(x); 
    } 

    Xall.push_back(X); 
    X.clear(); 

    /// Observing data 
    for(int t = 1; t <= 18; ++t) 
    { 
     char y = Y[t-1]; // current observation 

     /// Step (2) Importance sampling 
     float sumWeights = 0; 
     vector<Particle> X; // a vector of N particles 
     for(int i = 0; i < N; ++i) 
     { 
      Particle x; 

      // P(X^i_t = A) = P(X^i_t = A | X^i_t-1 = A) * P(X^i_t-1 = A) + P(X^i_t = A | X^i_t-1 = B) * P(X^i_t-1 = B) 
      x.distribution.PA = evolutionProba_A_A * Xall[t-1][i].distribution.PA + evolutionProba_A_B * Xall[t-1][i].distribution.PB; 

      // P(X^i_t = B) = P(X^i_t = B | X^i_t-1 = A) * P(X^i_t-1 = A) + P(X^i_t = B | X^i_t-1 = B) * P(X^i_t-1 = B) 
      x.distribution.PB = evolutionProba_B_A * Xall[t-1][i].distribution.PA + evolutionProba_B_B * Xall[t-1][i].distribution.PB; 

      // sample the a particle from this distribution 
      float r = uniform_generator(); 
      if(r <= x.distribution.PA) x.state = 'A'; 
      if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; 

      // compute weight of this particle according to the observation y 
      if(y == 'A') 
      { 
       if(x.state == 'A') x.weight = observationProba_A_A; // P(y = A | X^i_t = A) 
       else if(x.state == 'B') x.weight = observationProba_A_B; // P(y = A | X^i_t = B) 
      } 
      else if(y == 'B') 
      { 
       if(x.state == 'A') x.weight = observationProba_B_A; // P(y = B | X^i_t = A) 
       else if(x.state == 'B') x.weight = observationProba_B_B; // P(y = B | X^i_t = B) 
      } 

      sumWeights += x.weight; 

      X.push_back(x); 
     } 

     // normalise weights 
     for(int i = 0; i < N; ++i) 
      X[i].weight /= sumWeights; 

     /// Step (3) resampling N particles according to weights 
     float PA = 0, PB = 0; 
     for(int i = 0; i < N; ++i) 
     { 
      if(X[i].state == 'A') PA += X[i].weight; 
      else if(X[i].state == 'B') PB += X[i].weight; 
     } 

     vector<Particle> reX; // new vector of particles 
     for(int i = 0; i < N; ++i) 
     { 
      Particle x; 

      x.distribution.PA = PA; 
      x.distribution.PB = PB; 

      float r = uniform_generator(); 
      if(r <= x.distribution.PA) x.state = 'A'; 
      if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; 

      reX.push_back(x); 
     } 

     Xall.push_back(reX); 
    } 

    return 0; 
} 

/// =========================================================================== 

double uniform_generator(void) 
{ 
    mt19937 gen(55); 
    static uniform_01< mt19937, double > uniform_gen(gen); 
    return uniform_gen(); 
} 
+0

Когда вы можете использовать этот фильтр в реальном мире? Можете ли вы провести тест на проблему с аналитическим решением? Если вы внедрили это исправно, вы получите тот же номер. Очень маловероятно, чтобы получить правильный результат с неправильной реализацией! –

+0

@AlessandroTeruzzi Это просто реализация простого примера, приведенного здесь (здесь) (http://www.aiqus.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo-method-implementation/39950). Я реализовал это только для того, чтобы лучше понять концепцию [фильтр частиц], данную этим алгоритмом] (http://www.aiqus.com/upfiles/PFAlgo.png), но я не уверен, правильно ли я ее реализовал, поскольку Я не очень хорошо понял алгоритм. Я не знаю, как проверить, работает ли он, поскольку алгоритм и его вывод все еще не очень понятны мне (даже если алгоритм кажется очень простым). – shn

+0

Мое первое предложение для универсального алгоритма: не пытайтесь реализовать то, что вы не полностью понимаете. Сначала возьмите, а затем выполните. В противном случае вы не сможете сказать, что происходит не так. –

ответ

20

This online course очень прост и понятен, и для меня он очень хорошо объяснил фильтры частиц.

Это называется «Программирование роботизированного автомобиля», и в нем рассказывается о трех методах локализации: локализации Монте-Карло, фильтрах Калмана и фильтрах частиц.

Курс полностью бесплатный (теперь он закончен, поэтому вы не можете активно участвовать, но вы все еще можете следить за лекциями), преподаваемым профессором Стэнфорда. «Классы» были для меня удивительно легкими, и они сопровождаются небольшими упражнениями - некоторые из них просто логичны, но многие из них программируют. Кроме того, домашние задания, с которыми вы можете играть.

Это действительно заставляет вас писать свой собственный код в python для всех фильтров, которые они также тестируют для вас. К концу курса вы должны иметь все 3 фильтра, реализованных в python.

Настоятельно рекомендуем проверить его.

+0

Хорошо, я проверю это. Но поскольку меня интересуют фильтры частиц (возможно, еще два других фильтра), следует ли мне проверять все курсы всех единиц с самого начала? – shn

+0

Если вас интересуют все фильтры, обязательно проверьте весь курс. Но даже если вы этого не сделаете, я рекомендую пройти другой курс - он даст вам очень хороший общий обзор методов локализации, и вы сможете более легко понять, где наиболее подходящий фильтр. Я думаю, что 1 лекция обычно может быть выполнена примерно через 4 часа - возможно, сделайте это за 1 или 2 дня, если вы хотите это сделать легко;) – penelope

+0

Кстати, я не буду использовать фильтры частиц для робототехники (локализация и т. Д.), Я 'll использовать его для другой проблемы, связанной с онлайн кластеризации последовательных данных. – shn

3
+0

Они как-то не то, что я ожидал. Есть ли способ реализовать простой, представленный на стр. 9 www.cs.ubc.ca/~ arnaud/doucet_defreitas_gordon_smcbookintro.ps? – shn

+0

Конечно, есть способы :) Как ссылки отличаются от ваших ожиданий? Где вас повесили трубку? Я считаю, что алгоритм на стр. 11. довольно просто. – Throwback1986

+0

Ну, я хочу внедрить фильтры частиц, оставшиеся от скречков, чтобы понять это. Я отредактировал свое первое сообщение, чтобы добавить простую реализацию на C++ простого примера, описанного здесь: http://www.aiqus.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo- метод-реализация? page = 1 # 39950 Не могли бы вы проверить, хорошо ли я это понял или есть некоторые недоразумения? – shn

Смежные вопросы