big*_*zer 6 java performance artificial-intelligence reinforcement-learning markov-models
我正在用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中,我可以通过跟踪每个对象的所有存储组合来实现此功能.我在想通过在每次迭代中以小步骤分配跟踪过程,它不应该太慢.
另一种解决方案是绘制所有可能的组合及其潜在的倾向.这当然只需要一个搜索功能,但也会在计算所有可能性和存储在某个地方时出现问题,可能在文件中.
有人建议我应该使用Markov模型和/或库,尽管我对这种类型的数学并不太熟悉.
如何在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 可能是大型集合的更好选择)
我认为你最好将其视为“整数分数”数组,又名......每组动作概率的二维数组。意思是“顶行”上的分子和“底行”上的分母。由于您要使用的集合可能很小,因此我认为一个简单的节点链接列表(其中每个节点都有自己的概率集)是可行的。(这些概率是从“那个”节点从 S 到 S' 的转换表。)
int[][] probs = new int[100][2];
Run Code Online (Sandbox Code Playgroud)
所以你可以把它想象成...
1 2 1 1
4 3 4 9
如 1/4、2/3、1/4、1/9 的整数运算。这在算法的“某些”部分会更容易,因为您将能够为“removeColumn”创建很好的辅助函数(制作0/0,并跳过其余处理等(或者您想要表示它的方式))和“调整概率()”
(如果你将分母设置为单个 int (最小公分母),你可能能够摆脱单个分子数组的困扰,但我可能会在 2D 数组版本工作后对此进行优化)
然后只需编写与每个节点的数据进行交互的“简单”通用 P、R 和 V 方法即可。然后通过良好的面向对象设计使它们可调整/可扩展等。
然后只需“玩弄数字”以获得折扣系数等。
我认为这更多的是“花时间测试一下”,而不是关于任何真正复杂的数学算法等的问题,因为从我看来,没有“明显”的地方可以优化核心算法。
| 归档时间: |
|
| 查看次数: |
419 次 |
| 最近记录: |