轮盘赌选择算法

发布于 2024-07-09 05:24:49 字数 61 浏览 11 评论 0原文

谁能提供一些轮盘赌选择函数的伪代码? 我将如何实现这个:我真的不明白如何阅读这个数学符号。我想要通用算法。

Can anyone provide some pseudo code for a roulette selection function? How would I implement this: I don't really understand how to read this math notation.I want General algorithm to this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

挥剑断情 2024-07-16 05:24:49

其他答案似乎假设您正在尝试实现轮盘赌游戏。 我认为您问的是进化算法中的轮盘赌选择。

此处是一些实现轮盘赌选择的Java代码

假设您有 10 个项目可供选择,并且您通过生成 0 到 1 之间的随机数进行选择。您将 0 到 1 的范围划分为十个不重叠的部分,每个部分与十个项目之一的适合度成比例。 例如,这可能看起来像这样:

0 - 0.3 is item 1
0.3 - 0.4 is item 2
0.4 - 0.5 is item 3
0.5 - 0.57 is item 4
0.57 - 0.63 is item 5
0.63 - 0.68 is item 6
0.68 - 0.8 is item 7
0.8 - 0.85 is item 8
0.85 - 0.98 is item 9
0.98 - 1 is item 10

这是您的轮盘赌轮。 0 到 1 之间的随机数就是你的旋转。 如果随机数为 0.46,则选择的项目为项目 3。如果随机数为 0.92,则选择项目为项目 9。

The other answers seem to be assuming that you are trying to implement a roulette game. I think that you are asking about roulette wheel selection in evolutionary algorithms.

Here is some Java code that implements roulette wheel selection.

Assume you have 10 items to choose from and you choose by generating a random number between 0 and 1. You divide the range 0 to 1 up into ten non-overlapping segments, each proportional to the fitness of one of the ten items. For example, this might look like this:

0 - 0.3 is item 1
0.3 - 0.4 is item 2
0.4 - 0.5 is item 3
0.5 - 0.57 is item 4
0.57 - 0.63 is item 5
0.63 - 0.68 is item 6
0.68 - 0.8 is item 7
0.8 - 0.85 is item 8
0.85 - 0.98 is item 9
0.98 - 1 is item 10

This is your roulette wheel. Your random number between 0 and 1 is your spin. If the random number is 0.46, then the chosen item is item 3. If it's 0.92, then it's item 9.

黒涩兲箜 2024-07-16 05:24:49
def roulette_select(population, fitnesses, num):
    """ Roulette selection, implemented according to:
        <http://stackoverflow.com/questions/177271/roulette
        -selection-in-genetic-algorithms/177278#177278>
    """
    total_fitness = float(sum(fitnesses))
    rel_fitness = [f/total_fitness for f in fitnesses]
    # Generate probability intervals for each individual
    probs = [sum(rel_fitness[:i+1]) for i in range(len(rel_fitness))]
    # Draw new population
    new_population = []
    for n in xrange(num):
        r = rand()
        for (i, individual) in enumerate(population):
            if r <= probs[i]:
                new_population.append(individual)
                break
    return new_population
def roulette_select(population, fitnesses, num):
    """ Roulette selection, implemented according to:
        <http://stackoverflow.com/questions/177271/roulette
        -selection-in-genetic-algorithms/177278#177278>
    """
    total_fitness = float(sum(fitnesses))
    rel_fitness = [f/total_fitness for f in fitnesses]
    # Generate probability intervals for each individual
    probs = [sum(rel_fitness[:i+1]) for i in range(len(rel_fitness))]
    # Draw new population
    new_population = []
    for n in xrange(num):
        r = rand()
        for (i, individual) in enumerate(population):
            if r <= probs[i]:
                new_population.append(individual)
                break
    return new_population
思慕 2024-07-16 05:24:49

首先,生成一个由您指定的百分比组成的数组,例如 p[1..n]
并假设总数是所有百分比的总和。

然后得到一个1到total之间的随机数,比如说r

现在,lua中的算法:

local  c  =  0
for i = 1,n do
    c = c + p[i]
    if r <= c then
        return i
    end
