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:
parent
a32a750bed
commit
64b5d77267
3 changed files with 79 additions and 64 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2013 Stefan Schroeder
|
* Copyright (C) 2014 Stefan Schroeder
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -61,24 +61,31 @@ public class SearchStrategy {
|
||||||
|
|
||||||
private static Logger logger = LogManager.getLogger(SearchStrategy.class);
|
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;
|
private String name;
|
||||||
|
|
||||||
public SearchStrategy(SolutionSelector solutionSelector, SolutionAcceptor solutionAcceptor, SolutionCostCalculator solutionCostCalculator) {
|
public SearchStrategy(String id, SolutionSelector solutionSelector, SolutionAcceptor solutionAcceptor, SolutionCostCalculator solutionCostCalculator) {
|
||||||
super();
|
if(id == null) throw new IllegalStateException("strategy id cannot be null");
|
||||||
this.solutionSelector = solutionSelector;
|
this.solutionSelector = solutionSelector;
|
||||||
this.solutionAcceptor = solutionAcceptor;
|
this.solutionAcceptor = solutionAcceptor;
|
||||||
this.solutionCostCalculator = solutionCostCalculator;
|
this.solutionCostCalculator = solutionCostCalculator;
|
||||||
|
this.id = id;
|
||||||
logger.info("initialise " + this);
|
logger.info("initialise " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2013 Stefan Schroeder
|
* Copyright (C) 2014 Stefan Schroeder
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -20,11 +20,7 @@ import jsprit.core.algorithm.listener.SearchStrategyListener;
|
||||||
import jsprit.core.algorithm.listener.SearchStrategyModuleListener;
|
import jsprit.core.algorithm.listener.SearchStrategyModuleListener;
|
||||||
import jsprit.core.util.RandomNumberGeneration;
|
import jsprit.core.util.RandomNumberGeneration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class SearchStrategyManager {
|
public class SearchStrategyManager {
|
||||||
|
|
@ -33,11 +29,15 @@ public class SearchStrategyManager {
|
||||||
|
|
||||||
private List<SearchStrategy> strategies = new ArrayList<SearchStrategy>();
|
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 Random random = RandomNumberGeneration.getRandom();
|
||||||
|
|
||||||
private double sumOfProbabilities = 0;
|
private double sumWeights = 0;
|
||||||
|
|
||||||
|
private int strategyIndex = 0;
|
||||||
|
|
||||||
public void setRandom(Random random) {
|
public void setRandom(Random random) {
|
||||||
this.random = random;
|
this.random = random;
|
||||||
|
|
@ -49,32 +49,51 @@ 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() {
|
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 strategy strategy to be added
|
||||||
* @param probability probability of corresponding strategy to be added
|
* @param weight of corresponding strategy to be added
|
||||||
* @throws java.lang.IllegalStateException if strategy is null OR prob > 1. OR prob < 0.
|
* @throws java.lang.IllegalStateException if strategy is null OR weight < 0
|
||||||
*/
|
*/
|
||||||
public void addStrategy(SearchStrategy strategy, double probability){
|
public void addStrategy(SearchStrategy strategy, double weight){
|
||||||
if(strategy == null){
|
if(strategy == null){
|
||||||
throw new IllegalStateException("strategy is null. make sure adding a valid strategy.");
|
throw new IllegalStateException("strategy is null. make sure adding a valid strategy.");
|
||||||
}
|
}
|
||||||
if(probability > 1.0){
|
if(id2index.keySet().contains(strategy.getId())){
|
||||||
throw new IllegalStateException("probability is higher than one, but it must be within [0,1].");
|
throw new IllegalStateException("strategyId " + strategy.getId() + " already in use");
|
||||||
}
|
}
|
||||||
if(probability < 0.0){
|
if(weight < 0.0){
|
||||||
throw new IllegalStateException("probability is lower than zero, but it must be within [0,1].");
|
throw new IllegalStateException("weight is lower than zero.");
|
||||||
}
|
}
|
||||||
|
id2index.put(strategy.getId(),strategyIndex);
|
||||||
|
strategyIndex++;
|
||||||
strategies.add(strategy);
|
strategies.add(strategy);
|
||||||
probabilities.add(probability);
|
weights.add(weight);
|
||||||
sumOfProbabilities += probability;
|
sumWeights += weight;
|
||||||
if(sumOfProbabilities > 1.0){
|
|
||||||
throw new IllegalStateException("total probability of all strategies is higher than one, but it must be within [0,1].");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -86,10 +105,10 @@ public class SearchStrategyManager {
|
||||||
public SearchStrategy getRandomStrategy() {
|
public SearchStrategy getRandomStrategy() {
|
||||||
if(random == null) throw new IllegalStateException("randomizer is null. make sure you set random object correctly");
|
if(random == null) throw new IllegalStateException("randomizer is null. make sure you set random object correctly");
|
||||||
double randomFig = random.nextDouble();
|
double randomFig = random.nextDouble();
|
||||||
double sumWeight = 0.0;
|
double sumProbabilities = 0.0;
|
||||||
for (int i = 0; i < probabilities.size(); i++) {
|
for (int i = 0; i < weights.size(); i++) {
|
||||||
sumWeight += probabilities.get(i);
|
sumProbabilities += weights.get(i) / sumWeights;
|
||||||
if (randomFig < sumWeight) {
|
if (randomFig < sumProbabilities) {
|
||||||
return strategies.get(i);
|
return strategies.get(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,6 @@ public class VehicleRoutingAlgorithm {
|
||||||
logger.info("------------------------------------------------");
|
logger.info("------------------------------------------------");
|
||||||
logger.info("algorithm starts");
|
logger.info("algorithm starts");
|
||||||
double now = System.currentTimeMillis();
|
double now = System.currentTimeMillis();
|
||||||
verify();
|
|
||||||
int noIterationsThisAlgoIsRunning = maxIterations;
|
int noIterationsThisAlgoIsRunning = maxIterations;
|
||||||
counter.reset();
|
counter.reset();
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>(initialSolutions);
|
Collection<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>(initialSolutions);
|
||||||
|
|
@ -249,16 +248,6 @@ public class VehicleRoutingAlgorithm {
|
||||||
return maxIterations;
|
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) {
|
private void algorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
algoListeners.algorithmEnds(problem, solutions);
|
algoListeners.algorithmEnds(problem, solutions);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue