From 64b5d77267fd579a992090509c50c99f1f04c0b1 Mon Sep 17 00:00:00 2001
From: oblonski <4sschroeder@gmail.com>
Date: Sat, 22 Nov 2014 12:37:22 +0100
Subject: [PATCH] add infrastructure towards adaptive/dynamic search strategies
---
.../jsprit/core/algorithm/SearchStrategy.java | 43 +++++----
.../core/algorithm/SearchStrategyManager.java | 87 +++++++++++--------
.../algorithm/VehicleRoutingAlgorithm.java | 13 +--
3 files changed, 79 insertions(+), 64 deletions(-)
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java
index 6a13beab..e93ca090 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java
@@ -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 .
******************************************************************************/
@@ -61,25 +61,32 @@ public class SearchStrategy {
private static Logger logger = LogManager.getLogger(SearchStrategy.class);
- private Collection searchStrategyModules = new ArrayList();
+ private final Collection searchStrategyModules = new ArrayList();
- 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;
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java
index fb38c740..4ddfd6ba 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java
@@ -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 .
******************************************************************************/
@@ -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 strategies = new ArrayList();
- private List probabilities = new ArrayList();
+ private List weights = new ArrayList();
+
+ private Map id2index = new HashMap();
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 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);
}
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java
index 7367815b..9fbaa97a 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java
@@ -193,7 +193,6 @@ public class VehicleRoutingAlgorithm {
logger.info("------------------------------------------------");
logger.info("algorithm starts");
double now = System.currentTimeMillis();
- verify();
int noIterationsThisAlgoIsRunning = maxIterations;
counter.reset();
Collection solutions = new ArrayList(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 solutions) {
algoListeners.algorithmEnds(problem, solutions);