从prolog中列举的事实创建一个列表



问题是:我们正在做一个学校测试。给定一定的时间和所需的分数,创建一个可能的问题组合列表,以在时间窗口中获得分数。

我一直在摸索Q,无法获得Q选项的列表。我知道这个错了,但我找不到合适的组合。

事实采用以下格式(项目编号、分数、解决问题的时间(分钟((。

test(1 , 1.5 , 22).
test(2 , 3.0 , 17).
test(3 , 1.5 , 13).
test(4 , 0.5 , 12).
test(5 , 0.5 , 11).
test(6 , 1.5 , 16).
test(7 , 0.5 , 10).
test(8 , 1   , 21).
set(Q, 0, 0) :- !.
set(Q, Points, Time) :- 
Points > 0, 
Time > 0, 
test(Q,P,T), 
P1 is P - Points, 
T1 is T - Time, 
set([Q],P1,T1).

在您的尝试中存在许多问题,我在下面的代码中已经解决了这些问题:

  • 您需要一个测试列表来跟踪您收集的内容(使用递归锚点中的回溯运算符不会阻止解释器在每一步中再次选择相同的测试(,并需要另一个测试来返回结果。需要一个附加参数。然后,在每个步骤中,+member(Q,Qs)都会检查是否已经选择了此测试
  • 要精确匹配点,需要在锚点中使用float(0.0(
  • 下一步要使用的点/时间计算顺序错误,结果为负值
  • 精确匹配时间可能是一个非常强烈的要求。我允许使用更少的时间作为一种选择,这样我就可以在不进行太多测试的情况下得到一些结果
set(Qs, 0.0, _, Qs) :- !.
set(Qs, Points, Time, Result) :- 
Points > 0.0, 
Time > 0, 
test(Q,P,T), 
+member(Q,Qs),
T < Time,
P1 is Points - P, 
T1 is Time - T, 
set([Q|Qs],P1,T1, Result).

120分钟内得到8分的示例查询给出了以下输出(使用SWI-Prolog(。当然,这仍然可以通过对列表进行排序来改进。

?- set([],8,120,Res).
Res = [8, 5, 4, 3, 2, 1] ;
Res = [6, 4, 3, 2, 1] ;
Res = [8, 7, 4, 3, 2, 1] ;
Res = [5, 8, 4, 3, 2, 1] ;
...

最新更新