如何使用局部变量作为参数调用foreach中的函数?

问题描述 投票:1回答:1

我有一个背包问题要在B-Prolog中解决。我必须写一些类似的东西:

knapsack(X, Indexes, Quantity, Weights, Values, Capacity)

X - 包含放入包中的第i项数量的数组 索引 - [0,...,NumOfItems-1] 数量 - 包含可用ith项数量的数组 重量 - 第i个位置上每个项目的重量数组(仅1个项目) 值 - 每个项目的值的数组(仅1项) 容量 - 限制行李容量

必须使用谓词来解决任务:

get([X|_], 0, X).
get([_|X], I, Y) :- I>0, I1 is I-1, get(X, I1, Y).

它返回第i个索引上的元素,考虑它们可以从0开始。然后Y具有该元素的值。 此外,我们必须最大化项目值。我试图让它不仅适用于固定数量的物品。 因为我只是Prolog的初学者,所以我有一个想法,但它当然没有。

knapsack(X, Indexes, Quantity, Weights, Values, Capacity) :-
    /*
        Find the last index of items, 
        Calculate NumOfItems as last index+1,
        Make an array X with NumOfItems elements,
        Define domen for each item (ith element in X) as 0..NumOfThatItem
        (meaning I can take zero or more up to the max number of that element that is avaliable)
    */
    last(Indexes, Elem),
    NumOfItems is Elem+1,
    length(X, NumOfItems),
    foreach(I in 1..NumOfItems, get(Quantity, I, K), X[I]::0..K), 

    /*
        Set up the constraint that sum of item weights must not be bigger than bag capacity
    */
    sum([X[I]*T : I in 1..NumOfItems], get(Weights, I, T)) #=< Capacity,

    /*
        Maximize the values of items in the bag, and find all possible combinations for it
    */
    labeling([maximize( sum([X[I]*V : I in 1..NumOfItems, get(Values, I, V)]))], X),

    /*
        This is the part of a task, to write out the Profit we made by taking those items,
        and the overall weight that we have put in the bag.
    */
    Profit is sum([X[I]*V : I in 1..NumOfItems, get(Values, I, V)]),
    Weight is sum([X[I]*T : I in 1..NumOfItems, get(Weights, I, T)]),
    nl,
    write('Profit: '), write(Profit), nl,

    write('Weight: '), write(Weight), nl
.

我正在使用B-Prolog版本8.1,它可以在这个link上下载( 您可以复制我的代码并将其放在您选择安装它的位置的BProlog文件夹中。当你打开/启动bp应用程序时:

cl('path_to_my_code.pro').

示例我对此问题的解释如下:

knapsack(X, [0,1,2,3], [1,1,1,4], [50,10,5,1], [1000,2000,100,1], 63).

这应该给我们:

Profit: 3003
Weight: 63
X = [1,1,0,3]

我得到以下内容:

***illegal_local_variables(get([1,1,1,4], _f8, _fc))

我得出结论,他不承认I是一个数字。如果您有任何书籍或文章或与此相关的任何内容,请分享。

该怎么做?请帮忙...

感谢您的时间

prolog constraints
1个回答
1
投票

此时因为你得到错误,你应该测试get/3谓词,看看这是否正常工作。问题在于:

I>0, I1 is I-1, get(X, I1, Y).

因为你用I作为变量调用get,I>0会产生实例化错误,相反你可以写:

get([X|_], 0, X).
get([_|X], I, Y) :- get(X, I1, Y), I is I1+1, I>0.
© www.soinside.com 2019 - 2024. All rights reserved.