Выбор случайного наименьшего веса - PullRequest
1 голос
/ 23 октября 2010

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

Мой алгоритм на данный момент - это случайный вес с уклоном в сторону более высоких значений.

double weights[2] = {1,2};
double sum = 0;
for (int i=0;i<2;i++) {
  sum += weights[i];
}
double rand = urandom(sum); //unsigned random (returns [0,sum])
sum = 0;
for (int i=0;i<2;i++) {
 sum += weights[i];
 if (rand < sum) {
  return i;
 }
}

Как я могу преобразовать это в более низкие значения смещения? Т.е. я хочу, чтобы в 100 выборках выборка по весам [0] выбиралась в 66% случаев; и весит [1] 33% времени (т. е. обратно пропорционально тому, что они есть сейчас).


Пример руки для Omni, ref sum - weights [x] solution

Original:
1 | 1 | 1%
20 | 21 | 20%
80 | 101 | 79%

Desired:
1 | ? | 79%
20 | ? | 20%
80 | ? | 1%

Now sum - weights[i]

100(101 - 1) | 100 | 50%
81(101 - 20) | 181 | 40%
21(101 - 80) | 202 | 10%

1 Ответ

1 голос
/ 23 октября 2010

Как насчет этого:

template<typename InputIterator>
vector<int> generateWeightMap(InputIterator first, InputIterator last)
{
    int value = 0;
    vector<int> weightMap;
    while(first != last)
    {
        while((*first)-- > 0)
            weightMap.push_back(value);
        ++first;
        value++;
    }
    return weightMap;
}
...later

int weights[] = {1,19,80};
vector<int> weightMap = generateWeightMap(weights, weights + 3);

int weighted_random = weightMap[urandom(weightMap.size())];
...