我正在用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。
答案 0 :(得分:1)
如果需要,你可以编写一个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()'
(如果你将分母设为单个int(最小的公分母),你可能可以使用单个数组的数组,但我可能会在使2D数组版本工作后进行优化)< / p>
然后只需为每个节点编写与该数据交互的'simple' generic P, R, and V methods。然后使用可靠的OO设计使它们可调节/可扩展/等。
然后只是'玩数字'来获得折扣因子等等。
我认为这更像是“只是花点时间来测试它”,而不仅仅是关于任何真正复杂的数学算法的问题,等等。因为从我看来,没有'明显'的地方来优化核心算法。