/*******************************************************************************
* Copyright 2006 - 2012 Vienna University of Technology,
* Department of Software Technology and Interactive Systems, IFS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This work originates from the Planets project, co-funded by the European Union under the Sixth Framework Programme.
******************************************************************************/
package eu.scape_project.planning.model.sensitivity;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import eu.scape_project.planning.model.tree.TreeNode;
/**
* This weight modifier assigns random weights to children while preserving importance ordering.
*
* This meens that if you have three children with the following weights: A=0.3, B=0.6, C=0.4
* then B will remail the most important while A will be the least important. However no guarantee
* is given about what the actual resulting weights will be, only that their ordering remains the same.
*
* @author Jan Zarnikov
*
*/
public class RandomSameOrderModifier implements IWeightModifier {
private static final int ITERATIONS = 300;
private Map<Double, List<TreeNode>> sortedChildren = null;
private List<Double> sortedKeys = null;
private int counter = 0;
public boolean performModification(TreeNode node) {
// Fortunately we have to do it only once for each node.
if(sortedChildren == null) {
// We build up a map that contains all the children:
// The weight is the key and the children with this weight are the values
// Example: A=0.1, B=0.3, C=0.5, D=0.1 will produce:
// 0.1 -> {A, D}; 0.3 -> {B}; 0.5 -> {C}
sortedChildren = new HashMap<Double, List<TreeNode>>();
for(TreeNode child : node.getChildren()) {
double weight = child.getWeight();
if(sortedChildren.get(weight) == null) {
List<TreeNode> l = new LinkedList<TreeNode>();
l.add(child);
sortedChildren.put(weight, l);
} else {
sortedChildren.get(weight).add(child);
}
}
sortedKeys = new LinkedList<Double>(sortedChildren.keySet());
Collections.sort(sortedKeys);
}
// now we have to generate the new random weights
List<Double> randomWeights = new LinkedList<Double>();
for(int i = 0; i < sortedChildren.size(); i++) {
randomWeights.add(Math.random());
}
Collections.sort(randomWeights);
Iterator<Double> randomWeightsIterator = randomWeights.iterator();
// now iterate over the keys of the sortedChildren map we have generated at the beginning.
// at the same time we iterate over random weights and assign them to the children.
for(Double w : sortedKeys) {
double newWeight = randomWeightsIterator.next();
for(TreeNode tn : sortedChildren.get(w)) {
tn.setWeight(newWeight);
}
}
counter++;
if(counter < ITERATIONS) {
return true;
} else {
sortedChildren = null;
return false;
}
}
}