GraphHopper.com | Forum | GitHub | Maps | Blog

Multiple breaks for vehicles. Feature #211


#1

Hi,

I’m working on feature #211, I changed the “informJobInserted” and “informInsertionStarts” methods of the BreakScheduling class to perform an insertion of more than one break:

@Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
    List<Break> aBreakList = inRoute.getVehicle().getBreak(); // HERE
    if(aBreakList != null){
    	for(int i=aBreakList.size()-1; i >= 0; i--) {
		Break aBreak = aBreakList.get(i);		
    		boolean removed = inRoute.getTourActivities().removeJob(aBreak);
    		if(removed){
                    logger.trace("ruin: {}", aBreak.getId());
                    stateManager.removed(aBreak,inRoute);
                    stateManager.reCalculateStates(inRoute);
                }
    		if(inRoute.getEnd().getArrTime() > aBreak.getTimeWindow().getEnd()){
                    InsertionData iData = breakInsertionCalculator.getInsertionData(inRoute, aBreak, inRoute.getVehicle(), inRoute.getDepartureTime(), inRoute.getDriver(), Double.MAX_VALUE);
                    if(!(iData instanceof InsertionData.NoInsertionFound)){
                        //logger.trace("insert: [jobId={}]{}", aBreak.getId(), iData);
                        for(Event e : iData.getEvents()){
                            eventListeners.inform(e);
                        }
                        stateManager.informJobInserted(aBreak,inRoute,0,0);
                }
            }
    	}
    }
}

However, in some cases the break is not being inserted because of the following rule of the VehicleDependentTimeWindowConstraints class:

double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double endTimeAtNewAct = Math.max(arrTimeAtNewAct, newAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(newAct, arrTimeAtNewAct,iFacts.getNewDriver(),iFacts.getNewVehicle());
double latestArrTimeAtNewAct =
        Math.min(newAct.getTheoreticalLatestOperationStartTime(),
            latestArrTimeAtNextAct -
                routingCosts.getBackwardTransportTime(newAct.getLocation(), nextActLocation, latestArrTimeAtNextAct, iFacts.getNewDriver(), iFacts.getNewVehicle())
                - activityCosts.getActivityDuration(newAct, arrTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle())
        );
/*
*  |--- prevAct ---|
*                       		                 |--- vehicle's arrival @newAct
*        latest arrival of vehicle @newAct ---|
*/
if (arrTimeAtNewAct > latestArrTimeAtNewAct) {
    return ConstraintsStatus.NOT_FULFILLED;
}

I would like to understand this rule.

Best regards,
Emerson