【问题标题】:Knapsack Find Max背包查找最大
【发布时间】:2016-08-24 21:46:02
【问题描述】:

我在一门课程中学习prolog,我有一个练习来解决背包问题。 我成功编写了代码,但我不知道如何从所有可能的解决方案中找到最大利润。

这是代码

between( Lo, Hi, Nu ) :-
   (  integer( Lo ),
      integer( Hi ),
      integer( Nu )
   -> Nu >= Lo,
      Nu =< Hi
   ;  integer( Lo ),
      integer( Hi ),
      var( Nu )
   -> repeat( Lo, Hi, Nu )
   ).


add_list(A, [], [A]).
add_list(A, L, [A|L]).
add_list([], L, L).
add_list([H|T], L, L1) :- add(H, L2, L1), add_list(T, L, L2).


knapsack_go(L, Limit, Amounts, Profit):-
    knapsack(L, Limit, Amounts, 0, Profit).
knapsack([], _, _, ProfitSoFar, ProfitSoFar).
knapsack([Item-Size-Value| Tail], Limit, Amounts, ProfitSoFar, Profit):-
    Upper is Limit//Size,
    between(0, Upper, A),
    Profit2 is (A * Value) + ProfitSoFar,
    Limit2 is Limit - (A*Size),
    add_list(A, Amounts2, Amounts), 
    knapsack(Tail, Limit2, Amounts2, Profit2, Profit).

我怎样才能最大化利润?

编辑: 这是我的运行方式:

knapsack_go([a-7-9, b-11-14, c-19-24], 100, Amounts, Profit).

我想我在问如何让 prolog 生成所有解决方案,因为现在我得到了一个解决方案,我可以按下空间来获得下一个解决方案。 那么我如何生成所有解决方案,将它们保存在列表或其他东西中并选择最佳利润。

更多信息 - L 是 Item-Size-Value 的列表,Limit 是包中的剩余空间,Amounts 是 Item1 数量、Item2 数量等的列表

【问题讨论】:

  • 如果你的实现为你提供了所有个解决方案,没有特定的顺序,你总是可以把它们全部收集起来,然后挑选出最大值。例如,请参阅here。顺便说一句,您似乎正在重写每个 Prolog 中都可用的谓词(并且已经存在了几十年)。
  • 您在哪个列表中收集您的解决方案??
  • @coder 这将是knapsack_go/4 的最后一个参数,我猜。问题中应包含从顶层调用程序的示例。
  • 似乎 knapsack_go/4 的最后一个参数收集了整体利润,但我认为元素列表是数量。我不认为背包会找到所有可能的解决方案,无论如何我同意应该包括一个例子......
  • add/3 是 win-prolog 的内置函数吗?我认为这可能更简单:between(L,H,N) :- repeat(L,H,N).

标签: prolog win-prolog


【解决方案1】:

你可以使用:

findall(Profit-Amounts,knapsack_go([a-7-9, b-11-14, c-19-24], 100, Amounts, Profit),L).

这将收集列表 L 中的所有解决方案,其中 L 将是 [Profit-Amounts|T] 形式的列表。

现在,要找到您可以写的最大利润:

  max([First | Rest], Result) :- First =FirstP-_
  maxC(Rest, First,FirstP, Result).

  maxC([], Sofar, _, Sofar).

  maxC([First | Rest], _, Max, Result) :-
  First = FirstP-_
  Max =< FirstP,
  maxC(Rest, First, FirstP,Result).

  maxC([First | Rest], Sofar,Max,Result):-
  First = FirstP-_
  Max > FirstP,
  maxC(Rest, Sofar, Max, Result).

如果您想要在 FirstP-Amounts 上方使用的金额列表,这将返回利润的最大值,其中现在是谓词 max,maxC 中的 FirstP-_。

【讨论】:

  • 谢谢!我还有一个问题,在我的 add_list 中,我收到了一次与 [a,b,c] 相同的内容,另一次收到了 [a,b,c|_1111] 的内容 - 为什么会这样?
  • @Infested,对此我不确定,因为我无法运行您的代码,因为我使用的是 swi-prolog 并且它无法识别重复谓词,因此无需运行程序我看不出问题出在哪里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多