20

Может ли кто-нибудь предоставить некоторый псевдокод для функции выбора рулетки? Как бы это реализовать: я действительно не понимаю, как читать эту математическую нотацию. Мне нужен общий алгоритм.Алгоритм выбора колеса рулетки

+1

Отредактированные теги. Кто-то удалил «генетический» тег из первой редакции этого вопроса, что значительно уменьшило то, что было задано. – 2008-11-26 16:25:55

+1

unsigned int num = :: rand()% 37; – 2010-05-07 09:22:33

ответ

4

Есть 2 шага к этому: сначала создайте массив со всеми значениями на колесе. Это может быть двухмерный массив с цветом, а также числом, или вы можете добавить 100 красных цифр.

Затем просто создайте случайное число между 0 или 1 (в зависимости от того, начинает ли ваш язык индексировать индексы массива от 0 или 1) и последний элемент в вашем массиве.

Большинство языков имеют встроенные функции случайных чисел. В VB и VBScript функция RND(). В Javascript это Math.random()

Извлеките значение из этой позиции в массиве, и у вас есть номер случайной рулетки.

Заключительная записка: не забудьте засеять генератор случайных чисел, или вы получите одну и ту же последовательность розыгрышей при каждом запуске программы.

-5

Генератор случайных чисел псевдокод

  • добавьте в последовательный счетчик
  • получить текущее значение последовательного счетчика
  • добавить значение счетчика на компьютере клещ счетчик или какой-либо другой небольшое значение интервала таймера
  • необязательно добавлять дополнительные номера, например, номер из внешней части аппаратного обеспечения, такой как плазменный генератор или какой-либо другой ее тип несколько случайных явлений
  • делит результат на очень большом простом числе 359334085968622831041960188598043661065388726959079837, например
  • получить некоторые цифры из правой части десятичной точки результата
  • использовать эти цифры в качестве случайного номер

Используйте цифры случайных чисел для создания случайных чисел между 1 и 38 (или 37 европейскими) для рулетки.

+5

Я думаю, что случайные числа были решены на каждом языке программирования, и этот процесс больше не нужно делать вручную. Почему вы не указали на подключение всех полузагрузчиков, пока вы на это? – Karl 2008-11-27 00:22:05

1

Ну, за рулем американской рулетки, вы будете нуждаться, чтобы сгенерировать случайное число от 1 до 38. Есть 36 номеров, а 0, и 00.

Одна из больших вещей однако считают, что в американской рулетке их много разных ставок, которые можно сделать. Одна ставка может охватывать 1, 2, 3, 4, 5, 6, две разные 12 или 18. Возможно, вы захотите создать список списков, в которых каждый номер имеет дополнительные флаги, чтобы упростить это, или сделать все это в программировании ,

Если бы я реализовал его в Python, я бы просто создал набор из 0, 00 и от 1 до 36 и использовал random.choice() для каждого вращения.

44

Другие ответы, похоже, предполагают, что вы пытаетесь реализовать игру в рулетку. Я думаю, что вы спрашиваете о выборе колеса рулетки в эволюционных алгоритмах.

Here is some Java code, который осуществляет выбор колес рулетки.

Предположим, у вас есть 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.

+1

Это самый быстрый из тех, с которыми я столкнулся. Очень хорошо. – 2014-04-19 02:14:23

+0

Никто не говорит о замене выбранного элемента, чтобы выбранный элемент больше не выбирался. Любое решение для этого? – 2016-03-24 17:20:17

+1

@AnikIslamAbhi, насколько мне известно, выбор колесика рулетки предполагает, что каждый предмет может быть выбран более одного раза. Если вы рандомизировали `N` раз (где` N` - подсчет населения), вы после этой выборки возьмете ровно одну и ту же популяцию. – 2017-05-11 12:43:55

4

Во-первых, сформировать массив проценты вы назначены, скажем p[1..n] и предположим, что общая сумма сумма всех процентов.

Тогда получить случайное число от 1 до общего, скажем r

Теперь алгоритм в Lua:

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

Это предполагает некоторый класс «Классификатор», который только есть условие String, String сообщение и двойную силу. Просто следуйте логике.

- Пол

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; 
} 
9

Вот немного питона код:

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 
1

Вы можете использовать структуру данных, как это:

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

где А представляет собой целое число который представляет карман колеса рулетки, а 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; 
} 
2

Я хотел, чтобы такой же и созданный этот самостоятельный класс рулетки. Вы даете ему ряд весов (в виде двойного массива), и он просто возвращает индекс из этого массива в соответствии с взвешенным случайным выбором.

Я создал класс, потому что вы можете получить большую скорость, только делая кумулятивные добавления один раз через конструктор.Это код 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-е место = 1,0 взвешивание, 2-е место = 0,5, 3-е место = 0,333, 4-е место = 0,25 взвешивания и т. Д.

3

Вот очень быстрый способ сделать это, используя выбор потока на Java. Он выбирает индексы массива, используя значения в виде весов. Никаких кумулятивных весов не требуется из-за 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;   
} 

Это может быть дополнительно улучшено с помощью Kahan summation или чтения через двойники как итератор, если массив был слишком велик, чтобы инициализировать сразу.

-4

Я боюсь, что любой, кто использует встроенный генератор случайных чисел во всех языках программирования, должен знать, что сгенерированное число не является 100% случайным. Это следует использовать с осторожностью.

0

Я разработал код Java, аналогичный 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"; 
} 
} 

Ниже приводится образец выполнения для вектора Р проба = [0.2,0.1,0.6,0.1], WheelElements = [0,1,2,3]:

элемента, выбранных 3, Р (с) = 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 (с) = 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

Код также проверяет колесо рулетки с нулевой вероятностью.

Смежные вопросы