end

First, generate an array of the percentages you assigned, let's say p[1..n]
and assume the total is the sum of all the percentages.

Then get a random number between 1 to total, let's say r

Now, the algorithm in lua:

local  c  =  0
for i = 1,n do
    c = c + p[i]
    if r <= c then
        return i
    end
end
意中人 2024-07-16 05:24:49

有两个步骤:首先创建一个包含轮盘上所有值的数组。 这可以是一个包含颜色和数字的二维数组,或者您可以选择将 100 添加到红色数字。

然后简单地生成一个介于 0 或 1(取决于您的语言是否从 0 或 1 开始对数组索引进行编号)和数组中最后一个元素之间的随机数。

大多数语言都有内置的随机数函数。 在 VB 和 VBScript 中,该函数是 RND()。 在 Javascript 中,它是 Math.random()

从数组中的该位置获取值,您就得到了随机轮盘赌号码。

最后一点:不要忘记为随机数生成器添加种子,否则每次运行程序时都会得到相同的抽奖序列。

There are 2 steps to this: First create an array with all the values on the wheel. This can be a 2 dimensional array with colour as well as number, or you can choose to add 100 to red numbers.

Then simply generate a random number between 0 or 1 (depending on whether your language starts numbering array indexes from 0 or 1) and the last element in your array.

Most languages have built-in random number functions. In VB and VBScript the function is RND(). In Javascript it is Math.random()

Fetch the value from that position in the array and you have your random roulette number.

Final note: don't forget to seed your random number generator or you will get the same sequence of draws every time you run the program.

鲜肉鲜肉永远不皱 2024-07-16 05:24:49

这是一种使用 Java 中的流选择来实现这一点的非常快速的方法。 它使用值作为权重来选择数组的索引。 由于数学属性,不需要累积权重。

static int selectRandomWeighted(double[] wts, Random rnd) {
    int selected = 0;
    double total = wts[0];

    for( int i = 1; i < wts.length; i++ ) {
        total += wts[i];            
        if( rnd.nextDouble() <= (wts[i] / total)) selected = i;
    }

    return selected;        
}

这可以使用 Kahan 求和 进一步改进,或者如果数组太小,则将双精度数作为可迭代对象读取大到可以立即初始化。

Here is a really quick way to do it using stream selection in Java. It selects the indices of an array using the values as weights. No cumulative weights needed due to the mathematical properties.

static int selectRandomWeighted(double[] wts, Random rnd) {
    int selected = 0;
    double total = wts[0];

    for( int i = 1; i < wts.length; i++ ) {
        total += wts[i];            
        if( rnd.nextDouble() <= (wts[i] / total)) selected = i;
    }

    return selected;        
}

This could be further improved using Kahan summation or reading through the doubles as an iterable if the array was too big to initialize at once.

千寻… 2024-07-16 05:24:49

我想要同样的东西,所以创建了这个独立的轮盘赌类。 您给它一系列权重(以双精度数组的形式),它只会根据加权随机选择从该数组返回一个索引。

我创建了一个类,因为您只需通过构造函数执行一次累积添加即可获得很大的速度。 这是 C# 代码,但享受 C 般的速度和简单性!

class Roulette
{
    double[] c;
    double total;
    Random random;

    public Roulette(double[] n) {
        random = new Random();
        total = 0;
        c = new double[n.Length+1];
        c[0] = 0;
        // Create cumulative values for later:
        for (int i = 0; i < n.Length; i++) {
            c[i+1] = c[i] + n[i];
            total += n[i];
        }
    }

    public int spin() {
        double r = random.NextDouble() * total;     // Create a random number between 0 and 1 and times by the total we calculated earlier.
        //int j; for (j = 0; j < c.Length; j++) if (c[j] > r) break; return j-1; // Don't use this - it's slower than the binary search below.

        //// Binary search for efficiency. Objective is to find index of the number just above r:
        int a = 0;
        int b = c.Length - 1;
        while (b - a > 1) {
            int mid = (a + b) / 2;
            if (c[mid] > r) b = mid;
            else a = mid;
        }
        return a;
    }
}

