Java中的马尔可夫模型决策过程

我正在用Java编写辅助学习算法。

我遇到了一个我可能解决的数学问题,但由于处理过程很重,我需要一个最佳解决方案。

话虽如此,如果有人知道一个非常棒的优化库,但语言是Java,因此需要加以考虑。

这个想法很简单:

对象将存储变量的组合,例如ABDC,ACDE,DE,AE。

组合的最大数量将取决于我可以在不减慢程序速度的情况下运行的数量,因此理论上可以说100。

决策过程将每次迭代生成一个随机变量。 如果生成的变量是其中一个组合的一部分,例如。 ‘A’是ABDC和ACDE的一部分,而不是C和B(或存储的组合中的任何后续字母)的倾向将增加。

为了使事情更加清晰,我们假设’A’,’B’,’C’,’D’和’E’是唯一可能的变量。 事实是,会有更多像12或14,但这个最大值还取决于我可以处理多少没有滞后。

由于有五个可能的变量,它将为第一次迭代生成加权1/5随机滚动。 如果该滚动结果为’A’,则比下一次迭代’B’和’C’现在将具有2/5倾向而不是1/5。

如果下一次迭代产生’B’,’D’倾向将增加到3/5。 注意:关系是指数关系; 实际上,它不会是1/5,而是像10%那样略微提升,如果它达到序列中的第4个变量,它将滚雪球说50%。

现在,在Java中,我可以通过跟踪每个对象的所有存储组合来实现此function。 我想通过在每次迭代中以小步骤分配跟踪过程,它不应该太慢。

另一种解决方案是绘制所有可能的组合及其潜在的倾向。 这当然只需要一个搜索function,但也会在计算所有可能性和存储在某个地方时出现问题,可能在文件中。

有人建议我应该使用马尔可夫模型和/或库,尽管我对这种类型的数学并不太熟悉。

如何在Java中快速计算此过程?

示例>>>

只有一个序列ABC。

对于三个数字,机会开始相等所以它看起来像兰特(1,3)

如果A是结果,我们增加B的可能性,因为它是序列中的下一个字母。 让我们说它加倍。

所以现在机会是:A = 1/4,C = 1/4,B = 2/4

该函数现在看起来像rand(1,4),其中3和4的结果都代表选项B.

如果下一个结果是B,我们希望增加C的可能性,因为它是序列中的下一个字符,但是它是上次增加的两倍(指数)

机会现在是这样的:A = 1/6,C = 1/6,B = 4/6

该函数现在为rand(1/6),其中值3,4,5,6表示C.

如果需要,您可以编写C / C ++版本,并使用NDK(NDK的开销是从Java到C / C ++方法的JNI转换,但是一旦出现,它们就会快得多)

这是一个想法。 但是……我认为你不得不走得那么远(至少要获得一个适用于小型套装的版本)(也许后来转向NDK可能是LARGE套装更好的选择)

我认为你会更好地把它当作一个“整数分数”数组来处理,也就是……每组动作概率的二维数组。 意思是“顶行”上的分子和“底行”上的分母。 由于您要使用的集合可能很小,我认为每个节点都有自己的概率集的节点的简单链接列表将起作用。 (这些概率是从’那个’节​​点到S’到S’的转换表。)

int[][] probs = new int[100][2]; 

所以你可以把它想象成……

1 2 1 1

4 3 4 9

为整数整数运算的1 / 4,2 / 3,1 / 4,1 / 9。 这在算法的“某些”部分会更容易,因为您将能够为“removeColumn”制作好的辅助函数(make 0/0,并跳过其余的处理等等(或者你想表示它))和’adjustProbabilities()’

(如果你将分母作为单个整数(最小公分母),你可能能够使用单个数组的数组,但我可能会在使2D数组版本工作后进行优化)

然后只需编写“简单”的通用P,R和V方法 ,这些方法就每个节点的数据进行交互。 然后使它们具有良好的OO设计,可调节/可扩展/等。

然后只是“玩数字”的折扣因子等。

我认为这更像是“只是花点时间来测试它”,而不仅仅是关于任何真正复杂的数学算法的问题等等,因为从我看来,没有“明显”的地方来优化核心算法。