From 7450f476b6d93662ba38e4631415bd9a538f3709 Mon Sep 17 00:00:00 2001 From: oblonski Date: Thu, 8 Jan 2015 19:15:54 +0100 Subject: [PATCH] add new ruin strategy --- .../ruin/RuinRadialMultipleCenters.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinRadialMultipleCenters.java diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinRadialMultipleCenters.java b/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinRadialMultipleCenters.java new file mode 100644 index 00000000..c4415c27 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinRadialMultipleCenters.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (C) 2014 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.core.algorithm.ruin; + +import jsprit.core.algorithm.ruin.distance.JobDistance; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.job.Job; +import jsprit.core.problem.solution.route.VehicleRoute; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.*; + + +/** + * + * RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by + * the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary + * measure). + * + * @author stefan + * + */ +public final class RuinRadialMultipleCenters extends AbstractRuinStrategy { + + private Logger logger = LogManager.getLogger(RuinRadialMultipleCenters.class); + + private VehicleRoutingProblem vrp; + + private JobNeighborhoods jobNeighborhoods; + + private final int noJobsToMemorize; + + private int noCenters = 1; + + public RuinRadialMultipleCenters(VehicleRoutingProblem vrp, int neighborhoodSize, JobDistance jobDistance) { + super(); + this.vrp = vrp; + noJobsToMemorize = neighborhoodSize; + ruinShareFactory = new RuinShareFactory() { + + @Override + public int createNumberToBeRemoved() { + return noJobsToMemorize; + } + + }; + JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, noJobsToMemorize); + jobNeighborhoodsImpl.initialise(); + jobNeighborhoods = jobNeighborhoodsImpl; + logger.info("initialise " + this); + } + + public void setNumberOfRuinCenters(int noCenters){ + this.noCenters = noCenters; + } + + @Override + public String toString() { + return "[name=radialRuin][noJobsToBeRemoved="+noJobsToMemorize+"]"; + } + + /** + * Ruins the collection of vehicleRoutes, i.e. removes a share of jobs. First, it selects a job randomly. Second, it identifies its neighborhood. And finally, it removes + * the neighborhood plus the randomly selected job from the number of vehicleRoutes. All removed jobs are then returned as a collection. + */ + @Override + public Collection ruinRoutes(Collection vehicleRoutes) { + if(vehicleRoutes.isEmpty()){ + return Collections.emptyList(); + } + Set available = new HashSet(vrp.getJobs().values()); + Collection ruined = new ArrayList(); + for(int center=0;center ruinRoutes(Collection vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){ + return ruinRoutes_(vehicleRoutes,targetJob,nOfJobs2BeRemoved,null); + } + + private Collection ruinRoutes_(Collection vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved, Set available){ + List unassignedJobs = new ArrayList(); + int nNeighbors = nOfJobs2BeRemoved - 1; + removeJob(targetJob,vehicleRoutes); + unassignedJobs.add(targetJob); + Iterator neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(nNeighbors, targetJob); + while(neighborhoodIterator.hasNext()){ + Job job = neighborhoodIterator.next(); + if(available!=null) available.remove(job); + removeJob(job,vehicleRoutes); + unassignedJobs.add(job); + } + return unassignedJobs; + } + + private Job pickRandomJob(Set available) { + int randomIndex = random.nextInt(available.size()); + int i=0; + for(Job j : available){ + if(i>=randomIndex) { + return j; + } + else i++; + } + return null; + } + +}