Является ли это хорошей настройкой для генератора случайных чисел на основе вероятности для C?

#c #random

#c #Случайный

Вопрос:

На мой взгляд, я чувствую, что это определенно не достигает того, что он должен делать. Мне нужен был генератор случайных чисел, основанный на вероятности, чтобы определить победителя гонки. Например, у бегуна A 40% шансов на победу.

     //function definition
void createDogs(DOGS* dogList) {
    //adding info the the dogInfo struct
    strcpy(dogList[0].dogName, "Easy Rex"); //dog 1
    dogList[0].odds = 40;
    dogList[0].payoutMultiplier = 2;
    strcpy(dogList[1].dogName, "Worried Bud"); //dog 2
    dogList[1].odds = 10;
    dogList[1].payoutMultiplier = 5;
    strcpy(dogList[2].dogName, "Money Ace"); //dog 3
    dogList[2].odds = 8;
    dogList[2].payoutMultiplier = 10;
    strcpy(dogList[3].dogName, "Lucky Lady"); //dog 4
    dogList[3].odds = 15;
    dogList[3].payoutMultiplier = 15;
    strcpy(dogList[4].dogName, "Cash Dawg"); //dog 5
    dogList[4].odds = 1;
    dogList[4].payoutMultiplier = 50;
    strcpy(dogList[5].dogName, "Unlucky Brutus"); //dog 6
    dogList[5].odds = 4;
    dogList[5].payoutMultiplier = 20;
    strcpy(dogList[6].dogName, "Gamble Champ"); //dog 7
    dogList[6].odds = 8;
    dogList[6].payoutMultiplier = 10;
    strcpy(dogList[7].dogName, "Nothing Chewy"); //dog 8
    dogList[7].odds = 10;
    dogList[7].payoutMultiplier = 5;
    strcpy(dogList[8].dogName, "Easy Roxy"); //dog 9
    dogList[8].odds = 13;
    dogList[8].payoutMultiplier = 3;
}//end createDogs
  

Итак, вот где я указываю вероятность в разделе «шансы», а затем здесь я ее реализую. Думая, что шансы — это процент, поэтому возьмите случайное число от 0 до этого «процента», а затем сравните их с другими, чтобы определить победителя.

 //function definition
void dogRace(DOGS* dogList, DATA* raceInfo, int counter) {
    int numberRolled[NO_OF_DOGS];
    int i, moneyWon;
    int biggestNumber, position = 0;
    srand(time(0));
    printf("nAnd the race is on!");
    pause(5);
    for (i = 0; i < NO_OF_DOGS; i  ) { //assigns a number to each dog based on its odds
        numberRolled[i] = (rand() % dogList[i].odds);
    }//end for
    biggestNumber = numberRolled[0];
    for (i = 0; i < NO_OF_DOGS; i  ) { //determines which dog won (>number rolled)
        if (biggestNumber < numberRolled[i]) {
                biggestNumber = numberRolled[i];
                position = i;
            }//end if
    }//end for
}
  

Технически это работает, но я чувствую, что это не совсем правильный способ сделать это — дайте мне знать, если есть лучший способ сделать это, потому что в моих учебниках нет примеров для такого типа проблем. Я также пробовал использовать Google / youtubing, и мне не повезло найти то, что я искал.

Комментарии:

1. Что такое odds ? Это шанс из скольких? Если, скажем, out of 100 , тогда вы должны свернуть число с 0 to 100 и сравнить odds его с ним.

2. «шансы» обычно не означают%. Например, шансы 40: 1 составляют 2,5%. Шанс на выигрыш.

3. Затем сначала его следует преобразовать в равномерный масштаб.

4. @EugeneSh. итак, как бы я сравнил шансы с ним, скажем, с dogList [1].odds> rolledNumber ? или что-то в этом роде?

5. @stark. Да, я знаю, но я просто назвал это коэффициентами в программе, потому что это намного короче, чем процент или вероятность выигрыша

Ответ №1:

Попробуйте использовать кумулятивные коэффициенты:

  • S = сумма шансов собак от 0 до количества собак — 1
  • R = случайное целое число от 0 до S-1
  • i = 0
  • в то время как i <количество собак и dog[i].шансы <= R: R = R — dog[i].шансы, i = i 1
 //function definition
void dogRace(DOGS* dogList, DATA* raceInfo, int counter) {
    int i, moneyWon, position;
    int sum_of_odds = 0;
    int rolled;
    for (i = 0; i < NO_OF_DOGS; i  ) {
        sum_of_odds  = dogList[i].odds;
    }
    // Note, usually you should only call srand() once in a program.
    srand(time(0));
    printf("nAnd the race is on!");
    pause(5);
    rolled = randInt(sum_of_odds);
    for (i = 0; i < NO_OF_DOGS; i  ) {
        if (dogList[i].odds > rolled)
            break;
        rolled -= dogList[i].odds;
    }//end for
    position = i;
}
  

randInt Функция, вызванная выше, приведена ниже:

 // random integer from 0 to n-1 (for n in range 1 to RAND_MAX 1u)
int randInt(unsigned int n) {
    unsigned int x = (RAND_MAX   1u) / n;
    unsigned int limit = x * n;
    int s;
    do {
        s = rand();
    } while (s >= limit);
    return s / x;
}
  

Вышеизложенное предпочтительнее использовать rand() % n , поскольку оно устраняет любое смещение в вероятном случае, которое RAND_MAX 1 не кратно n . Кроме того, некоторые реализации rand() производят не очень случайные последовательности rand() % n , поэтому лучше использовать коэффициент деления, а не остаток.

Комментарии:

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

2. Я добавил это, и я получаю странные результаты… В первых 10 играх выиграла первая собака, а затем в течение следующих 20 игр это была последняя собака в моем сет-листе, выигравшая ее. Я не знаю, просто ли это шансы , но я не знаю.

3. @CodedRoses Вы звоните srand(time(0)) каждый раз? Этот вызов, вероятно, не должен быть в этой функции. Как правило, srand() должно вызываться один раз за все время выполнения программы. (Я оставил вызов, потому что он был в вашей исходной функции.)

4. @CodedRoses Код определяет победителя из одного случайного числа с «коэффициентами», взвешивающими результат. (Более высокие «шансы» означают большую вероятность выигрыша. Обратите внимание, что это противоречит обычному определению ставок «коэффициентов», которое больше похоже на ваш множитель выплат.)