Выберите конкретные списки из списка списков - PullRequest
0 голосов
/ 30 апреля 2019

Я хочу установить предикат 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).

То, что я ожидаю, показано на следующем снимке экрана: Ожидаемый результат

1 Ответ

0 голосов
/ 30 апреля 2019

Я нахожу твой набор и танец немного запутанным.Моя реализация использует некоторые функции SWI из library(lists), но она будет загружаться автоматически.

Мы всегда должны начинать с базового случая:

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, чтобы дать нам заданную разницу.Поскольку мы знаем, что Package является подмножеством товаров, мы не покупаем ничего, что нам не нужно (то есть предложение за [1,2,5] не будет выбрано, если мы попытаемся купить [1,2,3,4], поскольку [1,2,5] не являетсяподмножество [1,2,3,4]).Затем мы можем просто повторить разность наборов и затем вести бухгалтерский учет того, что возвращается из рекурсивного вызова.

Я проверил с этой базой данных:

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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...