2010-10-23 4 views
1

Существует множество вопросов 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, реф сумма - вес [х] решение

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% 
+0

О. :-(К сожалению, я должен был, хотя это более тщательно. – Omnifarious

ответ

1

Как об этом:

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())]; 
+0

Спасибо, но я просто решил пойти с 1/x. С {1,2,3} он дает {50%, 33%, 16%} ... который работает на то, что я хочу. Основное внимание было сосредоточено на скорости, поэтому выделение памяти было чем-то, что я хотел избежать, насколько мог. – dcousens

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