以下是设置:
我有一个可以成功或失败的算法。 我希望它以尽可能高的概率成功。 成功的可能性取决于一些参数(和一些外部环境):
struct Parameters {
float param1;
float param2;
float param3;
float param4;
// ...
};
bool RunAlgorithm (const Parameters& parameters) {
// ...
// P(return true) is a function of parameters.
}
如何(自动)找到对RunAlgorithm调用次数最少的最佳参数? 我会对readl库特别满意。
如果您需要有关我的具体案例的更多信息:
澄清:
最佳参数必须在一夜之间自动发现,并在白天使用。 外部环境每天都在变化,因此一劳永逸地计算它们是不可能的。
更多说明:
RunAlgorithm实际上是游戏算法。它对抗固定的对手整场比赛(围棋或国际象棋)。我可以在一夜之间玩1000场比赛。每晚都是其他对手。
我想看看不同的对手是否需要不同的参数。
RunAlgorithm在某种意义上是平滑的,即稍微改变参数只会稍微改变算法。
可以通过具有相同参数的大量样本来估计成功的可能性。 但是在不改变参数的情况下运行如此多的游戏成本太高。
我可以尝试独立优化每个参数(这会导致每个参数100次运行),但我想有一些依赖项。
整个问题是明智地使用稀缺数据。
游戏非常随机化,没问题。
答案 0 :(得分:3)
也许您正在寻找genetic algorithms。
答案 1 :(得分:2)
为什么不让程序与自己斗争?取一些向量v(参数)并让它与v +(0.1,0,0,0,...,0)对抗,比如说15次。然后,取得胜利者并修改另一个参数,依此类推。如果有足够的运气,你将获得一个强大的球员,能够打败其他大多数人。
以前的答案(在编辑问题后大部分内容都无法解决):
有了这些假设和那种普遍性,你就什么也得不到(除了可能不可能的结果)。
基本问题:您是否可以更改算法以使其返回成功的概率,而不是单个实验的结果?然后,使用适当的optimization技术(没有人会告诉你哪些在这样的一般假设下)。在Haskell中,您甚至可以更改代码,以便在简单的情况下(probability monad)找到概率,而不是给出单个结果。正如其他人提到的,您可以使用遗传算法将概率作为适应度函数。如果您有一个公式,使用computer algebra system来找到最大值。
成功的可能性是参数的平滑函数,并具有单一的全局最优。
顺畅还是连续?如果平滑,您可以使用微积分(Lagrange multipliers?)。您甚至可以在代码变化很小的情况下(假设您的编程语言足够通用),使用automatic differentiation自动计算导数。
那个复杂的?这将允许您在许多浮点数中检查两个可能的值(2 10 = 1024)。你甚至不会确定数量级,甚至数量级的数量级。我将在一夜之间运行调优,我可以处理大约1000次调用Run算法。
大约有10个参数,其中大多数是独立可调的(但有些是相互依赖的)
如果你知道什么是独立的,修复一些参数并改变那些独立于它们的参数,比如分而治之。显然,用5个参数调整两个算法要好得多。
除非你提供更多细节,否则我正在低估这个问题。这对于学术问题来说噪音太大,对于现实世界的问题没有足够的数据。
答案 2 :(得分:2)
你遇到的主要问题是,有10个参数,1000次运行几乎没有,因为对于每次运行,你所拥有的只是一个真/假的结果,而不是与参数相关的P(成功)。
这是一个想法,一方面,可以充分利用你的1000次运行,另一方面,也说明你的问题难以处理。让我们假设十个参数确实是独立的。为每个参数选择两个值(例如“高”值和“低”值)。有1024种方法可以选择这些值的唯一组合;为每个组合运行您的方法并存储结果。完成后,您将为每个参数的每个值进行512次测试运行;在独立性假设下,可能会对每个值的条件成功概率给出合适的估计。对该数据的分析应该为您提供有关如何设置参数的一些信息,并可能建议您对未来夜晚的“高”和“低”值进行改进。我的想法是在这里挖掘ANOVA作为一种可能有用的统计工具。
非常含糊的建议......但是,正如已经指出的那样,这是一个相当模糊的问题。
答案 3 :(得分:1)
专门用于调整游戏代理的参数,您可能对CLOP感兴趣
答案 4 :(得分:0)
不确定我是否理解正确...
如果您可以选择算法的参数,是否意味着您可以选择一次?
然后,你可以简单地说:
或者,如果每次运行的最佳值都发生变化...... 您在寻找遗传算法类型的方法吗?
答案 5 :(得分:0)
这个问题的答案取决于:
这个问题看起来很自然的一种方法是Hill Climbing。
实施的一种可能方式是从几个点开始,并计算他们的“等级”。然后找出下一个点的有利方向,并尝试“提升”。
我在这个问题中看到的主要问题,就像你提出的那样,是大范围的参数值,以及运行结果是布尔值(而不是数字等级)的事实。这将需要许多运行来确定一组所选参数是否确实是好的,另一方面,还有一大组参数值尚待检查。只检查所有方向将导致(太多?)大量运行。