即使创建了副本,引用也会出错

时间:2016-05-24 11:14:10

标签: java reference

不幸的是,我有一个参考问题。一旦调用了ELIMINATOR,变量emptyRoutes就会改变。但是,在ELIMINATOR中我已经制作了一个副本(路径的新ArrayList(emptyRoutes)),因此更改removeor中的路由不应该更改emptyRoutes?

有人知道出了什么问题吗?

主要代码:

public Triple<List<ROUTE>, Integer, List<Customer>> initialization()
{
    boolean initialization = true;

    // Create the empty routes (also used in the for loop)
    Customer vertex0 = u.get(0);
    Pair<List<ROUTE>, Integer> results = createEmptyRoutes(vertex0, num_routes);
    u.remove(0);
    List<ROUTE> emptyRoutes = new ArrayList<ROUTE>(results.getFirst());
    int profit = results.getSecond();

    // Initialize the values of the variables
    List<ROUTE> bestroutes = new ArrayList<ROUTE>(4);
    List<Customer> best_u = new ArrayList<Customer>(u);
    int tpBestSolution = 0;
    int tdBestSolution = 1000000000;

    int inU = u.size();
    int num = (emptyRoutes.get(0).getLocations().size()-2) +  (emptyRoutes.get(1).getLocations().size()-2) +  (emptyRoutes.get(2).getLocations().size()-2)+ (emptyRoutes.get(3).getLocations().size()-2);

    if (inU + num != 50)
    {
        System.out.println();
    }


    for (int i = 0; i < (3*N); i++)
    {
        Collections.shuffle(u, rnd);
        ELIMINATOR B = new ELIMINATOR(u, emptyRoutes, profit, initialization, name, rnd);

        inU = B.getU().size();
        num = (B.getRoutes().get(0).getLocations().size()-2) +  (B.getRoutes().get(1).getLocations().size()-2) +  (B.getRoutes().get(2).getLocations().size()-2)+ (B.getRoutes().get(3).getLocations().size()-2);

        if (inU + num != 50)
        {
            System.out.println(i);
        }

        POSTPROCEDURE PP = new POSTPROCEDURE(B.getRoutes(), profitRoutes(B.getRoutes()), B.getU(), name);

        // Temporary solution
        List<ROUTE> tempRoutes = PP.getBestSolution();

        for (int p = 0; p < PP.getBestSolution().size(); p++)
        {
            ROUTE r = PP.getBestSolution().get(p);
            addToPOOL(r);
        }

        boolean improvement = false;
        if (PP.getTP() > tpBestSolution)
        {
            improvement = true;
        }
        else if (PP.getTP() == tpBestSolution)
        {
            if (PP.getTD() < tdBestSolution)
            {
                improvement = true;
            }
        }

        if (improvement == true)
        {
            best_u = new ArrayList<Customer>(PP.getU());
            bestroutes = new ArrayList<ROUTE>(tempRoutes);
            tpBestSolution = new Integer(PP.getTP());
            tdBestSolution = new Integer(PP.getTD());
        }
    }
    return new Triple<List<ROUTE>, Integer, List<Customer>>(bestroutes, tpBestSolution, best_u);
}

ELIMINATOR:

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

