Страницы

Поиск по вопросам

воскресенье, 8 марта 2020 г.

Алгоритм ГСЧ генерирующий одинаковые числовые последовательности при одинаковом Seed [закрыт]

#javascript #алгоритм #случайные_числа


        
             
                
                    
                        
                            Закрыт. Этот вопрос необходимо уточнить или дополнить
подробностями. Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Добавьте больше подробностей
и уточните проблему, отредактировав это сообщение.
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
В языке есть генератор случайных чисел не привязанный к какому-либо параметру, а
надо сделать наоборот.

Сверх сложный не надо, но и совсем простой тоже было бы не желательно.
    


Ответы

Ответ 1



Классический линейный конгруэнтный метод может стать приемлемым решением, если нет требований к криптостойкости. С учетом специфики JavaScript, проще взять параметры генератора, используемые в стандартной функции minstd_rand из c++11: multiplier = 48271 increment = 0 modulus = 2147483647 В случае умножения multiplier (48271) на максимальное значение seed (2147483646), получается 103661183076066, что меньше максимально возможного безопасного целого числа в JavaScript 9007199254740991. var Random = function(seed) { seed = (seed || 1) % 2147483647; return { next: function() { return seed = seed * 48271 % 2147483647; }, seed: function(s) { seed = s; } }; }; var random = new Random(1); for (var i = 0; i < 1000; i = i + 1) { console.log(random.next()); } Для сверки результатов можно использовать код на c++11: #include #include int main() { std::minstd_rand g(1); for (int i = 0; i < 1000; ++i) std::cout << g() << std::endl; } Ссылка на действующий C++ код. Оба варианта дают в конце последовательности из 1000 итераций одинаковый результат: ... 390639274, 1641974594, 429183498 Как ограничить результат по диапазону, думаю, вы знаете.

Ответ 2



Mersenne Twister или любой линейный конгруэнтный используйте. Можно еще из Кнута взять или из glibc

Ответ 3



В общем решил ответить на свой вопрос, возможно кто-то прокоментирует, может я что-то не так сделал. Использую пример из вики-статьи Линейный конгруэнтный метод Единственное: я исключил отсечение разрядов (вроде) и вместо целочисленного возвращаю дробное число от 0 до 1.0. var Random = function(seed) { var A = 1103515245, C = 12345, M = 0x80000000; seed = seed || 1; return { rnd: function() { seed = (A * seed + C) % M; return seed / M; }, seed: function(s) { seed = s; } }; }; var seedInp = document.querySelector('#seed'); var out = document.querySelector('#out'); document .querySelector('#rndBtn') .addEventListener( 'click', function() { var numbers = []; var random = new Random(seedInp.value); for (var i = 0; i < 200; i++) { numbers.push(random.rnd()); } out.innerHTML = numbers.join('\n'); } ); body { font-family: sans-serif; }



Комментариев нет:

Отправить комментарий