初始重量由您决定。 也许它可以是每个成员的适应度,或者是与成员在“前50名”中的位置成反比的值。 例如:第一名 = 1.0 权重,第二名 = 0.5,第三名 = 0.333,第四名 = 0.25 权重等。

I wanted the same and so created this self-contained Roulette class. You give it a series of weights (in the form of a double array), and it will simply return an index from that array according to a weighted random pick.

I created a class because you can get a big speed up by only doing the cumulative additions once via the constructor. It's C# code, but enjoy the C like speed and simplicity!

class Roulette
{
    double[] c;
    double total;
    Random random;

    public Roulette(double[] n) {
        random = new Random();
        total = 0;
        c = new double[n.Length+1];
        c[0] = 0;
        // Create cumulative values for later:
        for (int i = 0; i < n.Length; i++) {
            c[i+1] = c[i] + n[i];
            total += n[i];
        }
    }

    public int spin() {
        double r = random.NextDouble() * total;     // Create a random number between 0 and 1 and times by the total we calculated earlier.
        //int j; for (j = 0; j < c.Length; j++) if (c[j] > r) break; return j-1; // Don't use this - it's slower than the binary search below.

        //// Binary search for efficiency. Objective is to find index of the number just above r:
        int a = 0;
        int b = c.Length - 1;
        while (b - a > 1) {
            int mid = (a + b) / 2;
            if (c[mid] > r) b = mid;
            else a = mid;
        }
        return a;
    }
}

The initial weights are up to you. Maybe it could be the fitness of each member, or a value inversely proportional to the member's position in the "top 50". E.g.: 1st place = 1.0 weighting, 2nd place = 0.5, 3rd place = 0.333, 4th place = 0.25 weighting etc. etc.

我一向站在原地 2024-07-16 05:24:49

嗯,对于美式轮盘,您需要生成一个 1 到 38 之间的随机整数。有 36 个数字,一个 0 和一个 00。

不过,需要考虑的重要事项之一是在美式轮盘中轮盘赌,可以进行许多不同的投注。 单次投注可以涵盖 1、2、3、4、5、6、两个不同的 12 或 18。您可能希望创建一个列表列表,其中每个数字都有附加标志来简化,或者在编程中完成这一切。

如果我在 Python 中实现它,我只需创建一个 0、00、1 到 36 的元组,并为每次旋转使用 random.choice()。

Well, for an American Roulette wheel, you're going to need to generate a random integer between 1 and 38. There are 36 numbers, a 0, and a 00.

One of the big things to consider, though, is that in American roulette, their are many different bets that can be made. A single bet can cover 1, 2, 3, 4, 5, 6, two different 12s, or 18. You may wish to create a list of lists where each number has additional flages to simplify that, or do it all in the programming.

If I were implementing it in Python, I would just create a Tuple of 0, 00, and 1 through 36 and use random.choice() for each spin.

浅暮の光 2024-07-16 05:24:49

这假设某个类“分类器”仅具有字符串条件、字符串消息和双倍强度。 只要遵循逻辑即可。

——保罗

public static List<Classifier> rouletteSelection(int classifiers) {
    List<Classifier> classifierList = new LinkedList<Classifier>();
    double strengthSum = 0.0;
    double probabilitySum = 0.0;

    // add up the strengths of the map
    Set<String> keySet = ClassifierMap.CLASSIFIER_MAP.keySet();
    for (String key : keySet) {
        /* used for debug to make sure wheel is working.
        if (strengthSum == 0.0) {
        ClassifierMap.CLASSIFIER_MAP.get(key).setStrength(8000.0);
        }
         */
        Classifier classifier = ClassifierMap.CLASSIFIER_MAP.get(key);
        double strength = classifier.getStrength();
        strengthSum = strengthSum + strength;
    }
    System.out.println("strengthSum: " + strengthSum);

    // compute the total probability. this will be 1.00 or close to it.
    for (String key : keySet) {
        Classifier classifier = ClassifierMap.CLASSIFIER_MAP.get(key);
        double probability = (classifier.getStrength() / strengthSum);
        probabilitySum = probabilitySum + probability;
    }
    System.out.println("probabilitySum: " + probabilitySum);

    while (classifierList.size() < classifiers) {
        boolean winnerFound = false;
        double rouletteRandom = random.nextDouble();
        double rouletteSum = 0.0;

        for (String key : keySet) {
            Classifier classifier = ClassifierMap.CLASSIFIER_MAP.get(key);
            double probability = (classifier.getStrength() / strengthSum);
            rouletteSum = rouletteSum + probability;
            if (rouletteSum > rouletteRandom && (winnerFound == false)) {
                System.out.println("Winner found: " + probability);
                classifierList.add(classifier);
                winnerFound = true;
            }
        }
    }
    return classifierList;
}

