Java 中的马尔可夫模型决策过程
Markov Model descision process in 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 中,我可能可以通过跟踪每个对象的所有存储组合来实现此功能。我在想,通过在每次迭代中分小步分布跟踪过程,应该不会太慢。
另一种解决方案是映射所有可能的组合及其潜在倾向。这当然只需要一个搜索功能,但也会在计算所有可能性和存储在某个地方(可能在文件中)时出现问题。
有人建议我应该使用马尔可夫模型 and/or 库,虽然我对这种类型的数学不太熟悉。
如何在 Java 中快速计算这个过程?
.
例子>>>
只有一个序列ABC。
对于三个数字,机会开始时是相等的,所以它看起来像 rand(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 可能是大集合的更好选择)
我认为您最好将其视为 'whole number fractions' 数组,也就是...每组动作概率的二维数组。意思是 'top row' 上的分子和 'bottom row' 上的分母。由于您要使用的集合可能很小,我认为一个简单的节点链表(其中每个节点都有自己的一组概率)会起作用。 (这些概率是 'that' 节点从 S 到 S' 的转换表。)
int[][] probs = new int[100][2];
所以你可以把它想象成...
1 2 1 1
4 3 4 9
作为整数运算的 1/4、2/3、1/4、1/9。这在算法的 'some' 部分会更容易,因为您将能够为“removeColumn”创建很好的辅助函数(创建 0/0,并跳过其余的处理等(或者您想要表示它) )) 和 'adjustProbabilities()'
(如果您将分母设为单个 int(最小公分母),您也许可以使用单个分子数组,但我可能会在让 2D 数组版本工作后将其作为优化)
然后只需为每个节点编写与该数据交互的 'simple' generic P, R, and V methods。然后让它们adjustable/extensible/etc具有良好的面向对象设计。
然后 'play with the numbers' 折扣系数等
我认为这更多的是 'just take the time to test it out' 而不是关于任何真正复杂的数学算法等的问题,因为据我所知,没有 'obvious' 可以优化核心算法的地方.
我正在 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 中,我可能可以通过跟踪每个对象的所有存储组合来实现此功能。我在想,通过在每次迭代中分小步分布跟踪过程,应该不会太慢。
另一种解决方案是映射所有可能的组合及其潜在倾向。这当然只需要一个搜索功能,但也会在计算所有可能性和存储在某个地方(可能在文件中)时出现问题。
有人建议我应该使用马尔可夫模型 and/or 库,虽然我对这种类型的数学不太熟悉。
如何在 Java 中快速计算这个过程?
.
例子>>>
只有一个序列ABC。
对于三个数字,机会开始时是相等的,所以它看起来像 rand(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 可能是大集合的更好选择)
我认为您最好将其视为 'whole number fractions' 数组,也就是...每组动作概率的二维数组。意思是 'top row' 上的分子和 'bottom row' 上的分母。由于您要使用的集合可能很小,我认为一个简单的节点链表(其中每个节点都有自己的一组概率)会起作用。 (这些概率是 'that' 节点从 S 到 S' 的转换表。)
int[][] probs = new int[100][2];
所以你可以把它想象成...
1 2 1 1
4 3 4 9
作为整数运算的 1/4、2/3、1/4、1/9。这在算法的 'some' 部分会更容易,因为您将能够为“removeColumn”创建很好的辅助函数(创建 0/0,并跳过其余的处理等(或者您想要表示它) )) 和 'adjustProbabilities()'
(如果您将分母设为单个 int(最小公分母),您也许可以使用单个分子数组,但我可能会在让 2D 数组版本工作后将其作为优化)
然后只需为每个节点编写与该数据交互的 'simple' generic P, R, and V methods。然后让它们adjustable/extensible/etc具有良好的面向对象设计。
然后 'play with the numbers' 折扣系数等
我认为这更多的是 'just take the time to test it out' 而不是关于任何真正复杂的数学算法等的问题,因为据我所知,没有 'obvious' 可以优化核心算法的地方.