List Prolog中的图

List Prolog中的图,list,prolog,graph-theory,knapsack-problem,List,Prolog,Graph Theory,Knapsack Problem,我不熟悉Prolog,我需要一些帮助:D 我学会了递归,我或多或少知道如何使用它。 我在图形方面有困难。我试图解决背包问题,所以我一步一个脚印 我的问题是: 我有一个类型列表,我想制作所有长度为n=3的子列表,然后选择一个值最大的。我想我需要一个函数来提取类型列表的头部,并将其传递给另一个递归计算子类的函数。我的想法是这样的: append([],L2,L2):- !. append([T|C],L2,[T|L3]):- append(C,L2,L3). genera_ext(_,[]

我不熟悉Prolog,我需要一些帮助:D

我学会了递归,我或多或少知道如何使用它。 我在图形方面有困难。我试图解决背包问题,所以我一步一个脚印

我的问题是: 我有一个类型列表,我想制作所有长度为n=3的子列表,然后选择一个值最大的。我想我需要一个函数来提取类型列表的头部,并将其传递给另一个递归计算子类的函数。我的想法是这样的:

append([],L2,L2):- !.
append([T|C],L2,[T|L3]):-
    append(C,L2,L3).

genera_ext(_,[],_).

genera_ext(Padre,[TT|CT],Figlio):-
    genera(Padre,TT,[TT|CT],Figlio),
    genera_ext(Padre,CT,[]).

genera(Padre,Elem,L_tipi,Figlio):-
    append(Padre,[Elem],Base),
    copy_term(Figlio,Base),
    length(Base,Lun),
    Lun =< 3,
    genera_ext(Base,L_tipi,Temp),
    total_ing(Temp,I_Temp),
    total_ing(Base,I_Base),
    I_Temp >= I_Base,
    copy_term(Figlio,Temp),
    nl,write("Figlio = "),write(Figlio).

genera(_,_,_,_).
inefficient([A1,A2,A3], Sum) :-
    art(A1, X),
    art(A2, Y),  A2 \= A1,
    art(A3, Z),  A3 \= A2, A3 \= A1,
    Sum is X+Y+Z.

inefficient_best(L, Sum) :-
    inefficient(L, Sum),
    \+ (inefficient(L2, Sum2), L2 \= L, Sum2 > Sum).
这个函数计算由xxx元素组成的列表的权重

total_ing([],0).
total_ing([X|C],I0):-
    art(X,N),
    total_ing(C,I1),
    I0 is I1 + N.
我叫它

genera_ext([],L_tipi, Figlio)
其中L_tipi是我可以选择的元素xxx的列表

我想生成长度为3的元素xxx的所有可能的子列表,并选择权重最大的一个

我想生成长度为3的元素xxx的所有可能的子列表,并选择权重最大的一个

这是一个经典的生成和测试问题。你可以用一种天真的方式来解决它,通过生成所有可能的艺术排列,像这样:

append([],L2,L2):- !.
append([T|C],L2,[T|L3]):-
    append(C,L2,L3).

genera_ext(_,[],_).

genera_ext(Padre,[TT|CT],Figlio):-
    genera(Padre,TT,[TT|CT],Figlio),
    genera_ext(Padre,CT,[]).

genera(Padre,Elem,L_tipi,Figlio):-
    append(Padre,[Elem],Base),
    copy_term(Figlio,Base),
    length(Base,Lun),
    Lun =< 3,
    genera_ext(Base,L_tipi,Temp),
    total_ing(Temp,I_Temp),
    total_ing(Base,I_Base),
    I_Temp >= I_Base,
    copy_term(Figlio,Temp),
    nl,write("Figlio = "),write(Figlio).

genera(_,_,_,_).
inefficient([A1,A2,A3], Sum) :-
    art(A1, X),
    art(A2, Y),  A2 \= A1,
    art(A3, Z),  A3 \= A2, A3 \= A1,
    Sum is X+Y+Z.

inefficient_best(L, Sum) :-
    inefficient(L, Sum),
    \+ (inefficient(L2, Sum2), L2 \= L, Sum2 > Sum).
称之为低效是非常仁慈的;它实际上是多次尝试每一个置换与每一个其他置换,它将生成多个解决方案,这些解决方案只是相同的序列置换。但它确实有效

接下来要考虑的是如何提高效率。没有明显的方法可以让测试更快,但是generate步骤肯定会创建大量浪费的组合。我们可以做的第一件事是使用findall/3将数据库具体化为一个列表,然后使用permutation/2生成要尝试的置换。但我觉得这也会很糟糕。我开始认为最好的方法是做一个谓词来生成一定长度的组合。我想不出一个更好的方法来使用内置谓词,也许有一个,我只是不够聪明,但我想到了这个:

combination(0, _, []) :- !.
combination(N, [X|Xs], [X|Ys]) :-
    succ(N0, N),
    combination(N0, Xs, Ys).
combination(N, [_|Xs], Ys) :-
    combination(N, Xs, Ys).
这会产生如下结果:

?- combination(3, [a,b,c,d,e], X).
X = [a, b, c] ;
X = [a, b, d] ;
X = [a, b, e] ;
X = [a, c, d] ;
X = [a, c, e] ;
X = [a, d, e] ;
X = [b, c, d] ;
X = [b, c, e] ;
X = [b, d, e] ;
X = [c, d, e] ;
false.
其工作方式基本上是要么获取列表中的当前项并将我们仍然需要的长度减少1,要么在不获取当前项的情况下重复出现。这很像会员/2

所以现在我们有了这个,我们就可以实现数据库,并且尝试所有的排列可以减少工作量。事实上,我们可以使用sort/2来查找赢家,假设您只需要一个结果,但我们首先需要一个helper函数:

art_cost(ArtList, Cost-ArtList) :-
    maplist(art, ArtList, CostList),
    sumlist(CostList, Cost).
art_cost/2计算艺术品列表的总成本,但返回一对:成本与实际艺术品列表。这种情况并不罕见,我们在下一步的预测中依靠它来找到最高成本:

best(ArtList, Cost) :-
    % materialize the list of all artworks
    findall(A, art(A,_), Art),

    % materialize the list of candidate combinations
    findall(Candidate, combination(3, Art, Candidate), Candidates),

    % compute the cost+list for all the candidate lists
    maplist(art_cost, Candidates, CostsWithArtLists),

    % sort the list, which will put them in order of cost
    % but lowest-to-highest
    sort(CostsWithArtLists, CostsLowToHigh),

    % flip the list around and deconstruct the highest 
    % as our result
    reverse(CostsLowToHigh, [Cost-ArtList|_]). 
使用libraryaggregate可能有一种更有效的方法,但我没能找到


顺便说一句,我认为您根本不需要在代码中使用copy_term/2,当我看到类似于一组匿名变量的术语时,我总是很怀疑:generas_uu、u、uu、uu、uu——在我看来,您的意思似乎不太可能是generas对任何四种事物都适用。

您如何称呼这一点?什么目标不起作用?你能告诉我们你到底希望做什么吗?2的代码在哪里?