This assumes some class "Classifier" which just has a String condition, String message, and double strength. Just follow the logic.

-- Paul

public static List<Classifier> rouletteSelection(int classifiers) {
    List<Classifier> classifierList = new LinkedList<Classifier>();
    double strengthSum = 0.0;
    double probabilitySum = 0.0;

    // add up the strengths of the map
    Set<String> keySet = ClassifierMap.CLASSIFIER_MAP.keySet();
    for (String key : keySet) {
        /* used for debug to make sure wheel is working.
        if (strengthSum == 0.0) {
        ClassifierMap.CLASSIFIER_MAP.get(key).setStrength(8000.0);
        }
         */
        Classifier classifier = ClassifierMap.CLASSIFIER_MAP.get(key);
        double strength = classifier.getStrength();
        strengthSum = strengthSum + strength;
    }
    System.out.println("strengthSum: " + strengthSum);

    // compute the total probability. this will be 1.00 or close to it.
    for (String key : keySet) {
        Classifier classifier = ClassifierMap.CLASSIFIER_MAP.get(key);
        double probability = (classifier.getStrength() / strengthSum);
        probabilitySum = probabilitySum + probability;
    }
    System.out.println("probabilitySum: " + probabilitySum);

    while (classifierList.size() < classifiers) {
        boolean winnerFound = false;
        double rouletteRandom = random.nextDouble();
        double rouletteSum = 0.0;

        for (String key : keySet) {
            Classifier classifier = ClassifierMap.CLASSIFIER_MAP.get(key);
            double probability = (classifier.getStrength() / strengthSum);
            rouletteSum = rouletteSum + probability;
            if (rouletteSum > rouletteRandom && (winnerFound == false)) {
                System.out.println("Winner found: " + probability);
                classifierList.add(classifier);
                winnerFound = true;
            }
        }
    }
    return classifierList;
}
我也只是我 2024-07-16 05:24:49

您可以使用如下数据结构:

Map<A, B> roulette_wheel_schema = new LinkedHashMap<A, B>()

其中 A 是一个整数,代表轮盘赌轮的一个口袋,B 是标识群体中染色体的索引。 口袋的数量与每条染色体的适应度比例成正比:

口袋数量=(适应度比例)·(比例因子)

然后我们生成一个介于 0 和选择模式大小之间的随机数,并用我们从轮盘赌中得到这个随机数的染色体索引。

我们计算每个染色体的适应度比例与被选择方案选择的概率之间的相对误差。

getRouletteWheel 方法返回基于先前数据结构的选择方案。

private Map<Integer, Integer> getRouletteWheel(
        ArrayList<Chromosome_fitnessProportionate> chromosomes,
        int precision) {

    /*
     * The number of pockets on the wheel
     * 
     * number of pockets in roulette_wheel_schema = probability ·
     * (10^precision)
     */
    Map<Integer, Integer> roulette_wheel_schema = new LinkedHashMap<Integer, Integer>();
    double fitness_proportionate = 0.0D;
    double pockets = 0.0D;
    int key_counter = -1;
    double scale_factor = Math
            .pow(new Double(10.0D), new Double(precision));
    for (int index_cromosome = 0; index_cromosome < chromosomes.size(); index_cromosome++){

        Chromosome_fitnessProportionate chromosome = chromosomes
                .get(index_cromosome);
        fitness_proportionate = chromosome.getFitness_proportionate();
        fitness_proportionate *= scale_factor;
        pockets = Math.rint(fitness_proportionate);
        System.out.println("... " + index_cromosome + " : " + pockets);

        for (int j = 0; j < pockets; j++) {
            roulette_wheel_schema.put(Integer.valueOf(++key_counter),
                    Integer.valueOf(index_cromosome));
        }
    }

    return roulette_wheel_schema;
}

