Author Topic: Рандом с неравномерным распределением  (Read 2087 times)

0 Members and 1 Guest are viewing this topic.

gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Всем день добрый.
Возможно простой вопрос: можно ли и как сделать рандом, но неравномерный?
Например, в интервале 1-100 чтобы чаще всего выдавало из 50-70, чуть реже в интервалах 40-50 и 70-85, еще реже 20-40 и 85-95, и совсем редко 0-20 и 95-100 ?

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Рандом с неравномерным распределением
« Reply #1 on: February 16, 2018, 09:54:36 PM »
Вот вариант
Code: (clickermann) [Select]
$r1 = RND(50,70)
$r2a = RND(40,49)
$r2b = RND(71,85)
$r3a = RND(20,39)
$r3b = RND(86,95)
$r4a = RND(0,19)
$r4b = RND(96,100)

$r = RNDFROM($r1,$r1,$r1,$r1,$r1,$r1,$r1,$r1, $r2a,$r2a,$r2a,$r2b,$r2b,$r2b, $r3a,$r3a,$r3b,$r3b, $r4a,$r4b)
LOGWRITE ($r)

Вот результаты частоты выпадания на 1000 рандомизаций
Code: [Select]
22:46:42 1: 433
22:46:42 2: 275
22:46:42 3: 183
22:46:42 4: 109
22:46:42 
22:46:46 1: 412
22:46:46 2: 285
22:46:46 3: 194
22:46:46 4: 109
22:46:46 
22:46:48 1: 363
22:46:48 2: 341
22:46:48 3: 196
22:46:48 4: 100
22:46:48 
22:46:51 1: 397
22:46:51 2: 298
22:46:51 3: 212
22:46:51 4: 93
22:46:51 
22:46:53 1: 376
22:46:53 2: 313
22:46:53 3: 201
22:46:53 4: 110
22:46:53 
22:46:56 1: 391
22:46:56 2: 301
22:46:56 3: 200
22:46:56 4: 108
22:46:56 
22:46:58 1: 387
22:46:58 2: 333
22:46:58 3: 187
22:46:58 4: 93
22:46:58 
22:47:00 1: 414
22:47:00 2: 288
22:47:00 3: 205
22:47:00 4: 93
22:47:00 
22:47:02 1: 390
22:47:02 2: 297
22:47:02 3: 207
22:47:02 4: 106
22:47:02 

gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Re: Рандом с неравномерным распределением
« Reply #2 on: February 16, 2018, 10:12:34 PM »
Вот вариант
...
Красивое решение! ))

Вот результаты частоты выпадания на 1000 рандомизаций
...
Эту часть не понял, что за "1: 433" и т.д.?
...наверное это промежуточные результаты? Но не итоговые?
« Last Edit: February 16, 2018, 10:15:01 PM by gsukhado »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Рандом с неравномерным распределением
« Reply #3 on: February 16, 2018, 11:35:37 PM »
Вот результаты частоты выпадания на 1000 рандомизаций
...
Эту часть не понял, что за "1: 433" и т.д.?
...наверное это промежуточные результаты? Но не итоговые?
просто показано насколько часто выпадают те или иные интервалы чисел. к примеру 1: 433 - это числа от 50 до 70, выпадают 433 раза из тысячи.

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

в твоем примере это будет выглядеть примерно так:
Code: (clickermann) [Select]
$rnd = RND( rnd(60-rnd(1,60),60), rnd(60,60+rnd(1,40)))
на десяти тысячах прогонов выходят такие результаты:
Code: [Select]
23:36:36 0-9   - 8
23:36:36 10-19 - 81
23:36:36 20-29 - 206
23:36:36 30-39 - 547
23:36:36 40-49 - 1168
23:36:36 50-59 - 3281
23:36:36 60-69 - 3519
23:36:36 70-79 - 925
23:36:36 80-89 - 227
23:36:36 90-100- 38



а лучше так
Code: (clickermann) [Select]
$rnd = RND(60-rnd(1,60),60+rnd(1,40))
Code: [Select]
23:47:38 0-9   - 114
23:47:38 10-19 - 343
23:47:38 20-29 - 695
23:47:38 30-39 - 963
23:47:38 40-49 - 1427
23:47:38 50-59 - 2088
23:47:38 60-69 - 2128
23:47:38 70-79 - 1283
23:47:38 80-89 - 706
23:47:38 90-100- 253




« Last Edit: February 16, 2018, 11:43:03 PM by dramster »

gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Re: Рандом с неравномерным распределением
« Reply #4 on: February 28, 2018, 09:55:52 PM »
Да, идея красивая. Но если выводить не интервалами, а точными значениями, и строить график получаемого распределения, то
(а) распределение получается достаточно "острым" (см скрин).
(б) относительно равномерным распределение получается если центр распределения равноудален от краев. А если распределение (интервал Х2-Х4 на рисунке) должно быть сильно сдвинуто к одному из краев? У меня тогда получается неравномерная капля, вместо того чтобы получить равномерное распределение :(
...хотя, по (б) можно ввести фиктивное продолжение распределения и потом обнулять выходящие за его границы результаты, так наверное и сделаю..
...а по поводу (а) надо подумать, как перевести распределение в достаточно равномерное плато в интервале Х2-Х4, вместо острого пика в середине...
« Last Edit: February 28, 2018, 10:01:05 PM by gsukhado »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
да, с этим $rnd = RND(60-rnd(1,60),60+rnd(1,40)) как то остро выходит. ну да и ладно, вот вариант, где график частоты рандомного выпадания чисел можно нарисовать самому  :D .

на рисунках: черным - график нарисованный в ручную, красные точки - рандом из скрипта. по Х - цифра, по У - количество повторений этой цифры. разрешение брал 100х100.

вот мое творчество:


и твоя кривая:


скрипт:
Code: (clickermann) [Select]
//координаты рисунка графика. по Х - цифра, по У - количество повторений этой цифры
$x1= 824
$y1= 901
$x2= 1619
$y2= 1495


GETSCREEN($x1,$y1,$x2,$y2)
FOR($x=$x1,$x<$x2,($x2-$x1)/100) //разрешение по оси Х = 100
   
   
   IF_PIXEL_IN(int($x),$y1,int($x),$y2, 0)
     
      $h = int(($y2-$_return2)/(($y2-$y1)/100))  //разрешение по оси У = 100
      FOR($n=0,$n<$h)
         arrpush($rnd_gr, $step)
      END_CYC
     
      // print(int(($y2-$_return2)/(($y2-$y1)/100)))
   else
      print("no pix")
   END_IF
   inc($step)
END_CYC

print("SIZE ",ARRSIZE($rnd_gr))




//создаем массив
FOR($a=0,$a<100)
   arrpush($rnd_arr,0)
END_CYC



FOR($a=0,$a<10000)  // 10 000  рандомных чисел для теста
   
   // наше рандомное число !!!!!!!!
   $rnd_i = rnd(0,ARRSIZE($rnd_gr)-1)
   $rnd = $rnd_gr[$rnd_i] //вот оно   
   //------------------------------
   
   //для дальнейшей проверки на количество выпадений каждой цифры (от 0 до 99)
   $rnd_arr[$rnd_gr[$rnd_i]] = $rnd_arr[$rnd_gr[$rnd_i]]+1
END_CYC



//рисуем в паинте то что нарандомило. по Х - цифра (от 0 до 99), по У - количество повторений этой цифры (кол-во можно глянуть в логе)
$x = $x1
FOR($a=0,$a<100)
   print($a," -> ", $rnd_arr[$a])
   LCLICK(int($x),$y2 - int($rnd_arr[$a]*2))
   $x = ($x2-$x1)/100 + $x
END_CYC



halt