Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.93/14: Рейтинг темы: голосов - 14, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 6
1

Генерация массива случайных чисел

30.03.2015, 16:04. Просмотров 2934. Ответов 15
Метки нет (Все метки)

Начал свое знакомство с haskell, но наступил ступор, когда понадобилось решить задачу, для которой необходимо написать функцию, которая будет генерировать массив нормально распределенных на отрезке (0;1) случайных чисел.
Да и в принципе генерация случайных чисел на haskell для меня оказалась трудной темой.
С помощью каких операторов и как можно сгенерировать нормально распределенные случайные числа?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.03.2015, 16:04
Ответы с готовыми решениями:

Генерация массива случайных чисел
помогите пожалуйста ! нужно написать функцию которая будет генирировать числа от 1 до 60 и...

Генерация массива случайных неповторяющихся чисел
Нужно сгенирировать массив случайных чисел. Предположим что массив размером 10000, а диапазон...

Генерация массива случайных чисел равномерно распределенных в заданном интервале и упорядочение массива
Помогите создать ПО (на любом языке программирования) позволяющее, генерирующее массив заданной...

Генерация значений массива с помощью датчика случайных чисел
Задание: Разработать программу для обработки массива, обеспечив выполнение следующих операций: 1...

15
Антикодер
1844 / 820 / 46
Регистрация: 15.09.2012
Сообщений: 2,959
30.03.2015, 16:49 2
Это для изучения Haskell такую задачу решаете, если не секрет?
0
3640 / 2373 / 310
Регистрация: 01.06.2013
Сообщений: 5,063
Записей в блоге: 9
30.03.2015, 16:57 3
Два вопроса?
1. Точно ли нормальное распределение нужно? Или равномерное на отрезке (0,1) ?
2. В Haskell не встроены массивы, только списки. По этому, обычно изучают списки. Но если нужно сгененрировать массив - сделаем.
А пока - список из равномерно распределённых чисел. Создаётся в два шага. Создаём генератор (инициализируем его случайным числом из системы), и генерируем список чисел.
Haskell
1
2
3
4
5
import System.Random
 
main = do
   randGen <- newStdGen
   print $ take 50 $ randomRs (0 :: Double ,1) randGen
ps: Для генерации нормального распределения лучше подключить пакет normaldistribution.
3
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 6
30.03.2015, 17:07  [ТС] 4
Да, исключительно.
Начал копать различные задачи непосредственно с модулем random, и стало интересно как получить гауссовское распределение, или. к примеру, экспоненциальное. Изначально пытался найти конкретные операторы, которые генерируют случайные величины с различным распределением, но так понял, что таковых нет. А вот как реализовать - пришел в тупик.

Добавлено через 4 минуты
Собственно модуль random, как я понял и предусматривает почти во всех языках равномерное распределение, поэтому я столкнулся именно с вопросом о нормальном распределении.
Да, собственно, суть генерации нормального распределения будет понятна и на списках

А вот про пакет не знал, спасибо, попробую такой вариант решения
0
3640 / 2373 / 310
Регистрация: 01.06.2013
Сообщений: 5,063
Записей в блоге: 9
30.03.2015, 17:09 5
Цитата Сообщение от Olche Посмотреть сообщение
и стало интересно как получить гауссовское распределение
Гауссовское (нормальное) распределение задаётся не интервалом, а средним и дисперсией (например).
По этому, я и заподозрил равномерное распределение.
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 6
30.03.2015, 17:16  [ТС] 6
Пардон, виноват.
Нормальное распределение с параметрами 0 и 1 имелось ввиду, неправильно сформулировал, то есть стандартное нормальное распределение, где среднее = 0, а дисперсия =1.
0
649 / 259 / 16
Регистрация: 02.03.2014
Сообщений: 587
30.03.2015, 18:12 7
KolodeznyDiver, позвольте с вами не согласиться, есть не только списки! Data.Vector, Data.Set, Data.Array, Data.Map это так на вскидку, вектора, множества, массивы, отображения соответсвенно.
0
3640 / 2373 / 310
Регистрация: 01.06.2013
Сообщений: 5,063
Записей в блоге: 9
30.03.2015, 18:26 8
Araneo, Вы не внимательно читаете. Всё что Вы перечислили реализовано библиотечно, а не встроено в язык.
0
Модератор
26272 / 13680 / 2601
Регистрация: 12.02.2012
Сообщений: 22,437
30.03.2015, 19:00 9
Но проблема-то в том, что нужно по равномерно-распределенной выборке получить нормальную. Вот как это можно сделать (нашел в Сети):

Если качество ДСЧ "так себе" то по ЦПТ (центральная предельная теорема) - сумма n равномерных (6 и более) - n/2, все делить на корень из n/12 имеет распределение, близкое к нормальному.

