Java: значение обновляется, когда оно не должно - PullRequest
0 голосов
/ 09 апреля 2010

В основном я пытаюсь создать реализацию имитации отжига для многомерной задачи о ранце. У меня проблема с тем, чтобы система решала, принимать или нет состояние с более низким значением. Отжиг контролируется с помощью этой функции:

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;
    }
}

После некоторого тестирования я обнаружил, что поле currentBag присваивается следующему значению до вызова функции acceptNext (). Я не могу найти другой "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;
}

Я не вижу, что заставляет это значение обновляться. Кто-нибудь что-нибудь видит в коде?

Спасибо

Ben

Ответы [ 2 ]

3 голосов
/ 09 апреля 2010

Когда вы делаете это, next указывает на то же самое, что и текущий пакет, поэтому все изменения next отражаются в currentBag. В вашем методе getNext ():

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

Попробуйте вместо этого:

while (!valid)
{
    next = new ArrayList<Boolean>(this.currentBag);
    ...
}
1 голос
/ 09 апреля 2010

getNext () устанавливает рядом со ссылкой на объект currentBag, а затем выполняет над ним операцию set. Вам нужно скопировать / клонировать currentBag, если вы хотите затем изменить значение next.

...