c# – 计算函数/蒙特卡罗方法合理性的算法
我正在编写一个试图复制本文开头讨论的算法的程序,
http://www-stat.stanford.edu/~cgates/PERSI/papers/MCMCRev.pdf F是从char到char的函数.假设P1(f)是该函数的“合理性”度量.算法是: 从对函数的初步猜测开始,比如f,然后是新的函数f * – >计算Pl(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 ? } } } 我的问题基本上是否看起来像是实现该算法的最佳方法.尽管实施了这种方法,我似乎可能会陷入一些局部最大值/局部最小值. 编辑 – 这是Transpose()方法背后的本质问题.我使用类型<<的字典/哈希表char,char>>候选函数用于查看任何给定的char – > char变换.因此,转置方法只是在字典中交换两个指示函数行为的值. private Dictionary<char,char> Transpose(Dictionary<char,char> 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<char,char> theMap) { return theMap[char]; } 这是计算Pl(f)的函数: public decimal ComputePl(Func<char,char> 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; } 解决方法
暂时,codereview.stackexchange.com可能是“更好的论坛”.
从来没有,我会快速刺伤它: >一目了然,显示的代码段是算法的正确实现. >确保Flip()方法公平 关于算法本身及其对不同问题的适用性的讨论. 确保算法适用性的另一种方法是确保更好地评估给定函数的合理性.对算法的相对成功和一般性的可能解释是 >英语中一阶转换的分布不是很均匀(因此模型很好地模拟了给定函数的合理性,通过奖励它的匹配并惩罚它的不匹配).与给定语言/语料库中的字符的“0阶”分布相比,这种多维统计更偏离参考语料库. 因此,为了提高算法对给定问题的适用性,请确保使用的分布矩阵尽可能地匹配基础文本的语言和域. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |