Вам нужно случайное число от 0 до . Проблема тогда состоит в том, чтобы превратить это в битовую комбинацию.(64n)−1
Это известно как перечислительное кодирование, и это один из самых старых развернутых алгоритмов сжатия. Вероятно, самый простой алгоритм от Томаса Ковер. Это основано на простом наблюдении, что если у вас есть слово длиной битов, где заданные биты в порядке разрядов, то позиция этого слова в лексикографическом порядке всех слов с этим свойством является:x k … x 1nxk…x1
∑1≤i≤k(xii)
Так, например, для 7-битного слова:
i(0001011)= ( 3
i(0000111)=(23)+(12)+(01)=0
i(0001101)= ( 3i(0001011)=(33)+(12)+(01)=1
i(0001101)=(33)+(22)+(01)=2
...и так далее.
Чтобы получить битовый шаблон из порядкового номера, вы просто декодируете каждый бит по очереди. Примерно так, на C-подобном языке:
uint64_t decode(uint64_t ones, uint64_t ordinal)
{
uint64_t bits = 0;
for (uint64_t bit = 63; ones > 0; --bit)
{
uint64_t nCk = choose(bit, ones);
if (ordinal >= nCk)
{
ordinal -= nCk;
bits |= 1 << bit;
--ones;
}
}
return bits;
}
Обратите внимание, что поскольку вам нужны только биномиальные коэффициенты до 64, вы можете их предварительно вычислить.
- Cover, T., Enumerative Source Encoding . IEEE Труды по теории информации, том IT-19, № 1, январь 1973 г.