0

Sicstus Prolog でさまざまなラベル付けヒューリスティックを比較するためのいくつかの実験に取り組んでいます。

しかし、「リソース エラー: メモリ不足」が発生し続けます。

テストコードで何か間違ったことをしていると確信しています。

次のコードは私の問題を再現します:

:- use_module(library(clpfd)).
:- use_module(library(lists)).

atest( R, C ):-
    X is R * C,
    length( M, X),
    domain( M, 0, X),
    all_distinct( M ),

    statistics(walltime, [_,_SinceLast]),
    labeling( [],M ),
    statistics(walltime, [_,SinceLast]),

    write('Labeling time: '), write(SinceLast),write('ms'),nl.


% Testcode for looping through alot of variations and run one test for each variant
t1:-
    Cm = 1000,
    Cr = 1000,
    (
    for(C,0, Cm),
    param([Cm,Cr])
    do
        (
        for(R, 0, Cr ),
        param([C])
        do
            atest( C, R )
        )
    ).      

t1 述語を呼び出した直後に、「リソース エラー: メモリ不足」という例外が発生します。

リソースを解放するために atest を呼び出した後、何かをする必要があると思いますか?

また、これはラベル付け時間を測定する正しい方法ですか? これを行うより良い方法はありますか?

4

2 に答える 2

1

トップレベルは代替回答を非表示にします

t1SICStus のトップレベル シェルで小さい値を使用してテストしている場合、t1答え/解決策が 1 つしかないという間違った印象を受ける可能性があります。しかし、そうではありません!したがって、トップレベルは他の答えを隠します。これは、クエリに変数が含まれていない場合、それ以上の回答を表示しない SICStus トップレベルの特別な動作です。しかし、合計は x です。ラベル付けのための多くのソリューション x! テストケースごとに、他のソリューションのタイミングはランダムな値です。テスト ケースごとに Prolog が記録を保持して、テスト ケースごとに次のソリューションの作成を続行するため、メモリが不足しています。

ループ

テストに障害駆動ループを使用することはお勧めしません。代わりに、非常に似ていますが、より安全な次のループを使用してください。

\+ (
      between(0, Cm, C),
      between(0, Cr, R),
      \+ atest(C, R)
   ).

失敗駆動型ループとの大きな違いは、一部のとatest/2が誤って失敗した場合です。障害駆動ループでは、これは本質的に気付かれませんが、上記の構成は失敗します。CR

forall/2一部のシステムは、この目的のために述語を提供します。

タイミング

タイミングをとる場合は、リストの最初の要素のみを使用して差を計算することをお勧めします。

statistics(walltime, [T0|_]),
Goal,
statistics(walltime, [T1|_]),
D is T1 - T0.

このように、目標に対する別の回答は、より意味のある値を提供します。

于 2014-02-11T10:27:31.107 に答える