你能帮我实现克拉克和赖特算法吗?

Posted

技术标签:

【中文标题】你能帮我实现克拉克和赖特算法吗?【英文标题】:Can you help me with my Clarke and Wright algorithm implementation? 【发布时间】:2012-01-21 20:53:19 【问题描述】:

我正在尝试实施 Clarke and Wright algorithm 来构建初始 VRP 解决方案。 它似乎运行正常,但由于某种原因,我得到的解决方案质量不是预期的。

这是我计算储蓄元素的代码:

private void computeSavingsElements() 
    for(int i = 0; i<vrp.getDimension(); i++)  
        for(int j = 0; j <  i; j++)            
                double savingValue =  vrp.distance(i, 0) + vrp.distance(0, j) - lamda * vrp.distance(i, j);
                SavingsElement savingElement = new SavingsElement (i,j, savingValue);
                savingsElements.add(savingElement);                                                 
        
    
    Collections.sort(savingsElements); // sort in ascending order
    Collections.reverse(savingsElements); // but we need descending order
    

构造解的方法:

private void constructSolution() 
    List<VRPNode> nodes = this.vrp.getNodesList();
    VRPNode depot = this.vrp.getDepot();
    double vehicleCapacity = this.vrp.getVehicleCapacity();
    
    
    VRPSolution solution = new VRPSolution(vehicleCapacity, depot);
    
    /*
     * In the initial solution, each vehicle serves exactly one customer
     */
    for (VRPNode customer:nodes) 
        if (customer.getId()!=0)  // if not depot
            VRPRoute route = new VRPRoute(vehicleCapacity, depot);
            route.addCustomer(customer);
            solution.addRoute(route);
            route = null; // eliminate obsolete reference to free resources
        
       
    
    //System.out.println("INITIAL SOLUTION: \n"+solution.toString());
    
    int mergesCounter=0;
    for (SavingsElement savingElement : this.savingsElements) 
        if (savingElement.getSavingValue() > 0)  // If serving customers consecutively in a route is profitable
            
            VRPNode i = this.vrp.getNode(savingElement.getNodeId1());
            VRPNode j = this.vrp.getNode(savingElement.getNodeId2());
            
            VRPRoute route1 = solution.routeWhereTheCustomerIsTheLastOne(i);
            VRPRoute route2 = solution.routeWhereTheCustomerIsTheFirstOne(j);
            
            if ((route1!=null) & (route2!=null)) 
                if (route1.getDemand() + route2.getDemand() <= this.vrp.getVehicleCapacity())  // if merge is feasible
                    /*
                     * Merge the two routes
                     */
                    solution.mergeRoutes(route1, route2);
                    mergesCounter++;
                
            
            
            
        
        
       
    //System.out.println("\n\nAfter "+mergesCounter+" Merges"+"\n"+solution.toString());
    this.solutionConstructed = solution;
    

对于路由合并:

public void mergeRoutes(VRPRoute a, VRPRoute b) 
    /*
     * Provided that feasibility check has already been performed
     */
    List<VRPNode> customersFromRouteA = new LinkedList<VRPNode>(a.getCustomersInRoute());
    List<VRPNode> customersFromRouteB = new LinkedList<VRPNode>(b.getCustomersInRoute());
    
    /*
     * Remove the old routes
     */
    solutionRoutes.remove(a);
    solutionRoutes.remove(b);
    
    /*
     * Construct a new merged route
     */
    VRPRoute mergedRoute = new VRPRoute(vehicleCapacity,depot);
    
    /*
     * The new route has to serve all the customers 
     * both from route a and b
     */
    for (VRPNode customerFromA:  customersFromRouteA) 
        mergedRoute.addCustomer(customerFromA);
    
    
    for (VRPNode customerFromB:  customersFromRouteB) 
        mergedRoute.addCustomer(customerFromB);
    
    
    addRoute(mergedRoute);

    evaluateSolutionCost();

似乎可以正确计算节省并按应有的方式合并路线,但是构造的解决方案的成本太高了。例如,在给定的实例中,我得到 1220,而它应该是 820。

【问题讨论】:

【参考方案1】:

一个明显的问题是,当j 时,您的代码只考虑在路由i 之后加入路由j。您还应该考虑以相反的方式加入它们 - 换句话说,在 computeSavingsElements j 的内部循环中应该达到客户节点的数量 (vrp.getDimension())。

当然,很难判断您未显示的代码部分是否存在错误,例如数组routeWhereTheCustomerIsTheLastOne 是否正确更新?

【讨论】:

以上是关于你能帮我实现克拉克和赖特算法吗?的主要内容,如果未能解决你的问题,请参考以下文章

你能帮我为matlab中ytop和ybot值的所有'ht'编写代码吗? [关闭]

你好,请问能帮我做个计时器吗?

你能帮我处理移动媒体查询吗?

谁能帮我翻译一下

你能帮我解析这个 JSON 吗?

你能帮我解决keras的尺寸问题吗?