2017-08-20 10 views
3

私は、各顧客が複数の場所を持っており、そのうちの1つを訪問する必要がある車両のルーティングを解決しようとしています。 Iはoptaplannerマスターを得て、次のようにvehiclerouting変形例:顧客ごとに複数の場所を持つ車両のルーティング

Customer.java:VehicleRoutingImporter.java、顧客の場所に変更している読み取るコードで

/* 
* Copyright 2012 Red Hat, Inc. and/or its affiliates. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package org.optaplanner.examples.vehiclerouting.domain; 

import com.thoughtworks.xstream.annotations.XStreamAlias; 
import com.thoughtworks.xstream.annotations.XStreamInclude; 
import org.optaplanner.core.api.domain.entity.PlanningEntity; 
import org.optaplanner.core.api.domain.valuerange.CountableValueRange; 
import org.optaplanner.core.api.domain.valuerange.ValueRangeFactory; 
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider; 
import org.optaplanner.core.api.domain.variable.AnchorShadowVariable; 
import org.optaplanner.core.api.domain.variable.PlanningVariable; 
import org.optaplanner.core.api.domain.variable.PlanningVariableGraphType; 
import org.optaplanner.examples.common.domain.AbstractPersistable; 
import org.optaplanner.examples.vehiclerouting.domain.location.Location; 
import org.optaplanner.examples.vehiclerouting.domain.solver.DepotAngleCustomerDifficultyWeightFactory; 
import org.optaplanner.examples.vehiclerouting.domain.timewindowed.TimeWindowedCustomer; 

import java.util.List; 

@PlanningEntity(difficultyWeightFactoryClass = DepotAngleCustomerDifficultyWeightFactory.class) 
@XStreamAlias("VrpCustomer") 
@XStreamInclude({ 
     TimeWindowedCustomer.class 
}) 
public class Customer extends AbstractPersistable implements Standstill { 

    protected int demand; 

    // Planning variables: changes during planning, between score calculations. 
    protected Standstill previousStandstill; 

    // Shadow variables 
    protected Customer nextCustomer; 
    protected Vehicle vehicle; 

    protected List<Location> locations; 
    protected Integer selectedLocation = 0; 

    public void setSelectedLocation(Integer selectedLocation){ 
     this.selectedLocation = selectedLocation; 
    } 

    @PlanningVariable(valueRangeProviderRefs = {"selectedLocation"}) 
    public Integer getSelectedLocation(){ 
     return selectedLocation; 
    } 

    @ValueRangeProvider(id = "selectedLocation") 
    public CountableValueRange<Integer> getSelectableLocations(){ 
     return ValueRangeFactory.createIntValueRange(0, locations.size()); 
    } 

    public void setLocations(List<Location> locations) { 
     this.locations = locations; 
    } 

    public List<Location> getLocations(){ 
     return locations; 
    } 

    @Override 
    public Location getLocation() { 
     return locations.get(selectedLocation); 
    } 

    @Override 
    public String toString() { 
     return "Customer " + getId(); 
    } 


    public int getDemand() { 
     return demand; 
    } 

    public void setDemand(int demand) { 
     this.demand = demand; 
    } 

    @PlanningVariable(valueRangeProviderRefs = {"vehicleRange", "customerRange"}, 
      graphType = PlanningVariableGraphType.CHAINED) 
    public Standstill getPreviousStandstill() { 
     return previousStandstill; 
    } 

    public void setPreviousStandstill(Standstill previousStandstill) { 
     this.previousStandstill = previousStandstill; 
    } 

    @Override 
    public Customer getNextCustomer() { 
     return nextCustomer; 
    } 

    @Override 
    public void setNextCustomer(Customer nextCustomer) { 
     this.nextCustomer = nextCustomer; 
    } 

    @Override 
    @AnchorShadowVariable(sourceVariableName = "previousStandstill") 
    public Vehicle getVehicle() { 
     return vehicle; 
    } 

    public void setVehicle(Vehicle vehicle) { 
     this.vehicle = vehicle; 
    } 

    // ************************************************************************ 
    // Complex methods 
    // ************************************************************************ 

    /** 
    * @return a positive number, the distance multiplied by 1000 to avoid floating point arithmetic rounding errors 
    */ 
    public long getDistanceFromPreviousStandstill() { 
     if (previousStandstill == null) { 
      throw new IllegalStateException("This method must not be called when the previousStandstill (" 
        + previousStandstill + ") is not initialized yet."); 
     } 
     return getDistanceFrom(previousStandstill); 
    } 

    /** 
    * @param standstill never null 
    * @return a positive number, the distance multiplied by 1000 to avoid floating point arithmetic rounding errors 
    */ 
    public long getDistanceFrom(Standstill standstill) { 
     return standstill.getLocation().getDistanceTo(getLocation()); 
    } 

    /** 
    * @param standstill never null 
    * @return a positive number, the distance multiplied by 1000 to avoid floating point arithmetic rounding errors 
    */ 
    public long getDistanceTo(Standstill standstill) { 
     return getLocation().getDistanceTo(standstill.getLocation()); 
    } 


} 