You can use a data structure like this:

Map<A, B> roulette_wheel_schema = new LinkedHashMap<A, B>()

where A is an integer that represents a pocket of the roulette wheel, and B is an index that identifies a chromosome in the population. The number of pockets is proportional to the fitness proportionate of each chromosome:

number of pockets = (fitness proportionate) · (scale factor)

Then we generate a random between 0 and the size of the selection schema and with this random number we get the index of the chromosome from the roulette.

We calculate the relative error between the fitness proportionate of each chromosome and the probability of being selected by the selection scheme.

The method getRouletteWheel returns the selection scheme based on previous data structure.

private Map<Integer, Integer> getRouletteWheel(
        ArrayList<Chromosome_fitnessProportionate> chromosomes,
        int precision) {

    /*
     * The number of pockets on the wheel
     * 
     * number of pockets in roulette_wheel_schema = probability ·
     * (10^precision)
     */
    Map<Integer, Integer> roulette_wheel_schema = new LinkedHashMap<Integer, Integer>();
    double fitness_proportionate = 0.0D;
    double pockets = 0.0D;
    int key_counter = -1;
    double scale_factor = Math
            .pow(new Double(10.0D), new Double(precision));
    for (int index_cromosome = 0; index_cromosome < chromosomes.size(); index_cromosome++){

        Chromosome_fitnessProportionate chromosome = chromosomes
                .get(index_cromosome);
        fitness_proportionate = chromosome.getFitness_proportionate();
        fitness_proportionate *= scale_factor;
        pockets = Math.rint(fitness_proportionate);
        System.out.println("... " + index_cromosome + " : " + pockets);

        for (int j = 0; j < pockets; j++) {
            roulette_wheel_schema.put(Integer.valueOf(++key_counter),
                    Integer.valueOf(index_cromosome));
        }
    }

    return roulette_wheel_schema;
}
一场信仰旅途 2024-07-16 05:24:49

我已经编写了类似于 Dan Dyer 的 Java 代码(前面引用过)。 然而,我的轮盘赌轮根据概率向量(输入)选择单个元素并返回所选元素的索引。
话虽如此,如果选择大小是单一的并且您不假设如何计算概率并且允许零概率值,则以下代码更合适。 该代码是独立的,包括 20 次轮子旋转(运行)的测试。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Roulette-wheel Test version.
 * Features a probability vector input with possibly null probability values.
 * Appropriate for adaptive operator selection such as Probability Matching 
 * or Adaptive Pursuit, (Dynamic) Multi-armed Bandit.
 * @version October 2015.
 * @author Hakim Mitiche
 */
public class RouletteWheel {

/**
 * Selects an element probabilistically.  
 * @param wheelProbabilities elements probability vector.
 * @param rng random generator object
 * @return selected element index
 * @throws java.lang.Exception 
 */
public int select(List<Double> wheelProbabilities, Random rng) 
        throws Exception{

    double[] cumulativeProba = new double[wheelProbabilities.size()];
    cumulativeProba[0] = wheelProbabilities.get(0);
    for (int i = 1; i < wheelProbabilities.size(); i++)
    {
        double proba = wheelProbabilities.get(i);
        cumulativeProba[i] = cumulativeProba[i - 1] + proba;
    }
    int last = wheelProbabilities.size()-1;
     if (cumulativeProba[last] != 1.0)
     {
            throw new Exception("The probabilities does not sum up to one ("
                    + "sum="+cumulativeProba[last]);
     }
    double r = rng.nextDouble();
    int selected = Arrays.binarySearch(cumulativeProba, r);
     if (selected < 0)
        {
            /* Convert negative insertion point to array index.
            to find the correct cumulative proba range index.
            */
            selected = Math.abs(selected + 1);
        }
     /* skip indexes of elements with Zero probability, 
        go backward to matching index*/  
    int i = selected; 
    while (wheelProbabilities.get(i) == 0.0){
        System.out.print(i+" selected, correction");
        i--;
        if (i<0) i=last;
    }
    selected = i;
    return selected;
}



