#cpp #c #математика #случайные_числа #opencl
Необходимо написать свой генератор, т. к. нет возможности добавить библиотеку со встроенным. Можете подсказать пожалуйста ссылку или формулу, по которой можно на C, где будут случайных числа между минимумом и максимумом. Типа int и double. P. S. Пишу под OpenCL. Никаких встроенных готовых библиотек с этим нет. Есть варианты, но там сложнее немного. Был ли у кого опыт написания примитивного ГПСЧ без каких-либо встроенных функций?
Ответы
Ответ 1
Когда-то давно (до С++11) писал по второму тому Кнута для 32 и 64 бит - если поможет... class Random { public: typedef int RandomValue; Random& operator = (int seed) { X = seed; return *this; } Random(int seed = 1):X(seed){}; int operator()(int seed = 0) { const int MM = 2147483647; const int AA = 48271; const int QQ = 44488; const int RR = 3399; if (seed != 0) X = seed; X = AA*(X%QQ)-RR*(X/QQ); if (X < 0) X += MM; return X-1; } int operator()(int min, int max) { return (*this)()%(max-min) + min; } private: int X; }; class Random64 { typedef unsigned long long uint64; public: typedef uint64 RandomValue; Random64& operator = (uint64 seed) { X = seed; return *this; } Random64(uint64 seed = 0):X(seed){}; uint64 operator()(uint64 seed = uint64(-1)) { const uint64 a = 3202034522624059733ULL; const uint64 c = 1ULL; if (seed != uint64(-1)) X = seed; uint64 Y = a * X + c; X = a * Y + c; Y = (Y&0xFFFFFFFF00000000ULL) | (X >> 32); return Y; } uint64 operator()(uint64 min, uint64 max) { return (*this)()%(max-min) + min; } private: uint64 X; };Ответ 2
Кому нужно будет, вот решение : main { uint32_t stat[1]; stat[0] = 2595719; uint32_t rang = 0; int min = 10; int max = 1000; for (int i = 0; i < 10000; i++) { rang = rand(stat) % (max - min) + min; cout << "Random Number is " << rang << endl; } } uint32_t rand(uint32_t state[1]) { uint32_t x = state[0]; x ^= x << 13; x ^= x >> 17; x ^= x << 5; state[0] = x; return x; } Предложите, что подкорректировать, если есть вариантыОтвет 3
Для написания своего ГПСЧ можно использовать линейный конгруэнтный метод. Он довольно часто применяется в реализации стандартной библиотеки. Этот метод может сгенерировать статистически хорошую псевдослучайную последовательность (т. е. часта появления каждого числа будет примерно одинаковой), но этот метод не применим в криптографии, т. к. может быть легко взломан. Переносимую реализацию функции rand и srand можно найти в стандарте языка C (в качестве примера приведена реализация из стандарта C11): static unsigned long long int next = 1; int rand(void) { next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768; } void srand(unsigned int seed) { next = seed; } ISO/IEC 9899:2011 Примечания Переменная next объявлена статической, т. к. предполагается, что она и (обе функции, к тому же) находится в файле stdlib.h.Ответ 4
Почему бы вам не использовать стандартный метод для Си: srand(time(NULL)); digit = begin_num + rand() % n;Ответ 5
Могу предложить еще один простой пример: class RandInt { using Cont = std::valarray; Cont v; static int k; public: RandInt(int min, int max, size_t seed) { k = seed; int langht = max - min; v = Cont(min, langht); for (int i = 1; i < langht; ++i) v[i] = v[i -1] + 1; } int operator ()() { v = v.cshift(k); ++k; return v[v.size()/2]; } }; int RandInt::k; int main(]) { RandInt r(-25, 25, 3); for (int i = 0; i < 20; ++i) std::cout << r() << '\n'; return 0; }
Комментариев нет:
Отправить комментарий