Алгоритм для вычисления правдоподобности Функция / Метод Monte Carlo

Я пишу программу, которая пытается дублировать алгоритм обсуждались в начале этой статьи,

http://www-stat.stanford.edu/~cgates/PERSI /papers/mcmcrev.pdf

F - это функция от CHAR для CHAR. Предположим, что PL (F) - мера «правдоподобности» этой функции. Алгоритм:

, начиная с предварительного угадания при функции, скажем F, а затем новую функцию F * -

  • Compute PL (F).
  • Изменится на F *, сделав случайное транспозицию значений F, присваивая на два символа.
  • Compute PL (F *); Если это больше, чем PL (F), примите F *.
  • Если нет, переверните монету PL (F) / PL (F *); Если это возникает головы, примите f *.
  • Если монета проходит хвосты, оставайтесь на е.

Я реализую это, используя следующий код. Я использую C #, но попытался сделать его несколько более упрощенным для всех. Если есть лучший форум для этого, пожалуйста, дайте мне знать.

 var current_f = Initial();    // current accepted function f
 var current_Pl_f = InitialPl();  // current plausibility of accepted function f

 for (int i = 0; i < 10000; i++)
        {
            var candidate_f = Transpose(current_f); // create a candidate function

            var candidate_Pl_f = ComputePl(candidate_f);  // compute its plausibility

            if (candidate_Pl_f > current_Pl_f)            // candidate Pl has improved
            {
                current_f = candidate_f;            // accept the candidate
                current_Pl_f = candidate_Pl_f; 
            }
            else                                    // otherwise flip a coin
            {
                int flip = Flip(); 

                if (flip == 1)                      // heads
                {
                    current_f = candidate_f;        // accept it anyway
                    current_Pl_f = candidate_Pl_f; 
                }
                else if (flip == 0)                 // tails
                {
                    // what to do here ?
                }
            }
        }

Мой вопрос в основном, похоже ли это оптимальный подход к реализации этого алгоритма. Похоже, я могу застрять в некоторых местных максимумах / локальных минимах, несмотря на реализацию этого метода.

Редактировать - вот по существу, что за транспонирование () методом. Я использую словарь / хеш-таблица типа > То, что функция (ы) кандидата, чтобы посмотреть любой данный символ -> преобразование CHAR. Таким образом, метод транспонирования просто сводит два значения в словаре, который диктует поведение функции.

    private Dictionary Transpose(Dictionary map, params int[] indices)
    {
        foreach (var index in indices)
        {
            char target_val = map.ElementAt(index).Value;   // get the value at the index

            char target_key = map.ElementAt(index).Key;     // get the key at the index

            int _rand = _random.Next(map.Count);   // get a random key (char) to swap with

            char rand_key = map.ElementAt(_rand).Key;

            char source_val = map[rand_key]; // the value that currently is used by the source of the swap

            map[target_key] = source_val; // make the swap

            map[rand_key] = target_val;
        }

        return map; 
    }

Имейте в виду, что функция кандидат, который использует базовый словарь в основном только:

public char GetChar(char in, Dictionary theMap)
{
     return theMap[char]; 
}

И это функция, которая вычисляет Pl (F):

    public decimal ComputePl(Func candidate, string encrypted, decimal[][] _matrix)
    {
        decimal product = default(decimal);

        for (int i = 0; i < encrypted.Length; i++)
        {
            int j = i + 1;

            if (j >= encrypted.Length)
            {
                break;
            }

            char a = candidate(encrypted[i]);
            char b = candidate(encrypted[j]);

            int _a = GetIndex(_alphabet, a); // _alphabet is just a string/char[] of all avl chars 
            int _b = GetIndex(_alphabet, b);

            decimal _freq = _matrix[_a][_b]; 

            if (product == default(decimal))
            {
                product = _freq;
            }
            else
            {
                product = product * _freq;
            }
        }

        return product;
    }

7
задан Sean Thoman 14 September 2011 в 22:43
поделиться