Если ДСЧ хороший, то берем пару равномерных с.в. X и Y, от них https://www.cyberforum.ru/cgi-bin/latex.cgi? \sqrt{-ln(X/2)}*cos(2\pi*Y) и https://www.cyberforum.ru/cgi-bin/latex.cgi?\sqrt{-ln(X/2)}*sin(2\pi*Y) будут иметь стандартное нормальное распределение
0
3640 / 2373 / 310
Регистрация: 01.06.2013
Сообщений: 5,063
Записей в блоге: 9
30.03.2015, 19:39 10
Catstail, А ещё велосипед можно сделать так. Взять кусок исходника Data.Random.Normal.hs
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
boxMuller :: Floating a => a -> a -> (a,a)
boxMuller u1 u2 = (r * cos t, r * sin t) where r = sqrt (-2 * log u1)
                                               t = 2 * pi * u2
 
-- API
-- ===
-- | Takes a random number generator g, and returns a random value
-- normally distributed with mean 0 and standard deviation 1,
-- together with a new generator. This function is analogous to
-- 'Random.random'.
normal :: (RandomGen g, Random a, Floating a) => g -> (a,g)
normal g0 = (fst $ boxMuller u1 u2, g2)
  -- While The Haskell 98 report says "For fractional types, the
  -- range is normally the semi-closed interval [0,1)" we will
  -- specify the range explicitly just to be sure.
  where
     (u1,g1) = randomR (0,1) g0
     (u2,g2) = randomR (0,1) g1
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 6
30.03.2015, 22:44  [ТС] 11
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
ps: Для генерации нормального распределения лучше подключить пакет normaldistribution.
Я конечно еще чайник в haskell, но сообразить не могу как работать с модулем, гугл ничего конкретного не отвечает.
Haskell
1
import Data.Random.Normal
Понятное дело, сначала нужно сделать импорт того самого модуля, который нормальное распределение строит. А вот дальше...
Haskell
1
samples    = normals'   (mean,sigma) myRandomGen
кусок того, что удалось нагуглить
mean и sigma в этом случае меняем на нужные значения среднего и дисперсии, но myRandomGen что делает?
Помогите разобраться, пожалуйста
Как работает данный пакет?
Что-то я совсем запутался
Как же получить, предположим, строку с заданным количеством случайных нормально распределенных чисел с заданными средним и дисперсией?

Добавлено через 18 минут
И, очевидно, что помимо normal нужно импортировать и это
Haskell
1
import System.Random
а также как-то объявить класс RandomGen
но при написании
Haskell
1
import System.Random.RandomGen
он не может найти RandomGen

я думал со случайными числами все проще...
а получилось, что в трех соснах заблудился
0
3640 / 2373 / 310
Регистрация: 01.06.2013
Сообщений: 5,063
Записей в блоге: 9
30.03.2015, 23:31 12
Цитата Сообщение от Olche Посмотреть сообщение
он не может найти RandomGen
У Вас пакет не подключен. Он не входит в поставку "из каробки"
В командной строке операционной системы (хоть, linux, хоть windows) выполняете (каждая команда занимает время)
Bash
1
2
cabal update
cabal install normaldistribution
ghci/wingci после этого перезапустить. Если сразу компилируете, то ничего не надо.
1
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 6
31.03.2015, 12:11  [ТС] 13
KolodeznyDiver, при установке пакета эти команды выполнял.
С пакетом вроде как разобрался, но запустить в работу пока не получилось, написал случайную формулу
Haskell
1
2
3
4
import Data.Random.Normal
st :: Float -> Float -> Float
st p t = 0.5 * p^2 * t + p * sqrt(t) * normals'(0,1)
test = print (st 0.06 1)
Компилятору теперь типы не нравятся
Пишет: Couldn't match expected type ‘Float’ with actual type ‘g0 -> [a0]’
Probable cause: ‘normals'’ is applied to too few arguments
In the second argument of ‘(*)’, namely ‘normals' (0, 1)’
In the second argument of ‘(+)’, namely
‘p * sqrt (t) * normals' (0, 1)’
0
3640 / 2373 / 310
Регистрация: 01.06.2013
Сообщений: 5,063
Записей в блоге: 9
31.03.2015, 14:18 14
Цитата Сообщение от Olche Посмотреть сообщение
Компилятору теперь типы не нравятся
Смотрите внимательно какой тип у функции normals' - ей ещё генератор нужен как параметр.
Если хотите с каждым вызовом st получать следующее случайное число, то нужно ... получать два значения. То, что Вам надо, и значение генератора для подстановки в следующий вызов этой функции.
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Data.Random.Normal                                   
import System.Random
 
