0

基本的に、多次元ナップザック問題のシミュレーテッド アニーリングの実装を作成しようとしています。より低い値の状態を受け入れるかどうかをシステムに決定させるのに問題があります。アニーリングは次の関数で制御されます。

while (this.temp > 0)
    {
        System.out.println("Temperature: "+this.temp);
        System.out.println("Current bag: "+bagString(currentBag)+" (Value "+problem.getValue(currentBag)+")");
        next = getNext();
        System.out.println("Next bag: "+bagString(next)+" (Value "+problem.getValue(next)+")");
        if (acceptNext(next))
        {
            System.out.println("Accepted");
            this.currentBag = next;
        } else {
            System.out.println("Not accepted");
        }
        this.temp -= this.delta;
    }

acceptNext() 関数は、次の状態を受け入れるかどうかを決定し、次のように定義されます。

public boolean acceptNext(ArrayList<Boolean> next)
{
    if (problem.getValue(next) > problem.getValue(this.currentBag))
    {
        return true;
    } else {
        int loss = (problem.getValue(this.currentBag) - problem.getValue(next));
        double prob = Math.exp(loss/this.temp);
        Random generator = new Random();
        double selection = generator.nextDouble();
        System.out.println("Prob: "+prob+", random number: "+selection);
        if (selection < prob) {
            return true;
        }
        return false;
    }
}

いくつかのテストを行った後、acceptNext() 関数が呼び出される前に currentBag フィールドが次の値に割り当てられていることがわかりました。どのコードにも別の「this.currentBag = next」が見つかりません。完全を期すために、ここに getNext() 関数を示します。

public ArrayList<Boolean> getNext()
{
    Random generator = new Random();
    boolean valid = false;
    ArrayList<Boolean> next = new ArrayList<Boolean>();
    int j;
    while (!valid)
    {
        next = this.currentBag;
        j = generator.nextInt(problem.getNumObjects());
        if (next.get(j) == true)
        {
            next.set(j, false);
        } else {
            next.set(j, true);
        }
        if (problem.isValid(next))
        {
            valid = true;
        }
    }
    return next;
}

何がこの値を更新しているのかわかりません。誰かがコードに何かを見ていますか?

ありがとう

ベン

4

2 に答える 2

3

これを行うと、next は現在のバッグと同じものを指すため、next へのすべての変更が currentBag に反映されます。getNext() メソッドで:

while (!valid)
{
    next = this.currentBag;
    ...
}

代わりにこれを試してください:

while (!valid)
{
    next = new ArrayList<Boolean>(this.currentBag);
    ...
}
于 2010-04-09T13:36:27.363 に答える
1

getNext() は next を設定して currentBag オブジェクトを参照し、それに対して設定操作を実行します。next の値を変更する場合は、 currentBag をコピー/クローンする必要があります。

于 2010-04-09T13:37:03.040 に答える