-1

我得到的输出是:

Inside loop : [5, 6, 3, 1, 4, 2]

Inside loop : [3, 1, 5, 6, 4, 2]

Inside loop : [1, 2, 4, 5, 6, 3]

Inside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PossibleSolution {
    // the indices of where to place the cuts to delimit routes (different
    // vehicles)
    int[] indicesCut;
    // the set of ordered Customers for each route. Routes delimited by cuts
    ArrayList<Integer> OrderedCustomers;
    // length of array
    int size;

    // Constructor
    public PossibleSolution(int[] indices, ArrayList<Integer> Customers) {
        this.indicesCut = indices;
        this.OrderedCustomers = Customers;

        this.size = Customers.size();
    }

    // method to generate the neighborhood for one possible solution. We need a
    // parameter
    // to specify the number of neighbors to generate

    public PossibleSolution[] generateNeighborhood(int number) {
        PossibleSolution[] sol = new PossibleSolution[number];
        for (int i = 0; i < number; i++) {
            java.util.Collections.shuffle(this.OrderedCustomers);

            sol[i] = new PossibleSolution(this.indicesCut, this.OrderedCustomers);
            System.out.println("Inside loop : " + sol[i].OrderedCustomers);
        }

        for (int i = 0; i < number; i++) {
            System.out.println("Outside loop : " + sol[i].OrderedCustomers);
        }

        return sol;
    }

    public static void main(String[] args) {
        ArrayList<Integer> Customers = new ArrayList();
        Customers.add(2);
        Customers.add(4);
        Customers.add(5);
        Customers.add(1);
        Customers.add(6);
        Customers.add(3);
        int[] ind = { 2, 3 };
        PossibleSolution initialSol = new PossibleSolution(ind, Customers);
        PossibleSolution[] table = initialSol.generateNeighborhood(4);
    }
}
4

3 回答 3

4

你所有PossibleSolution的引用都是一样的ArrayList

(您的所有ArrayList变量和字段都指向ArrayList您在 中创建的单曲main()。因此,每次您打乱列表时,它都会影响任何地方的列表值。如果您想PossibleSolution()捕获列表状态的快照,就像它在它被调用了,你需要制作一个副本。)

于 2013-11-08T17:10:10.897 回答
1

概括

构造函数不复制客户,它只是存储对它的引用。因此,如果您将对一个对象的引用传递给几个PossibleSolutions,那么它们都会共享它

public PossibleSolution(int[]indices, ArrayList<Integer> Customers){
    this.indicesCut = indices;
    this.OrderedCustomers = Customers; //<-- Only the reference is copied, not the object

    this.size = Customers.size();
}

解释

for(int i =0; i<number;i++){        
        java.util.Collections.shuffle(this.OrderedCustomers);

        sol[i] = new PossibleSolution(this.indicesCut,this.OrderedCustomers);
        System.out.println("Inside loop : "+sol[i].OrderedCustomers);
    }

所有PossibleSolutions 共享相同的this.OrderedCustomers内容,因此每当您洗牌时,this.OrderedCustomers您都在更改所有PossibleSolutions的内部结构。

所以它一遍又一遍地打印同样的东西并不奇怪

for(int i=0; i<number;i++){
   System.out.println("Outside loop : "+sol[i].OrderedCustomers);
}

因为它是相同的OrderedCustomers

解决方案

如果你想要一个副本,那么你需要请求一个对象的副本,而不仅仅是引用,最简单的方法是使用System.arrayCopy

System.arraycopy(from, 0,to,0,from.length);

进一步阅读

可以在此处找到相同的“在不同位置引用同一对象”问题的简化版本


其他注意事项

OrderedCustomers并且Customers都是变量,因此它们应该是 lowerCamelCase;orderedCustomerscustomers

于 2013-11-08T17:13:13.667 回答
0

所有标记为“外部循环”的打印语句始终在同一个数组上执行。for退出第一个循环后,您不再随机化任何东西。你只是一次又一次地打印。

于 2013-11-08T17:11:57.980 回答