1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

add infrastructure towards adaptive/dynamic search strategies

This commit is contained in:
oblonski 2014-11-22 12:37:22 +01:00
parent a32a750bed
commit 64b5d77267
3 changed files with 79 additions and 64 deletions

View file

@ -1,16 +1,16 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* 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
* 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 <http://www.gnu.org/licenses/>.
******************************************************************************/
@ -61,25 +61,32 @@ public class SearchStrategy {
private static Logger logger = LogManager.getLogger(SearchStrategy.class);
private Collection<SearchStrategyModule> searchStrategyModules = new ArrayList<SearchStrategyModule>();
private final Collection<SearchStrategyModule> searchStrategyModules = new ArrayList<SearchStrategyModule>();
private SolutionSelector solutionSelector;
private final SolutionSelector solutionSelector;
private SolutionCostCalculator solutionCostCalculator;
private final SolutionCostCalculator solutionCostCalculator;
private SolutionAcceptor solutionAcceptor;
private final SolutionAcceptor solutionAcceptor;
private final String id;
private String name;
public SearchStrategy(SolutionSelector solutionSelector, SolutionAcceptor solutionAcceptor, SolutionCostCalculator solutionCostCalculator) {
super();
this.solutionSelector = solutionSelector;
this.solutionAcceptor = solutionAcceptor;
this.solutionCostCalculator = solutionCostCalculator;
logger.info("initialise " + this);
}
public String getName() {
public SearchStrategy(String id, SolutionSelector solutionSelector, SolutionAcceptor solutionAcceptor, SolutionCostCalculator solutionCostCalculator) {
if(id == null) throw new IllegalStateException("strategy id cannot be null");
this.solutionSelector = solutionSelector;
this.solutionAcceptor = solutionAcceptor;
this.solutionCostCalculator = solutionCostCalculator;
this.id = id;
logger.info("initialise " + this);
}
public String getId() {
return id;
}
public String getName() {
return name;
}

View file

@ -1,16 +1,16 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* 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
* 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 <http://www.gnu.org/licenses/>.
******************************************************************************/
@ -20,11 +20,7 @@ import jsprit.core.algorithm.listener.SearchStrategyListener;
import jsprit.core.algorithm.listener.SearchStrategyModuleListener;
import jsprit.core.util.RandomNumberGeneration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.*;
public class SearchStrategyManager {
@ -33,11 +29,15 @@ public class SearchStrategyManager {
private List<SearchStrategy> strategies = new ArrayList<SearchStrategy>();
private List<Double> probabilities = new ArrayList<Double>();
private List<Double> weights = new ArrayList<Double>();
private Map<String, Integer> id2index = new HashMap<String,Integer>();
private Random random = RandomNumberGeneration.getRandom();
private double sumOfProbabilities = 0;
private double sumWeights = 0;
private int strategyIndex = 0;
public void setRandom(Random random) {
this.random = random;
@ -49,34 +49,53 @@ public class SearchStrategyManager {
}
/**
* Returns the probabilities.
* [schroeder (2014.11.21): Now they are actually no propabilities anymore but weights. The resulting probabilities
* are calculated here with the sum of weights]
* @return list of probabilities
*/
public List<Double> getProbabilities() {
return Collections.unmodifiableList(probabilities);
return Collections.unmodifiableList(weights);
}
/**
* adds a new search strategy. the probability must be within [0,1].
* adds a new search strategy with a certain weight.
* @param strategy strategy to be added
* @param probability probability of corresponding strategy to be added
* @throws java.lang.IllegalStateException if strategy is null OR prob > 1. OR prob < 0.
* @param weight of corresponding strategy to be added
* @throws java.lang.IllegalStateException if strategy is null OR weight < 0
*/
public void addStrategy(SearchStrategy strategy, double probability){
if(strategy == null){
throw new IllegalStateException("strategy is null. make sure adding a valid strategy.");
}
if(probability > 1.0){
throw new IllegalStateException("probability is higher than one, but it must be within [0,1].");
}
if(probability < 0.0){
throw new IllegalStateException("probability is lower than zero, but it must be within [0,1].");
public void addStrategy(SearchStrategy strategy, double weight){
if(strategy == null){
throw new IllegalStateException("strategy is null. make sure adding a valid strategy.");
}
if(id2index.keySet().contains(strategy.getId())){
throw new IllegalStateException("strategyId " + strategy.getId() + " already in use");
}
if(weight < 0.0){
throw new IllegalStateException("weight is lower than zero.");
}
id2index.put(strategy.getId(),strategyIndex);
strategyIndex++;
strategies.add(strategy);
probabilities.add(probability);
sumOfProbabilities += probability;
if(sumOfProbabilities > 1.0){
throw new IllegalStateException("total probability of all strategies is higher than one, but it must be within [0,1].");
}
weights.add(weight);
sumWeights += weight;
}
public void informStrategyWeightChanged(String strategyId, double weight){
int strategyIndex = id2index.get(strategyId);
weights.set(strategyIndex, weight);
updateSumWeights();
}
private void updateSumWeights() {
double sum = 0.;
for(double w : weights){
sum += w;
}
sumWeights = sum;
}
/**
* Returns search strategy that has been randomly selected.
*
@ -86,10 +105,10 @@ public class SearchStrategyManager {
public SearchStrategy getRandomStrategy() {
if(random == null) throw new IllegalStateException("randomizer is null. make sure you set random object correctly");
double randomFig = random.nextDouble();
double sumWeight = 0.0;
for (int i = 0; i < probabilities.size(); i++) {
sumWeight += probabilities.get(i);
if (randomFig < sumWeight) {
double sumProbabilities = 0.0;
for (int i = 0; i < weights.size(); i++) {
sumProbabilities += weights.get(i) / sumWeights;
if (randomFig < sumProbabilities) {
return strategies.get(i);
}
}

View file

@ -193,7 +193,6 @@ public class VehicleRoutingAlgorithm {
logger.info("------------------------------------------------");
logger.info("algorithm starts");
double now = System.currentTimeMillis();
verify();
int noIterationsThisAlgoIsRunning = maxIterations;
counter.reset();
Collection<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>(initialSolutions);
@ -248,17 +247,7 @@ public class VehicleRoutingAlgorithm {
public int getNuOfIterations(){
return maxIterations;
}
/**
* Asserts that the sum of probabilities of the searchStrategies is equal to 1.0.
*/
private void verify() {
double sum = 0.0;
for(Double prob : searchStrategyManager.getProbabilities()){
sum += prob;
}
if(sum < 1.0*0.99 || sum > 1.0*1.01) throw new IllegalStateException("sum of probabilities is not 1.0, but is "+ sum + ". make sure that the sum of the probability of each searchStrategy is 1.0");
}
private void algorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
algoListeners.algorithmEnds(problem, solutions);