st :: RandomGen g => Float -> Float -> g -> (Float,g)
st p t g = let (a,g1)= normal' (0,1) g 
           in  (0.5 * p^2 * t + p * sqrt t * a,g1) 
 
main = do
   randGen <- newStdGen
   let (r1,randGen1) = myNorm randGen
       (r2,randGen2) = myNorm randGen1
       (r3,_) = myNorm randGen2
   print [r1,r2,r3]
 where myNorm = st 0.06 1
Внутри st я вызываю более подходящую ф-ию normal'. Она возвращает случайное число и следующее значение генератора. В строках 10-12 три раза вызываю st и получаю три случайных числа. Последний раз генератор не нужен - _. Что бы параметры вызова st записывать в одном месте, добавляем, вложенную в main, вспомогательную функцию myNorm.

Разумеется, можно сразу в st генерировать бесконечный список случайных чисел, каждое преобразовывать по заданной формуле. А от st брать нужное число элементов списка
Haskell
1
2
3
4
5
6
7
8
9
import Data.Random.Normal                                   
import System.Random
 
st :: RandomGen g => Float -> Float -> g -> [Float]
st p t g = map (\a -> 0.5 * p^2 * t + p * sqrt t * a) (normals' (0,1) g) 
 
main = do
   randGen <- newStdGen
   print $ take 3 $ st 0.06 1 randGen
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 6
31.03.2015, 19:58  [ТС] 15
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Разумеется, можно сразу в st генерировать бесконечный список случайных чисел, каждое преобразовывать по заданной формуле. А от st брать нужное число элементов списка
Could not deduce (random-1.0.1.1:System.Random.RandomGe n g)
arising from a use of ‘normals'’
from the context (RandomGen g)
bound by the type signature for
st :: RandomGen g => Float -> Float -> g -> [Float]
at 1.hs:4:7-51
Possible fix:
add (random-1.0.1.1:System.Random.RandomGe n g) to the context of
the type signature for
st :: RandomGen g => Float -> Float -> g -> [Float]
In the second argument of ‘map’, namely ‘(normals' (0, 1) g)’
In the expression:
map (\ a -> 0.5 * p ^ 2 * t + p * sqrt t * a) (normals' (0, 1) g)
In an equation for ‘st’:
st p t g
= map (\ a -> 0.5 * p ^ 2 * t + p * sqrt t * a) (normals' (0, 1) g)


Сам модуль random установлен
Не пойму в чем дело
0
3640 / 2373 / 310
Регистрация: 01.06.2013
Сообщений: 5,063
Записей в блоге: 9
01.04.2015, 00:06 16
Цитата Сообщение от Olche Посмотреть сообщение
Не пойму в чем дело
Я тоже. Чегото с зависимостями между пакетами.
Исходный текст не меняли?
У Вас проект с .cabal файлом используется, или это в интерпретаторе?
Если есть .cabal - покажите.

В командной строке выполните ghc-pkg list random
Будет скорее всего список из 2-х версий пакета, типо
random-1.0.1.1
random-1.1
Мне кажется не та версия пакета подставляется.
Если проект ещё не делали - по любому понадобится. Почитайте Создаём проект
В корне проекта я создал tst3.cabal
Кликните здесь для просмотра всего текста
Код
name:                tst3
version:             0.1.0.0
-- synopsis:            
-- description:         
-- license:             
license-file:        LICENSE
author:              KD
maintainer:          abc@mail.ru
-- copyright:           
-- category:            
build-type:          Simple
-- extra-source-files:  
cabal-version:       >=1.10

executable tst3
  main-is:             Tst3.hs
  -- other-modules:       
  -- other-extensions:    
  build-depends:       base >=4.7 && <4.8,
                       random >=1.1,
                       normaldistribution >=1.1
  hs-source-dirs:      src
  default-language:    Haskell2010
указав версии пакетов явно. Компилируется.
(Хотя у меня и в WinGHCi работало)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.04.2015, 00:06

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Генерация массива целых случайных чисел, которые не повторяются
Случайные числа. Генерация случайного целого числа в заданном диапазоне. Генерация массива целых...

Генерация массива целых случайных чисел, которые не повторяются
Нужно получить числа от 0 до 15 в рандомном порядке, делаю так: BOOL...

Генерация массива случайных чисел код выдаёт неправильный результат
Вот код : #include &lt;stdio.h&gt; #include &lt;iostream&gt; #include &lt;cstring&gt; #include &lt;cstdlib&gt;...

Задача такое нужно построить случайных величин и генерация случайных чисел(ГСЧ
Народ помогите тут надо. Задание такое нужно построить случайных величин и генерация случайных...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.