【发布时间】:2010-11-09 19:45:11
【问题描述】:
这是interview question。 “给定一个数字数组和另一个数字,计算是否可以使用标准数学技术操纵数字数组以等于给定的另一个数字。例如,给定 5 和 10,你能得到 50 吗?5 * 10 = 50,所以是的”。 (为简单起见,我们只假设算术运算)。
我建议使用蛮力搜索(带有一些分支和界限)。有意义吗?
【问题讨论】:
-
而且每个数字在表达式中只能使用一次,对吗?
这是interview question。 “给定一个数字数组和另一个数字,计算是否可以使用标准数学技术操纵数字数组以等于给定的另一个数字。例如,给定 5 和 10,你能得到 50 吗?5 * 10 = 50,所以是的”。 (为简单起见,我们只假设算术运算)。
我建议使用蛮力搜索(带有一些分支和界限)。有意义吗?
【问题讨论】:
蛮力听起来是解决这个问题的有效方法。但是蛮力是不知情的搜索...当您到达搜索树中的一个分支时,它不会做出有根据的猜测。
您可能想要调查的是是否有heuristic functions 可以帮助您进行搜索知情。启发式函数查看状态并估计您离目标的距离。如果你能找到一个有效的启发式函数,你可以应用类似A*的算法。
请注意:这似乎不是一个定义启发式的简单问题。
【讨论】:
Haskell 编程,第 11 章:倒计时问题
【讨论】:
我会问
Numbers 是整数吗?standard mathematical techniques是指哪个?
等
【讨论】:
我认为这是有道理的。
您可以利用乘法之间的对称性来进一步修剪您的树。 a * b = b * a。
【讨论】:
解决此问题的另一种方法是使用genetic algorithms。您的总体将作为插入数组元素之间的随机运算符开始。
让S 成为您需要拨打的号码。您的适应度函数可以是|S - Value(E[i])|,其中Value(E[i]) 是在您的总体中评估i-th 表达式后的值。
您的变异运算符可以简单地将一个运算符更改为另一个,并且您的交叉函数可以将一个表达式左侧的运算符与另一个表达式右侧的运算符结合起来。
也许您可以找到更复杂的函数,效果更好,遗传算法需要一些猜测才能获得最佳结果。
我不知道这与蛮力相比如何,但这是一种不同的解决方案,我认为它会让你在面试中脱颖而出,因为每个人都可以看到蛮力解决方案。
如果您只需要一个足够好的解决方案(不完全是S,但足够接近),那么这绝对应该比蛮力更快。在我实现的少数遗传算法中,我注意到它们可以快速接近接近最优的解决方案,但速度相当慢,如果你想要最优解决方案,有时甚至会卡住。
【讨论】:
第一个非常重要的问题是:是否允许任何一元运算?也就是说,我可以“免费”将 x 更改为 -x、1/x、x! 或 sqrt(x) 吗?
如果是这样,天真的分支搜索不会终止,因为一元运算的使用次数没有先验限制。如果不是,那么简单的搜索可能就可以正常工作。
这是一个有趣的策略,如果不是一个有效的策略:为正在使用的算术请求或生成 BNF 语法。破解类似
的规则::= 5 | 10
然后使用该语法来开发使用少于 20 条语法规则获得的所有可能的表达式。评估它们。这将保证有界,并且会生成所有在该语言中有效的“不太复杂”的表达式。
【讨论】: