我想要设置一个谓词to_buy(货物、报价、价格、质量),这在列表提供时是正确的,包含总价和总质量,但我想要的正是商品的产品。如果没有能够准确涵盖商品产品的报价列表,我就什么也不会买,谓词也失败了。例如:
我试着找出所有属于包裹的商品子集,并将它们存储在一个列表中,如果我附加它们并对它们进行排序,我就会找到它们返回的商品。我有这样的包裹:
packages([products],Price,Quality).
packages([1,2,3],10,5).
to_buy(Goods,Offers,Price,Quality):-
findall(X,( subset(X,Goods), package(X,Price,Quality)),List),
setof( (X,Y),
( member(X,List),
member(Y,List),
append(X,Y,AList),
msort(AList,Goods)
),Offers).
我所期望的是在下面的截图中:预期产出
发布于 2019-04-30 15:23:31
我觉得你的舞蹈和分类舞有点让人困惑。我的实现使用了来自library(lists)
的一些SWI函数,但是它会自动加载。
我们必须从一个基本案例开始:
to_buy([], [], 0, 0).
这表明,如果我们不买任何东西,没有报价,价格和质量是零。现在是递归案例:
to_buy(Goods, [Package|OtherPackages], TotalPrice, TotalQuality) :-
%% choose a package
package(Package, Price, Quality),
%% this package is a subset of the goods we need
subset(Package, Goods),
%% after buying this package, we will still need RemainingGoods
subtract(Goods, Package, RemainingGoods),
%% recur on the remaining goods
to_buy(RemainingGoods, OtherPackages, Subtotal, SubtotalQuality),
TotalPrice is Subtotal + Price,
TotalQuality is SubtotalQuality + Quality.
所以,这里的主要想法也是使用subtract/3
给出设置的差异。因为我们知道包是商品的一个子集,所以我们不会购买任何我们不需要的东西(也就是说,如果我们试图购买[1,2,5]
,因为[1,2,5]
不是[1,2,3,4]
的子集,那么就不会选择给[1,2,5]
的报价)。然后,我们可以简单地重复设置的差异,然后对递归调用返回的内容进行簿记。
我用这个数据库进行了测试:
package([2,4], 7, 5).
package([1,3], 3, 8).
这个问题是:
?- to_buy([1,2,3,4], Offers, Price, Quality).
Offers = [[2, 4], [1, 3]],
Price = 10,
Quality = 13 ;
Offers = [[1, 3], [2, 4]],
Price = 10,
Quality = 13 ;
false.
https://stackoverflow.com/questions/55923163
复制相似问题