Java: значение обновляется, когда не должно

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

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

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

Спасибо

Бен


person benwad    schedule 09.04.2010    source источник


Ответы (2)


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

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

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

while (!valid)
{
    next = new ArrayList<Boolean>(this.currentBag);
    ...
}
person job    schedule 09.04.2010

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

person Steven Mackenzie    schedule 09.04.2010