如果同时给出相同的输入,则类会占用更多的计算时间

时间:2016-05-24 09:17:21

标签: algorithm time

我正在研究一种算法,除了一件事之外它似乎工作得很好。

让我先向您展示代码,然后我将解释代码的作用以及问题所在。

public Triple<List<ROUTE>, Integer, List<Customer>> LocalSearch()
{
    int noImprLS = 0;
    boolean initialization = false;
    List<ROUTE> bestRoutes = startRoutes;
    int bestProfit = profit;
    List<Customer> bestU = u;

    List<ROUTE> tempBestRoutes = startRoutes;
    int tempBestProfit = profit;
    List<Customer> tempBestU = u;
    int tempBestDistance = totalDistance(tempBestRoutes);

    ELIMINATOR e = new ELIMINATOR(bestU, bestRoutes, bestProfit, initialization, name, rnd);

    while (noImprLS <= noImprUB)
    {
        System.out.print(noImprLS);
        boolean improvement = false;
        long starttime = System.nanoTime();
        double timeE = 0;
        for (int i = 1; i <= N; i++)
        {
            long starttimeE = System.nanoTime();
            e = new ELIMINATOR(bestU, bestRoutes, bestProfit, initialization, name, rnd);
            timeE =  timeE + (System.nanoTime()-starttimeE)/1000000000.0;

            POSTPROCEDURE pp = new POSTPROCEDURE(e.getRoutes(), profitRoutes(e.getRoutes()), e.getU(), name);

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

            int tempprofit = pp.getTP();
            int tempdistance = pp.getTD();

            if (tempprofit > tempBestProfit)  
            {
                tempBestRoutes = pp.getBestSolution();
                tempBestProfit = tempprofit;
                tempBestU = pp.getU();
                tempBestDistance = tempdistance;
            }
            else if (tempprofit == tempBestProfit)
            {

                if (tempdistance < tempBestDistance)
                {
                    tempBestRoutes = pp.getBestSolution();
                    tempBestProfit = tempprofit;
                    tempBestU = pp.getU();
                    tempBestDistance = tempdistance;
                }
            }
        }

        if (tempBestProfit > bestProfit)
        {
            // Move to better neighbor
            bestRoutes = tempBestRoutes;
            bestProfit = tempBestProfit;
            bestU = tempBestU;
            noImprLS = 0;
            improvement = true;
            System.out.print(" total profit: " + bestProfit);
        }
        else if (tempBestProfit == bestProfit)
        {
            if (totalDistance(tempBestRoutes) < totalDistance(bestRoutes))
            {
                // Move to better neighbor
                bestRoutes = tempBestRoutes;
                bestProfit = tempBestProfit;
                bestU = tempBestU;
                noImprLS = 0;
                improvement = true;
                System.out.print(" total profit: " + bestProfit + " total distance: " + totalDistance(bestRoutes));
            }
        }

        if (improvement == false)
        {
            noImprLS++;
        }

        long endtime = System.nanoTime();
        double duration = (endtime - starttime)/1000000000.0;
        System.out.print(" duration: " + duration  + " timeE: " + timeE + "\n");
    }

解释 我知道代码很冗长,但这一切都非常重要。在这段代码中,我正在编写一个针对Time Orienteering Problem with Time Windows的算法(广泛的车辆路径问题)。我的目标是找到一套利润最大的好路线。在下面的示例中,bestRoutes和tempBestRoutes由4条不同的路由组成,profit(bestProfit / tempBestProfit)分别等于这些路由的总利润,而(temp)bestU是尚未包含在我的路由中的客户列表。

现在问题在于ELIMINATOR。此方法删除并添加一些客户。此类的输出用于PostProcedure,它也会更改路径中的某些事实。

我希望现在我的代码正在做什么。我正在考虑N个社区,我会选择最好的一个。如果最好的一个并不比我的起始解决方案好,那么我将noImprLS增加一个。我继续考虑新的nieghbours,直到我的上限连续迭代次数没有改善。

问题 现在的问题是,如果我没有找到更好的解决方案,因此我继续在ELIMINATOR中插入相同的路线和利润,我的计算时间也会增加。

一些示例,其中duration表示while循环中迭代的时间,timeE表示for循环中ELIMINATOR的总时间是多少。很明显,ELIMINATOR会导致持续时间增加。

0总利润:800持续时间:0.486570471 timeE:0.16644330999999998

0总利润:900持续时间:0.431213528时间:0.11342619799999998

0总利润:950持续时间:0.444671005 timeE:0.12090608200000001

0总利润:960期限:0.519406695时间:0.16836757300000005

0持续时间:0.460473438 timeE:0.137813155

1持续时间:0.572109775 timeE:0.30774360900000003

2持续时间:0.698965292 timeE:0.471859029

3持续时间:0.918376211 timeE:0.686916669

4持续时间:1.165481175 timeE:0.92621492

5持续时间:1.326080436 timeE:1.0874366910000002

6持续时间:2.006102605 timeE:1.674879135

7持续时间:2.787172112 timeE:2.4276636639999993

8持续时间:2.042213493 timeE:1.7967797849999998

9持续时间:2.652985618 timeE:2.3503671230000003

10持续时间:2.422183993 timeE:2.1859969810000006

消除器代码:

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 = u;
    this.routes = routes;
    this.totalprofit = 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 the total profit and total number of customers in the routes
    for(ROUTE route : routes)
    {
        num_customers = num_customers + (route.getLocations().size()-2);
    }

    // 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();
                total_profit = total_profit-node.customer.getProfit();
                average_profit = total_profit/num_customers;
            }
        }
    }
    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 = 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;
}

}

0 个答案:

没有答案