【问题标题】:Prolog out of global stackProlog 退出全局堆栈
【发布时间】:2011-06-08 19:04:41
【问题描述】:

大家好,我是 Prolog 的新手。 我试图在不重复的情况下组合第 3 类中的 1000 个元素。 我已经完成了代码,但是我有出栈问题。

member(T, [T|R], R) :- !.
member(T, [_|L], R) :- member(T, L, R). 

last_element([H], H) :- !.
last_element([H|[X]], X) :- !.
last_element([H|T], R) :- last_element(T, R). 


    macronutrienti(1).
    macronutrienti(2).
    macronutrienti(3).
    and so on

percentuale_macronutrienti(Alimento, R) :-
    macronutrienti(Alimento),
    R = Alimento.

combina(NRAlimenti, RIS) :-
    findall(PM, percentuale_macronutrienti(Alimento, PM), PMR),
    f1(NRAlimenti, PMR, PMR, RIS), !.

f1(1, RParz, PMR, RParz) :- !.
f1(Index, RParz, PMR, RIS) :-
    Index1 is Index - 1,
    g2(RParz, PMR, RIS1, RIS1),
    f1(Index1, RIS1, PMR, RIS).
f1(Index, RParz, PMR, RIS) :-
    Index1 is Index - 1,
    g1(RParz, PMR, RIS1, RIS1),
    f1(Index1, RIS1, PMR, RIS).

g1([A|[TA]], A1, OldR, R) :- 
    q([A], L1, A1), 
    h1(A, L1, OldR, OldR), !.
g1([A|T], A1, Risultato,  R) :- 
    q([A], L1, A1), 
    h1(A, L1, OldR, OldR),
    append(OldR, TOldR,Risultato),
    g1(T, A1, TOldR, R).

q(A, R, A1) :- last_element(A, LastElement), member(LastElement, A1, R).

g2([A|[TA]], A1, OldR, R) :-
    q(A, L1, A1), 
    h2(A, L1, OldR, OldR), !.
g2([A|T], A1, Risultato, R) :-
    q(A, L1, A1),  
    h2(A, L1, OldR, OldR),
    append(OldR, TOldR, Risultato),
    g2(T, A1, TOldR, R).

h1(_, [], _,  _) :- !.
h1(Alimento, [Alimento1], [OldM],  R) :- append([Alimento], [Alimento1], OldM).
h1(Alimento, [Alimento1|T1], [OldM|TOldM], NewM) :- 
    append([Alimento], [Alimento1], OldM),
    h1(Alimento, T1, TOldM, NewM).

h2(_, [], _,  _) :- !.
h2(Alimento, [Alimento1], [OldM],  R) :- append(Alimento, [Alimento1], OldM).
h2(Alimento, [Alimento1|T1], [OldM|TOldM], NewM) :- 
    append(Alimento, [Alimento1], OldM),
    h2(Alimento, T1, TOldM, NewM).

:- combinew(3,R).

怎么了?提前谢谢你

【问题讨论】:

  • prolog 可能陷入某种无限循环或搜索。使用跟踪检查 prolog 尝试找到解决方案的方式。
  • 相同的代码适用于 400 个宏量营养素(n),但如果我插入 1000 个宏量营养素(n),prolog 就会出栈。问题不是无限循环,但我认为是递归调用次数。
  • 在这种情况下,您可以尝试扩展堆栈:swi-prolog.org/pldoc/doc_for?object=set_prolog_stack/2
  • 我已经扩展了堆栈,但问题仍然存在。其他想法?
  • 如果你不能扩展它,我担心你需要提高算法的性能,这样它就不会消耗这么多的内存

标签: list stack prolog overflow


【解决方案1】:

这是一个更短的代码,(我认为)与您的代码相同:

combine(N,L) :-
    findall(PM, macronutrienti(PM), PMR),
    findall(L0, combine0(N, PMR, L0), LL).

combine0(0, _, []) :- !.
combine0(I, PMR, [X|LR]) :-
    member(X, PMR, PMRR),
    I1 is I-1,
    combine0(I1, PMRR, LR).

member(T, [T|R], R).
member(T, [_|L], R) :- member(T, L, R). 

(我稍微改变了你的member/3谓词)

但是,这仍然不能解决您的堆栈溢出问题。基本上,如果我正确理解了您的问题,您希望从 1000 个元素的集合中提取所有长度为 3 的排序子集。您正在查看的集合数是 1000!/(1000-3)!,即 997.002.000 个长度为 3 的列表。数量很多,所以如果您需要大量堆栈。

如果您不需要完整列表来继续,请更改您的工作流程以一次生成一个此类项目,然后立即处理它,然后继续下一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    相关资源
    最近更新 更多