【发布时间】:2014-06-06 02:50:45
【问题描述】:
前段时间,我为 Codeforces 2014 年愚人节比赛创建了一个问题 - “Feed the Golorp”:http://codeforces.com/contest/409/problem/I。 请阅读提供的链接上的问题说明。
这个问题本来打算由完全不了解 Prolog 的人来解决。比赛期间只有 3 人成功解决了这个问题 - 使用 Java、Python 和 C++。
主要挑战是了解需要做什么。对于有一些 Prolog 经验的人来说,这应该是显而易见的
像?(_-_/___*__):-___>__. 这样的golorp 名称定义了一个Prolog 谓词,任务是找到满足谓词的变量的最小值。
有一些细节:再次,请阅读问题说明。
其实在了解了目标之后解决问题并不是那么简单。算法上的任务是根据约束对变量进行拓扑排序。 Golorp 的名称最长可达 1024 个字符,因此需要相当高效的算法。
我在 Python 中使用正则表达式编写了我的参考解决方案。但比赛结束后,我开始想知道如何在 Prolog 中解决这个问题。
由于 golorp 名称的长度可能长达 1024 个字符,因此仅使用 Prolog 回溯来蛮力所有可能性看起来都不可行 - 可能需要约束逻辑编程。
如果我可以从不等式中提取所有变量列表和变量对列表,我可以解决它。例如在 ECLiPSe CLP 中:
:- lib(ic).
solve(Vars, Ineqs, Result) :-
Vars :: 0..9,
( foreach((A, B), Ineqs) do
A #< B ),
labeling(Vars),
concat_string(Vars, Result).
[eclipse]: Vars = [__, ___, __, ___], Ineqs = [(__, ___)], solve(Vars, Ineqs, Result).
Vars = [0, 1, 0, 1]
__ = 0
___ = 1
Ineqs = [(0, 1)]
Result = "0101"
但我不确定如何在没有太多代码的情况下从?(__+___+__-___):-___>__. 获取Vars = [__, ___, __, ___] 和Ineqs = [(__, ___)]。
term_variables/2 丢失重复变量。 DCG?
或者有完全不同的更好的方法来解决 Prolog 中的难题吗? (不一定在 ECLiPSe CLP 中)。
更新:几个大的例子来测试:
?(_____________________*_________________________*________________________*___________________*_________________*__________________*___________________________*___*__*____________________*_________________________*_______________*____*___________*_____________*______*_____*_______________*____________*__________________*___________________________*___________________________):-_____>__,_______________<___________________,__>___________,________________________>______,_____________>______,____________________<_________________________,_________________<__________________,_____________<___,____<_________________________,______>____________,________________________>_________________________,_____<____________________,__<____________,_____________________>____________,__________________>_______________,_____>___,___________<_______________,_________________________>____,____<___________________,________________________>___________________________,____________>___________________________,_____<_______________.
结果:3898080517870043672800
?(___*__*_____*____*_____*___*___*_____*___*___*___*__*___*_____*___*_____*____*___*____*_____*_____*____*_____*____*____*____*___*___*__*___*____*__*_____*_____*____*____*___*__*____*___*___*____*_____*_____*____*___*__*_____*____*__*_____*___*___*___*_____*____*___*_____*_____*___*___*___*____*__*_____*_____*__*___*__*__*_____*____*_____*___*__*_____*_____*__*____*___*____*_____*_____*___*___*___*_____*__*__*__*__*___*_____*__*___*___*____*_____*___*__*_____*_____*_____*_____*_____*__*__*___*___*_____*____*___*__*___*__*___*_____*__*_____*_____*_____*____*____*___*___*_____*____*____*__*__*_____*___*__*___*_____*_____):-____>_____,___>____.
结果:20010220222020201210010111220210001120122100120010022201200222100002000102000012100222000002002210200000000220120202002011
【问题讨论】:
标签: prolog metaprogramming constraint-programming