   public static void main(String[] args){

   RouletteWheel rw = new RouletteWheel();
   int rept = 20;
   List<Double> P = new ArrayList<>(4);
   P.add(0.2);
   P.add(0.1);
   P.add(0.6);
   P.add(0.1);
   Random rng = new Random();
   for (int i = 0 ; i < rept; i++){
       try {
           int s = rw.select(P, rng);
           System.out.println("Element selected "+s+ ", P(s)="+P.get(s));
       } catch (Exception ex) {
           Logger.getLogger(RouletteWheel.class.getName()).log(Level.SEVERE, null, ex);
       }
   }
   P.clear();
   P.add(0.2);
   P.add(0.0);
   P.add(0.5);
   P.add(0.0);
   P.add(0.1);
   P.add(0.2);
   //rng = new Random();
   for (int i = 0 ; i < rept; i++){
       try {
           int s = rw.select(P, rng);
           System.out.println("Element selected "+s+ ", P(s)="+P.get(s));
       } catch (Exception ex) {
           Logger.getLogger(RouletteWheel.class.getName()).log(Level.SEVERE, null, ex);
       }
   }
}

 /**
 * {@inheritDoc}
 * @return 
 */
 @Override
 public String toString()
 {
    return "Roulette Wheel Selection";
 }
}

下面是概率向量 P=[0.2,0.1,0.6,0.1] 的执行示例,
WheelElements = [0,1,2,3]:

选择的元素 3,P(s)=0.1

选择的元素 2,P(s)=0.6

选择的元素 3,P(s)=0.1

选择的元素 2,P(s) =0.6

选择的元素 1,P(s)=0.1

选择的元素 2,P(s)=0.6

选择的元素 3,P(s)=0.1

选择的元素 2,P(s)=0.6

选择的元素 2,P(s) =0.6

选择的元素 2,P(s)=0.6

选择的元素 2,P(s)=0.6

选择的元素 2,P(s)=0.6

选择的元素 3,P(s)=0.1

选择的元素 2,P(s) =0.6

选择的元素 2,P(s)=0.6

选择的元素 2,P(s)=0.6

选择的元素 0,P(s)=0.2

选择的元素 2,P(s)=0.6

选择的元素 2,P(s) =0.6

选择元素 2,P(s)=0.6

该代码还以零概率测试轮盘赌轮。

I have worked out a Java code similar to that of Dan Dyer (referenced earlier). My roulette-wheel, however, selects a single element based on a probability vector (input) and returns the index of the selected element.
Having said that, the following code is more appropriate if the selection size is unitary and if you do not assume how the probabilities are calculated and zero probability value is allowed. The code is self-contained and includes a test with 20 wheel spins (to run).

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Roulette-wheel Test version.
 * Features a probability vector input with possibly null probability values.
 * Appropriate for adaptive operator selection such as Probability Matching 
 * or Adaptive Pursuit, (Dynamic) Multi-armed Bandit.
 * @version October 2015.
 * @author Hakim Mitiche
 */
