2016-03-18 3 views
1

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

Объяснение:

Существует 8 слотов шарика и 100 шаров, чтобы быть случайным образом распределены между слотами. Существует 3 разных типа слотов: красный, зеленый и синий. Красный слот должен иметь не менее 6 мячей, зеленый 15 и синий не имеет значения.

Помимо необходимого количества для каждого цвета, есть возможность иметь несколько красных, зеленых или синих слотов, каждый из которых имеет ту же скорость шаров, которые будут входить в них. Красный - 4%, зеленый - 15%, а синий - это остальное, что не было выбрано.

Так случайно указывает последовательность это возможность:

Slot 1 - Blue with 17 balls 
Slot 2 - Green with 8 balls 
Slot 3 - Green with 12 balls 
Slot 4 - Red with 1 ball 
Slot 5 - Blue with 33 balls 
Slot 6 - Red with 7 balls 
Slot 7 - Blue with 12 balls 
Slot 8 - Green with 10 balls 

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

Что мне нужно - это псевдокод или код на любом языке, показывающий, как распределить все 100 шаров между разными слотами и с разными весами. Я программировал его, но каждые 3 прогона, один не может раздавать каждый мяч, он пропускает некоторые.

--edit: Эскиз кода, который я сделал в C# (это только поколение цветных слотов):

int amountOfRedSlots = 0, amountOfGreenSlots = 0, amountOfBlueSlots = 0; 
    int[] slotColors = new int[8]; //1 - red, 2 - green, 3 - blue; 
    for(int i = 0; i < 8; i++) 
    { 
     int num = Random.Range(1, 101); 
     if (num <= 4) //Spawn a redSlot 
     { 
      amountOfRedSlots++; 
      slotColors[i] = 1; 
     } 
     else if (num <= 19) //4 numbers excluded from not being a redSlot and 15 as percentage to be green 
     { 
      amountOfGreenSlots++; 
      slotColors[i] = 2; 
     } 
     else 
     { 
      amountOfBlueSlots++; 
      slotColors[i] = 3; 
     } 
    } 
    if (amountOfRedSlots < 1) 
    { 
     int rand = Random.Range(1, 9); //Choose a random slot to be red 
     if (slotColors[rand] == 2) 
     { 
      amountOfGreenSlots--; 
     } else amountOfBlueSlots--; 
     slotColors[rand] = 1; 
     amountOfRedSlots++; 
    } 
    if (amountOfGreenSlots < 1) 
    { 
     int rand; 
     do 
     { 
      rand = Random.Range(1, 9); 
     } while (slotColors[rand] == 1); //Choose a random slot to be green, but it can't be a former red slot 
     amountOfBlueSlots--; //Since there isn't a greenSlot, and we made sure it wasn't red, its certainly a former blue slot 
     slotColors[rand] = 2; 
     amountOfGreenSlots++; 
    } 

    //Now its needed to distribute the balls between the slots, giving the required minimum amount to be inside red slots and green slots 
    //Also note that there is smaller chance of a ball going inside a red/green slot (4% and 15%) 
+0

Можете ли вы показать код, который вы в настоящее время пытаетесь? Переполнение стека не является кодовым письмом. – Kupiakos

+0

Я действительно понимаю ваше утверждение, я сказал о необходимости кода, но то, что мне действительно нужно, - это просто руководство к решению, возможно, некоторые шаги. Код, который я сделал, имеет более 200 строк, очень ununoptimized. –

+0

Я не понимаю требования к красным и зеленым слотам. Должен быть один красный слот, поэтому вероятность того, что слот будет красным, должен составлять не менее 12,5%, что значительно превышает 4%. – rici

ответ

0

Что-то, как это должно работать это был быстрый код так, возможно, ошибка или два. Будьте осторожны с тем, что вы заявляете, хотя существует небольшая возможность с текущим расположением вы можете превысить количество шаров, которые будут распределены. Пример: 6 зеленых и 2 красных.

Вот код

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

enum types{RED=1,BLUE,GREEN}; 

typedef struct 
{ 
    int color; 
    unsigned int number_balls; 
}slot_t; 


#define NUM_SLOTS 8 
#define GREEN_PROBABILITY 15 
#define RED_PROBABILITY 4 

#define MINIMUM_RED 6 
#define MAX_NUMBER_BALLS 100 
int main(void) 
{ 
    slot_t slots[NUM_SLOTS]; 
    int slots_created,random_number; 
    int ball_count=0; 
    srand(time(NULL)); 
    for(slots_created=0;slots_created<NUM_SLOTS;slots_created++) 
    { 
     random_number=rand()%100+1;//random value between 1-100 
     if(random_number<=RED_PROBABILITY){ 
      slots[slots_created].color=RED; 
      slots[slots_created].number_balls=MINIMUM_RED; 
      ball_count+=MINIMUM_RED; 

     } 
     else if(random_number<=GREEN_PROBABILITY+RED_PROBABILITY) 
     { 
      slots[slots_created].color=GREEN; 
      slots[slots_created].number_balls=MINIMUM_RED; 
      ball_count+=MINIMUM_RED; 
     } 
     else if(random_number<=GREEN_PROBABILITY) 
      ;//blue case 
    } 

    while(ball_count<MAX_NUMBER_BALLS) 
    { 
     slots[rand()%NUM_SLOTS].number_balls+=1; //add one ball 
     ++ball_count; 
    } 


} 

Я захватывая значение randome между 1-100, если число находится в диапазоне 1-4 (4% шанс, что это будет красный), если это от 4 до 19 лет (обратите внимание на else if), он будет зеленым, иначе голубым. То же самое происходит с шарами при распределении, я получаю случайное значение между 0-7 (8 значений) и добавляю шар к одному.

+0

Спасибо за ответ, но обратите внимание на несколько вещей: вы не заставляете красное или зеленое количество, вы просто заявляете, что если это случится с нерестом, положите туда много шаров, а также количество шаров в красном/зеленом слот не является обязательным для 6/15, эта сумма требуется как сумма шаров в красных/зеленых слотах, а не в одном. Еще одна вещь, «оставшиеся» шары вы просто производите в слотах, вы не принимаете во внимание, что мяч также имеет скорость, чтобы попасть внутрь цветного слота. –

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