public class ELIMINATOR extends BASIS
{
private List<Customer> u;
private List<ROUTE> routes;
private int totalprofit;
private Random prob;

public ELIMINATOR(List<Customer> u, List<ROUTE> routes, int profit, boolean initialization, String name, Random rnd)
{
    super(name);
    this.u = new ArrayList<Customer>(u);
    this.routes = new ArrayList<ROUTE>(routes);
    this.totalprofit = new Integer(profit);
    this.prob = rnd;

    if (initialization == true)
    {
        addCustomers();
        for (ROUTE route : routes)
        {
            checkCorrectNess(route, "after adding procedure in eliminator");
        }
    }
    else
    {
        removeCustomers();
        for (ROUTE route : routes)
        {
            checkCorrectNess(route, "after removing procedure in eliminator");
        }

        addCustomers();
        for (ROUTE route : routes)
        {
            checkCorrectNess(route, "after removing and adding procedure in eliminator");
        }

    }
}

public void removeCustomers()
{
    double Ph = 0.1;
    double Pl = 0.3;
    double total_profit = totalprofit;
    int num_customers = 0;

    // Calculate average profit
    double average_profit = total_profit/num_customers;

    // For each customer on each route, determine whether he/she will be removed
    for(ROUTE r : routes)
    {
        List<RouteNode> route = r.getLocations();
        int routesize = route.size();
        int j = 1;
        while (j < routesize-1)
        {
            boolean removed = false;
            RouteNode node = route.get(j);
            if (node.customer.getProfit() >= average_profit)
            {
                if (prob.nextDouble() < Ph)
                {
                    removed = true;
                    RouteNode node_toberemoved = node;
                    int index_node = route.indexOf(node);
                    route.remove(index_node);
                    u.add(node.customer);
                    route = removal(route, node_toberemoved, index_node);
                    r.setLocations(route);
                    r.setDistance(distanceOneRoute(route));
                    r.setProfit(profitOneRoute(route));
                    checkCorrectNess(r, "remove customers eliminator");
                }
            }
            else
            {
                if (prob.nextDouble() < Pl)
                {
                    removed = true;
                    RouteNode node_toberemoved = node;
                    int index_node = route.indexOf(node);
                    route.remove(index_node);
                    u.add(node.customer);
                    route = removal(route, node_toberemoved, index_node);
                    r.setLocations(route);
                    r.setDistance(distanceOneRoute(route));
                    r.setProfit(profitOneRoute(route));
                    checkCorrectNess(r, "remove customers eliminator");
                }
            }

            if (removed == false)
            {
                j++;
            }
            else
            {
                routesize = route.size();
            }
        }
    }
    totalprofit = profitRoutes(routes);
}


public void addCustomers()
{
    List<Customer> u_copy = new ArrayList<Customer>(u);
    List<Customer> u_temp = new ArrayList<Customer>(u);
    for (Customer c : u_temp) 
    {   
        boolean added = false;
        for (ROUTE r : routes)
        {
            checkCorrectNess(r, "add customers eliminator");
            if (added == true)
            {
                break;
            }
            Customer customer = c;
            u_copy.remove(c);

            List<RouteNode> route = r.getLocations();
            for (int i = 0; i < route.size()-1; i++)
            {
                RouteNode possibleNode = new RouteNode();
                possibleNode.customer = customer;

                List<Integer> distances = calculateDistances(route.get(i), possibleNode, route.get(i+1));

                // Calculate shift for customer under consideration
                int arrivalTime = route.get(i).timeStartService+ route.get(i).customer.getService() + distances.get(0); 
                int wait = Math.max(0, customer.getOpeningTW()-arrivalTime);
                int serviceDuration = customer.getService();
                int shift = distances.get(0) + wait + serviceDuration + distances.get(2) - distances.get(1);

                // Determine Start Service
                int startServiceTime = Math.max(customer.getOpeningTW(), arrivalTime); 

                // Obtain waiting time of next customer
                int waiting_next = route.get(i+1).wait;

                // Obtain MaxShift of next customer
                int maxShift = route.get(i+1).maxShift;

                if (shift <= (waiting_next + maxShift) & startServiceTime <= customer.getClosingTW() )
                {
                    // Customer can be inserted
                    added = true;
                    RouteNode newNode = new RouteNode();
                    newNode.customer = customer;
                    newNode.arrivalTime = arrivalTime;
                    newNode.timeStartService = startServiceTime;
                    newNode.shift = shift;
                    newNode.wait = wait;

                    int pos_insertion = i + 1;
                    route = ADD(route, newNode, pos_insertion);
                    r.setLocations(route);
                    r.setDistance(distanceOneRoute(route));
                    r.setProfit(profitOneRoute(route));
                    checkCorrectNess(r, "add customers eliminator");
                    // exit the last for loop
                    break;
                }   
            }
        }
        if (added == false)
        {
            u_copy.add(c);
        }
    }
    u = new ArrayList<Customer>(u_copy);
    totalprofit = profitRoutes(routes);
}

/**
 * Returns list of unvisited customers
 * @return
 */
public List<Customer> getU()
{
    return u;
}

/**
 * Returns list of routes
 * @return
 */
public List<ROUTE> getRoutes()
{
    return routes;
}

}

1 个答案:

答案 0 :(得分:0)

我认为问题在于复制List<Route>对象,不会复制列表包含的Route个对象 1

因此,您最终会得到两个包含相同Route个对象的列表。更改一个列表中找到的Route的效果会影响另一个列表中的同一个对象。

1 - 我拒绝遵循您糟糕的Java风格决定!