List<Location> locations = new ArrayList<>(lineTokens.length-2); 
for (int j = 2; j < lineTokens.length; ++j){ 
    long locationId = Long.parseLong(lineTokens[j]); 
    Location location = locationMap.get(locationId); 
    if (location == null) 
     throw new IllegalArgumentException("Missing location (id=" + locationId + ") specified for customer id=" + id); 
     locations.add(location) 
} 
customer.setLocations(locations); 

Customer.setLocation(location)を呼び出すために使用された他のすべてのコードは、Customer.setLocations(Collections.singletonList(location))を呼び出すようになりました。私はそれが実際に呼び出されるとは思わない。 vehicleRoutingSolverConfig.xmlで

、私はこれらの行(そうでない場合、それは複数の変数文句)削除:

<subChainChangeMoveSelector> 
    <selectReversingMoveToo>true</selectReversingMoveToo> 
    </subChainChangeMoveSelector> 
    <subChainSwapMoveSelector> 
    <selectReversingMoveToo>true</selectReversingMoveToo> 
    </subChainSwapMoveSelector> 

チュートリアル-01-uncapacitated.vrpは今:

NAME : tutorial-01-uncapacitated 
COMMENT : Geoffrey De Smet - OptaPlanner VRP demo 01 
TYPE : CVRP 
DIMENSION : 8 
EDGE_WEIGHT_TYPE : EUC_2D 
CAPACITY : 100 
NODE_COORD_SECTION 
1 50 50 
2 45 100 
3 30 80 
4 70 85 
5 60 60 
6 35 10 
7 30 30 
8 45 20 
DEMAND_SECTION 
1 0 
2 1 2 3 
3 1 3 4 
4 1 4 5 
5 1 5 6 
6 1 6 7 
7 1 7 8 
8 1 8 2 
DEPOT_SECTION 
1 
-1 
VEHICLES : 2 
EOF 

それが表示されます小規模のテストケースで最適なソリューションを見つけ出します(大規模なケースでは合理的な解決策と思われます)。私はFAST_ASSERTモードを設定する場合しかし、それは次のエラーで失敗します。

Caused by: java.lang.IllegalStateException: Impossible VariableListener corruption: the expectedWorkingScore (0hard/-30000soft) is not the workingScore (0hard/-34142soft) after all VariableListeners were triggered without changes to the genuine variables. But all the shadow variable values are still the same, so this is impossible.

+0

drlの代わりにVehicleRoutingEasyScoreCalculatorを使用すると、エラーなく動作します。 – msasha

+0

DRLで一度に1つのスコアルールをコメントアウトして、この問題の原因となっているスコアルールを見つけて、この質問に貼り付けてコピーできますか? (この問題を修正することができたとしても、エラーメッセージを修正するために再現できる必要があります)いずれにしても、エラーメッセージは誤解を招くため、破損分析を含める必要があります。[https: /issues.jboss.org/browse/PLANNER-866)。 –

+0

私のDRLには2つのルールしかありません。キャパシティのハード制約と距離のソフト制約です。ソフト制約を削除すると、このエラーは返されません。ここではDRLルールは次のとおりです。 ルール "distanceToPreviousStandstill" $の顧客:顧客(previousStandstill = nullで、$ distanceFromPreviousStandstill:!distanceFromPreviousStandstill) 、その後 scoreHolder.addSoftConstraintMatch(kcontext、 - $ distanceFromPreviousStandstill)。 end – msasha

答えて

0

電源を入れる代わりにFAST_ASSERTFULL_ASSERTに速い本当の問題を指して失敗します。どのようにして問題が検出されるかを説明しているthe PR commentを参照してください。

関連する問題