public class RouletteWheel {

/**
 * Selects an element probabilistically.  
 * @param wheelProbabilities elements probability vector.
 * @param rng random generator object
 * @return selected element index
 * @throws java.lang.Exception 
 */
public int select(List<Double> wheelProbabilities, Random rng) 
        throws Exception{

    double[] cumulativeProba = new double[wheelProbabilities.size()];
    cumulativeProba[0] = wheelProbabilities.get(0);
    for (int i = 1; i < wheelProbabilities.size(); i++)
    {
        double proba = wheelProbabilities.get(i);
        cumulativeProba[i] = cumulativeProba[i - 1] + proba;
    }
    int last = wheelProbabilities.size()-1;
     if (cumulativeProba[last] != 1.0)
     {
            throw new Exception("The probabilities does not sum up to one ("
                    + "sum="+cumulativeProba[last]);
     }
    double r = rng.nextDouble();
    int selected = Arrays.binarySearch(cumulativeProba, r);
     if (selected < 0)
        {
            /* Convert negative insertion point to array index.
            to find the correct cumulative proba range index.
            */
            selected = Math.abs(selected + 1);
        }
     /* skip indexes of elements with Zero probability, 
        go backward to matching index*/  
    int i = selected; 
    while (wheelProbabilities.get(i) == 0.0){
        System.out.print(i+" selected, correction");
        i--;
        if (i<0) i=last;
    }
    selected = i;
    return selected;
}



   public static void main(String[] args){

   RouletteWheel rw = new RouletteWheel();
   int rept = 20;
   List<Double> P = new ArrayList<>(4);
   P.add(0.2);
   P.add(0.1);
   P.add(0.6);
   P.add(0.1);
   Random rng = new Random();
   for (int i = 0 ; i < rept; i++){
       try {
           int s = rw.select(P, rng);
           System.out.println("Element selected "+s+ ", P(s)="+P.get(s));
       } catch (Exception ex) {
           Logger.getLogger(RouletteWheel.class.getName()).log(Level.SEVERE, null, ex);
       }
   }
   P.clear();
   P.add(0.2);
   P.add(0.0);
   P.add(0.5);
   P.add(0.0);
   P.add(0.1);
   P.add(0.2);
   //rng = new Random();
   for (int i = 0 ; i < rept; i++){
       try {
           int s = rw.select(P, rng);
           System.out.println("Element selected "+s+ ", P(s)="+P.get(s));
       } catch (Exception ex) {
           Logger.getLogger(RouletteWheel.class.getName()).log(Level.SEVERE, null, ex);
       }
   }
}

 /**
 * {@inheritDoc}
 * @return 
 */
 @Override
 public String toString()
 {
    return "Roulette Wheel Selection";
 }
}

Below an execution sample for a proba vector P=[0.2,0.1,0.6,0.1],
WheelElements = [0,1,2,3]:

Element selected 3, P(s)=0.1

Element selected 2, P(s)=0.6

Element selected 3, P(s)=0.1

Element selected 2, P(s)=0.6

Element selected 1, P(s)=0.1

Element selected 2, P(s)=0.6

Element selected 3, P(s)=0.1

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

Element selected 3, P(s)=0.1

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

Element selected 0, P(s)=0.2

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

Element selected 2, P(s)=0.6

The code also tests a roulette wheel with zero probability.

岁月静好 2024-07-16 05:24:49

恐怕任何在所有编程语言中使用内置随机数生成器的人都必须意识到生成的数字不是 100% 随机的。因此应谨慎使用。

I am afraid that anybody using the in built random number generator in all programming languages must be aware that the number generated is not 100% random.So should be used with caution.

七婞 2024-07-16 05:24:49

随机数生成器伪代码

  • 向顺序计数器加一,
  • 获取顺序计数器的当前值,
  • 通过计算机滴答计数添加计数器值或一些其他小间隔计时器值(
  • 可选 )添加加法数字,例如来自外部硬件(如等离子体发生器)的数字或某种其他类型的随机现象,
  • 将结果除以一个非常大的素数
    例如359334085968622831041960188598043661065388726959079837
  • 从结果的小数点最右边获取一些数字,
  • 使用这些数字作为随机数

使用随机数数字创建1到38(或37欧)之间的随机数轮盘赌。

Random Number Generator pseudo code

  • add one to a sequential counter
  • get the current value of the sequential counter
  • add the counter value by the computer tick count or some other small interval timer value
  • optionally add addition numbers, like a number from an external piece of hardware like a plasma generator or some other type of somewhat random phenomena
  • divide the result by a very big prime number
    359334085968622831041960188598043661065388726959079837 for example
  • get some digits from the far right of the decimal point of the result
  • use these digits as a random number

Use the random number digits to create random numbers between 1 and 38 (or 37 European) for roulette.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文