Prolog 序言篮(L、Smin、Smax、S)

Prolog 序言篮(L、Smin、Smax、S),prolog,Prolog,这里有一个Prolog的问题。考虑一组产品,每个产品都有一个给定的价格。为了简单起见,我们考虑每种产品的一个项目。假设您有一个配对、商品、价格的列表,表示商店中商品的名称及其对应的价格。名称为常量,价格为正整数。 例如: [(radio,130),(tv,940),(laptop,400),(bicycle,330)] 写一个谓词basketL,Smin,Smax,S,找到L中可用项目的子集S,使得S中的价格总和高于Smin,低于Smax。 所有符合问题规范的可能子集都应通过回溯逐一呈现 在P

这里有一个Prolog的问题。考虑一组产品,每个产品都有一个给定的价格。为了简单起见,我们考虑每种产品的一个项目。假设您有一个配对、商品、价格的列表,表示商店中商品的名称及其对应的价格。名称为常量,价格为正整数。 例如:

[(radio,130),(tv,940),(laptop,400),(bicycle,330)]
写一个谓词basketL,Smin,Smax,S,找到L中可用项目的子集S,使得S中的价格总和高于Smin,低于Smax。
所有符合问题规范的可能子集都应通过回溯逐一呈现

在Prolog中,使用累加器在大多数情况下都会使事情变得简单。累加器是递归传递并在每个递归步骤中更新的变量。每个递归步骤都可以检查变量的值并做出相应的决定。这里累加器是到目前为止添加到S中的项目的价格总和。显然,在开始时,该总和为零,因此我们首先通过引入累加器来简化一些事情:

basket(L,Smin,Smax,S) :-
    basket(L,Smin,Smax,0,S).
现在我们需要做一个篮子/5。有一种基本情况,其中所有项都被枚举。因此L是空的。然后,我们需要做的是检查总和是否在给定界限之间:

basket([],Smin,Smax,Sum,[]) :-
    Smin < S,
    S < Smax.
因此,我们决定添加元素,通过将值V添加到原始和来计算新的和Sum1,我们可以选择已经对值的上限执行边界检查。如果有大量物品,这会很有效:我们从行李开始溢出的那一刻起就停止搜索

最后,我们有另一个递归案例,我们只是决定丢弃该项。这是一个简单的问题:

basket([_|T],Smin,Smax,Sum,S) :-
    basket(T,Smin,Smax,Sum,S).
我们甚至不看头部,我们只是把列表的尾部反馈给篮子,我们不必更新总和,因为子集没有任何变化

综上所述,下面的程序应该可以做到这一点:

basket(L,Smin,Smax,S) :-
    basket(L,Smin,Smax,0,S).

basket([],Smin,Smax,Sum,[]) :-
    Smin < S,
    S < Smax.
basket([(I,V)|T],Smin,Smax,Sum,[(I,V)|S]) :-
    Sum1 is Sum+V,
    Sum1 < Smax,
    basket(T,Smin,Smax,Sum1,S).
basket([_|T],Smin,Smax,Sum,S) :-
    basket(T,Smin,Smax,Sum,S).

但是请注意,使用动态规划可以更有效地生成解决方案。

当我们从

库可用于强制执行约束:

basket(L,Smin,Smax,S) :-
    sublist(L,S),
    aggregate(sum(P), I^member((I,P),S), T),
    T>=Smin,T=<Smax.

?- basket([(radio,130),(tv,940),(laptop,400),(bicycle,330)],1600,2000,S).
S = [(tv, 940),  (laptop, 400),  (bicycle, 330)] ;
S = [(radio, 130),  (tv, 940),  (laptop, 400),  (bicycle, 330)].

这是家庭作业吗?你试过什么?请展示你试过的。你好。医生们说:首先,你要真诚地尝试自己解决问题。如果我们看不到你的工作,你的问题很可能会被嘘下台;它将被否决并关闭。请把密码寄出去。
sublist([], []).
sublist([_|XS], YS) :-
    sublist(XS, YS).
sublist([X|XS], [X|YS]) :-
    sublist(XS, YS).
basket(L,Smin,Smax,S) :-
    sublist(L,S),
    aggregate(sum(P), I^member((I,P),S), T),
    T>=Smin,T=<Smax.

?- basket([(radio,130),(tv,940),(laptop,400),(bicycle,330)],1600,2000,S).
S = [(tv, 940),  (laptop, 400),  (bicycle, 330)] ;
S = [(radio, 130),  (tv, 940),  (laptop, 400),  (bicycle, 330)].