All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jamesframework.core.util.RouletteSelector Maven / Gradle / Ivy

Go to download

The James core module is part of the James framework for optimization using local search metaheuristics in Java. The core contains general components to model problems, objectives and constraints, as well as generic algorithms to solve the problems. Moreover, the core provides implementations of specific utilities for subset selection.

There is a newer version: 1.2
Show newest version
//  Copyright 2014 Herman De Beukelaer
//
//  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.

package org.jamesframework.core.util;

import java.util.List;
import java.util.Random;

/**
 * 

* A selection object which simulates a roulette wheel where all items have a weight expressing the * size of their section of the wheel. The size of the wheel is the sum of all item weights. During * selection a random number in (0, wheel size) is picked and then the item corresponding to this * section of the wheel is selected. *

*

* For a set of items with equal weight they will all have the same probability of being selected. * Items which are assigned higher weights will have a higher likelihood of being selected (and the * opposite holds for lower weights). *

*

* The implementation is heavily inspired by original code written by the Apache Software Foundation * (http://www.apache.org) for the Hadoop MapReduce * project (http://hadoop.apache.org). *

* * @param type of items from which one is to be selected * @author Herman De Beukelaer */ public class RouletteSelector { // applied random generator private final Random picker; /** * Create a roulette selector. * * @param rnd applied random generator */ public RouletteSelector(Random rnd) { this.picker = rnd; } /** * Select an item from a given list by roulette selection, where each item has a weight expressing * the size of its share of the roulette wheel. The total size of the wheel is the sum of all item * weights. The list of items and weights should be of the same size and all weights should be * positive. A weight of zero is allowed, in which case the respective item will never be selected. * One item is always selected, except when the item list is empty or when all weights are zero in * which case null is returned. * * @param items items from which one is to be selected * @param weights item weights (same order as items) * @return item selected by roulette selection, null if all weights are zero * or the item list is empty * @throws IllegalArgumentException if both lists are not of the same size or if any of the * given weights is < 0 * @throws NullPointerException if items or weights are null * or if weights contains any null elements */ public E select(List items, List weights){ // check null if(items == null){ throw new NullPointerException("List of items can not be null."); } if(weights == null){ throw new NullPointerException("List of weights can not be null."); } // check list sizes if(items.size() != weights.size()){ throw new IllegalArgumentException("Item and weight lists should be of the same size."); } // return null if no items given if(items.isEmpty()){ return null; } // at least one item: compute total weight double totalWeight = 0; for(Double w : weights){ // check not null if(w == null){ throw new NullPointerException("Null elements not allowed in weights list."); } // check positive if(w < 0){ throw new IllegalArgumentException("Negative weights not allowed."); } // increase sum totalWeight += w; } if(totalWeight > 0){ // roulette wheel selection double r = picker.nextDouble() * totalWeight; int i=0; while(i < items.size() && r > 0){ r -= weights.get(i); i++; } return items.get(i-1); } else { // all items have weight zero return null; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy