6

我正在用 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 中,我可能可以通过跟踪每个对象的所有存储组合来实现此功能。我在想,通过在每次迭代中分小步分布跟踪过程,它不应该太慢。

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

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

如何在 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。

4

1 回答 1

1

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

这是一个想法。但是...我认为您不必走那么远(至少要获得适用于较小系列的版本)(也许稍后迁移到 NDK 可能是较大系列的更好选择)

我认为您最好将其视为“整数分数”数组,也就是……每组动作概率的二维数组。意思是“顶行”的分子和“底行”的分母。由于您要使用的集合可能很小,我认为每个节点都有自己的一组概率的简单的节点链接列表会起作用。(这些概率是从“那个”节点从 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”制作很好的辅助函数(制作 0/0,并跳过其余处理等(或者您想要表示它))和“调整概率()”

(如果您将分母设为单个 int(最低公分母),您可能能够摆脱单个分子数组,但我可能会在 2D 数组版本正常工作后对其进行优化)

然后只需编写与每个节点的数据交互的“简单”通用 P、R 和 V 方法。然后通过良好的 OO 设计使它们可调整/可扩展/等。

然后只是“玩数字”以获得折扣因子等。

我认为这更像是一个“只需花时间测试一下”,而不是关于任何真正复杂的数学算法等的问题,因为据我所知,没有“明显”的地方可以优化核心算法。

于 2015-12-19T07:26:43.553 回答