2016-03-29 91 views
0

这个问题是与此相关的话题:Related jobs in JSprit相关工作在JSprit,一前另一种情况:抛出:IllegalArgumentException

我想“之前一个又一个”限制使用,但我遇到一个的Java。 lang.IllegalArgumentException:arg不能为空。在计算最大容量时,看起来容量cap2为空。我不明白为什么。

:(

你有这个想法?

为了记录在案,我在1.6.2版本。TY对您有所帮助。

 String before = "2"; 
     String after = "11"; 

     final StateManager stateManager = new StateManager(problem); 
     stateManager.addStateUpdater(new JobsInRouteMemorizer(stateManager)); 



     ConstraintManager constraintManager = new ConstraintManager(problem, stateManager); 
     constraintManager.addConstraint(new OneJobBeforeAnother(stateManager, before, after)); 

     final RewardAndPenaltiesThroughSoftConstraints contrib = new RewardAndPenaltiesThroughSoftConstraints(problem, before, after); 
     SolutionCostCalculator costCalculator = new SolutionCostCalculator() { 

      @Override 
      public double getCosts(VehicleRoutingProblemSolution solution) { 
       double costs = 0.; 
       List<VehicleRoute> routes = (List<VehicleRoute>) solution.getRoutes(); 
       for(VehicleRoute route : routes){ 
        costs+=route.getVehicle().getType().getVehicleCostParams().fix; 
        costs+=stateManager.getRouteState(route, InternalStates.COSTS, Double.class); 
        costs+=contrib.getCosts(route); 
       } 
       return costs; 
      } 

     }; 
     VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(problem, 
       "algorithmConfig.xml"); 
     vraBuilder.addCoreConstraints(); 
     vraBuilder.setStateAndConstraintManager(stateManager, constraintManager); 
     vraBuilder.addDefaultCostCalculators(); 
     vraBuilder.setObjectiveFunction(costCalculator); 
     algorithm = vraBuilder.build(); 



public class JobsInRouteMemorizer implements StateUpdater, ActivityVisitor { 
private StateManager stateManager; 
private VehicleRoute route; 



public JobsInRouteMemorizer(StateManager stateManager) { 
    super(); 
    this.stateManager = stateManager; 
} 

@Override 
public void begin(VehicleRoute route) { 
    this.route=route; 
} 

@Override 
public void visit(TourActivity activity) { 
    if(activity instanceof JobActivity){ 
     String jobId = ((JobActivity) activity).getJob().getId(); 
     StateId stateId = stateManager.createStateId(jobId); 
     System.out.println(stateId.getIndex()); 
     System.out.println(stateId.toString()); 
     stateManager.putProblemState(stateId, VehicleRoute.class, this.route); 
    } 

} 

@Override 
public void finish() {} 

} 
+0

Hi @CédricAlexis,你的问题已解决?我可能遇到了同样的问题。谢谢。 –

回答

0

简而言之:你不能动态地创建StateId实例,所有的StateId实例必须在算法运行之前生成。查看更长的答案,为什么这样做仍然不是一个好主意,你笑我想考虑重新设计。

分析:我遇到了同样的问题,追溯回STATEID实例在StateManager创建方式:

public StateId createStateId(String name) { 
    if (createdStateIds.containsKey(name)) return createdStateIds.get(name); 
    if (stateIndexCounter >= activityStates[0].length) { 
     activityStates = new Object[vrp.getNuActivities() + 1][stateIndexCounter + 1]; 
     vehicleDependentActivityStates = new Object[nuActivities][nuVehicleTypeKeys][stateIndexCounter + 1]; 
     routeStatesArr = new Object[vrp.getNuActivities()+1][stateIndexCounter+1]; 
     vehicleDependentRouteStatesArr = new Object[nuActivities][nuVehicleTypeKeys][stateIndexCounter+1]; 
     problemStates = new Object[stateIndexCounter+1]; 
    } 
    StateId id = StateFactory.createId(name, stateIndexCounter); 
    incStateIndexCounter(); 
    createdStateIds.put(name, id); 
    return id; 
} 

每次创建一个新的STATEID并没有更多的可用状态的空间旧状态数组会被更长的版本覆盖以为您的新状态留出空间(开始时有30个StateId空间,其中一些已被JSprit本身使用)。正如你所看到的,旧的元素不会被复制,所以这里发生的是UpdateLoads之间的竞争条件,UpdateLoads设置用作cap2的状态,你的代码生成一个新的StateId并覆盖当前状态,UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute读取状态(不存在了)。

鉴于此代码只能将数组扩展一个,因此对于每个新的StateId都必须重新创建所有数组,因此它的效率非常低。为了缓解这个我曾经在我的代码只有一个STATEID并存储在它Map<String, VehicleRoute>

Map<String, VehicleRoute> routeMapping = Optional.ofNullable(stateManager.getProblemState(stateId, Map.class)).orElse(new ConcurrentHashMap<>()) 

这样你就不会用完STATEID情况下,仍然可以存储无限数量的就业机会之间的关系。

相关问题