Имя: Пароль:
1C
 
Как написать генератор случайных чисел на 1С?
0 Груздь
 
02.09.05
12:57
Если получить последовательность случайных чисел в диапазоне от n до m любым из известных генераторов, то среднее арифметическое чисел этой последовательности будет стремиться к (m-n+1)/2, при количестве членов последовательности стремящемся к бесконечности.
Нужно написать генератор, для которого это среднее арифметическое можно было бы задавать.
Вывихнул мозги, а алгоритм придумать не могу.
Помогите, пожалуйста ...
1 ДенисЧ
 
02.09.05
12:58
Открывается учебник матстатистики, читается про матожидание...
2 Asmody
 
02.09.05
12:58
поиск по "генератор случайных чисел" зело много ссылок дает...
3 SnarkHunter
 
02.09.05
12:58
А при чем тут 1С...
4 Танюха
 
02.09.05
12:59
5 ДенисЧ
 
02.09.05
12:59
потом понимается что всё равно получатся ПСЕВДОслучайные числа...
6 снипер
 
02.09.05
13:01
тот что от avb нормально генерит
7 wuxep
 
02.09.05
13:03
(5) отсчет начинать беря что-нибудь типа времени. Перескакивать с интервалами в зависимости от времени. Почти случайные получатся :)
8 Лис в курятнике
 
02.09.05
13:03
Sc = CreateObject("MSScriptControl.ScriptControl");
Sc.language = "VBscript";
sc.executeStatement("randomize");
СлучайноеЧисло=Sc.eval("rnd");
9 povar
 
02.09.05
13:04
(0) Купи аппаратный генератор
10 снипер
 
02.09.05
13:08
у avd алгоритм тот же... но числа получаються шустрее
11 снипер
 
02.09.05
13:08
+10 это для Лиса
12 vvv29
 
02.09.05
13:15
ТОлько зачем в 1с генератор случайных чисел?, чтобы сумму случайно в отчеты писать? или зачем?
13 Груздь
 
02.09.05
13:15
Для настоящих одинэсников поясню на пиримере:
Предположим n=1, m=3 и чисел нужно 10 штук ...
Генерим последовательность: 2,1,2,3,1,1,3,2,3,1
Складываем все её члены и делим на их количество (получаем среднее арифметическое) ... = 1,9 ~ 2
Понятно, что, чем длиннее последовательность, тем ближе это среднее будет к двойке.
А мне нужен алгоритм, который генерил бы последовательности такие, чтоб это среднее было бы задаваемым пользователем.
Ну, предположим, для примера выше, я бы задал это среднее равным 2.8 ...
Разумеется, троек в ней должно быть больше, чем двоек ..., а единичек ещё меньше ...
...
Понятно теперь?
14 Конечно
 
02.09.05
13:18
(13)Так бы сразу и сказал
Только ответь -зачем в 1с генератор случайных чисел?,
15 Волшебник
 
модератор
02.09.05
13:20
16 снипер
 
02.09.05
13:20
это уже не генератор случайных чисел...
17 dk
 
02.09.05
13:32
Делал нечто подобное :) но на Дельфи
--------
Идея:
1) Выбираешь функцию распределения в пределах ограничений 1С :(
2) Делишь на участки (скажем штук на 100). Можно в зависимости от нужного кол-ва случ. чисел
3) Для каждого участка считаешь интеграл (ИнтУчастка), подразумевая, что интеграл функции распределения на нужном участке равен 100% (ИнтОбщ) и высчитываешь % этого интеграла от 100 %
Проц = ИнтУчастка / ИнтОбщ
4) Получаешь количество чисел на данном участке как
КоличествоНаУчастке = ОбщееКоличество * Проц
5) Получаешь случайные числа в количестве КоличествоНаУчастке в интервале участка (функцией равномерного распределения (см. 4))
Так по всем участкам
-------
Нужно учитывать, что если на участок приходится меньше одного случайного числа, то нужно складывать соседние участки, пока не получишь значение больше одного
---------------
Хм, получилось сумбурно, но надеюсь суть ясна
--------------------
Основные проблемы (в рамках 1С):
- Вычисление интеграла (функцию распределения нужно брать попроще)
- Вычисление случ. чисел по равномерному з-ну распределения
18 pupkin
 
02.09.05
13:36
Взять текущее время и расколбасить его как нить. Каки там интугралы.
19 dk
 
02.09.05
13:37
(pupkin) Внимательно читаем (13)
20 Груздь
 
02.09.05
13:38
(17) Спасибо ...
Но я примерно так же и начал делать, только слишком уж громоздко и заумно плучается, неговоря уже о тормозах ...
Наверняка есть более красивые решения ...
21 dk
 
02.09.05
13:40
17+
Потом нужно полученные числа перемешать :)
22 Груздь
 
02.09.05
13:44
(21) А если последовательность постоянно дополняться должна, с соблюдением всех условий её формирования, то алгоритм получается сложней втрое ...
23 raykom
 
02.09.05
14:04
(0)Пешу: генератор случайных чисел :)
24 Груздь
 
02.09.05
14:10
(23) Сергей Дроботенко?
25 raykom
 
02.09.05
14:11
Не отвлекайтесь. Я тока обстановку разрядит. Уже меня нет.
26 Zoltan
 
02.09.05
15:19
Пользуюсь такой.
Функция СлучайноеЧисло (Диапаз1,Диапаз2) Экспорт
   b=101;
   k=2;                                              
   mod=16384;//Степень двушки
   x1=0;                          
   //Диапазон=200; // От 0 до ...
   // Случайнее не бывает
   Если ПустоеЗначение(ВосстановитьЗначение("СлЧ"))=1 тогда
       ТекущееВремя(,,x1);
   Иначе;
       ВосстановитьЗначение("СлЧ",x1);
   КонецЕсли;
   x0=(b*x1+K);
   num=x0-Цел(x0/MOD)*mod;
   x1=num;                  
   y=x1/mod;  
   Результат=Цел(y*(Диапаз2-Диапаз1+1)+Диапаз1);  
   СохранитьЗначение("СлЧ",x1);
   Возврат Результат;
КонецФункции
27 Груздь
 
02.09.05
15:46
(26) Прикольно ...
Уже в начальных классах на уроках информатики детей приучают к платформе 1С ...
28 Груздь
 
02.09.05
18:58
ап
Может какой-нить NS придёт сюда завтра ...
29 NS
 
02.09.05
19:11
у AVB нормальный генератор, но он со временем начинает тормозить (число начинает увеличиваться)
Вообще проще всего где-нибудь скачать таблицу случайных чисел.
Тебе нужно задать среднее, и чтоб он на него выходил?
Диапазан при этом задается?
Сейчас соображу.
30 Груздь
 
02.09.05
19:16
(29) Да, диапазон задаётся жёстко ..., а количество чисел в последовательности может увеличиваться в любой момент ...
31 NS
 
02.09.05
19:25
(0) Стремится к (n+m)/2 ;-))
Устроит генератор в котором вероятность всех чисел одинакова, кроме одного из крайних - m, либо n ?
32 Груздь
 
02.09.05
19:28
(31) Так я и сам смогу ... Но, увы, не пойдет ...
33 NS
 
02.09.05
19:29
(32) А как пойдет?
34 NS
 
02.09.05
19:29
Более равномерно?
35 Груздь
 
02.09.05
19:34
(34) В принципе я уже сделал, кое-как ...
Втупую разбил весь диапазон на сотню маленьких, оценил вероятности выпадения чисел в каждом, генерю для каждого диапазона количество чисел кратное этой вероятности, затем из полученой кучи случайно выбираю одно ...
Изврат, но на большее меня не хватило ...
36 NS
 
02.09.05
20:02
(35) Я на выходных подумаю.
Сейчас не могу - нервы шалят. С женой в очередной раз из-за её б..дства посрался.
Вообще можно сделать линейную зависимость вероятности от числа(вероятность выпадения к:а+в(к-n)), где а и в - коэффициенты.
Числа целые?
37 Груздь
 
02.09.05
20:07
(36) Бабы - зло! ... Числа целые ...
Я тоже в выходные ещё подумаю ..., интересно ..., хоть какая-то зарядка для ума ...
38 Guk
 
02.09.05
20:12
(36) С годами это должно пройти. Жди...
39 NS
 
02.09.05
20:21
(38) К пятидесяти? ;-))
40 Guk
 
02.09.05
20:28
(39) Всегда надо искать консенсус...
41 NS
 
03.09.05
16:00
(0) Подумал... Сдуру вывел форумулу для линейной зависимости вероятности выпадения числа от самого числа. И понял, что это не надо.
Понятно, что смысл в том, чтобы скрыть, что вероятность неодинакова.
1 вариант - сделать максимум отклонения вероятности выпадения числа от равномерного (1/(m-n+1)) минимальным.
2 вариант сделать разность максимальной и минимальной вероятности минимальной.
.......
Для этого, допустим, если необходимое среднее больше, чем (m+n)/2 -
Нужно сделать вероятность для к, меньших требуемого среднего - одинаковым, и меньшим 1/(m-n+1))
А для больших - то-же одинаковым, но большим...
Через часик накидаю программку.
42 NS
 
05.09.05
19:43
перем randseed;  
перем минЗначение,максЗначение,срЗначение,коэфф1,коэфф2,Знач1,ПервыйПредел;
Процедура randomize(а=0)  
   // сбрасывает генератор
   Если а=0 тогда    
       randSeed=_getPerformanceCounter();  
   Иначе
       randseed=а;  
   КонецЕсли;    
КонецПроцедуры
// **************
Функция random()    
   // выдает случайное число 0 <= rand < 1
   // интерпретация интерпритации AVB
   // выдает последовательности лучше, и работает быстрее.
   // (не замедляется)
   // дело в том, что у него возникают очень большие числа,
   // а 1С некокорректно с ними работает (операция %)
   randSeed=(randSeed*1103515245+12345)%2147483648;
   возврат randSeed/2147483648;
КонецФункции    
// **************  
Функция Рандом()
   перем р;
   р=random();
   Если р<ПервыйПредел Тогда
       возврат мин(минЗначение+цел(р*Коэфф1),Знач1);
   Иначе
       возврат мин(Знач1+1+цел((р-ПервыйПредел)*Коэфф2),максЗначение);
   КонецЕсли;    
КонецФункции
// **************  
Процедура Инициализация(минЗ,максЗ,срЗ)
   перем СреднийПроцент,КоличествоЭлементов,Дельта,СуммаПр;
   минЗначение=минЗ;
   максЗначение=максЗ;
   срЗначение=срЗ;
   КоличествоЭлементов=максЗ-минЗ+1;  
   СреднийПроцент=1/КоличествоЭлементов;
   Дельта=((максЗ+минЗ)/2-срЗ)*4/(КоличествоЭлементов*КоличествоЭлементов-(КоличествоЭлементов % 2));
   Знач1=цел((минЗ+максЗ)/2);
   ПервыйПредел=(Знач1-минЗначение+1)*(СреднийПроцент+Дельта)-Дельта*(КоличествоЭлементов % 2);
   Коэфф1=1/(СреднийПроцент+Дельта);
   Коэфф2=1/(СреднийПроцент-Дельта);
КонецПроцедуры
// **************
Процедура Сформировать()
   перем а,сумм,Итераций,р;
   randomize();
   инициализация(11,46,25);
   сумм=0;
   Итераций=100000;
   Для а=1 по Итераций цикл
       р=Рандом();      
       Если а<200 тогда
           сообщить(р);
       КонецЕсли;    
       сумм=сумм+р;
   конеццикла;                        
   сообщить("мин "+минЗначение+" макс "+максЗначение+" среднее "+срЗначение);
   сообщить("Среднее "+сумм/Итераций);
КонецПроцедуры
43 Лошадка в пальто
 
05.09.05
20:25
а чо NS курит? или очередные шахматы пишет?
44 NS
 
05.09.05
20:31
(43) Не понял...
Я ответил на вопрос в ноль. Написал генератор случайных чисел (целых, в заданном интервале) с средним значением, задаваемым в процедуре инициализации.
При этом минимизируется максимальное отклонение |вер(i)-верСр|
Где ВерСр=1/КоличествоЭлементов
КоличествоЭлементов=(максЗначение-минЗначение+1)
Плюс попутно подправил генератор СЧ написанный avb
45 Лошадка в пальто
 
05.09.05
20:33
(44) Сережа, мне совершенно непонятно что написано в (44)... про (42) молчу в тряпочку...
46 NS
 
05.09.05
20:34
(45) Зато (0) отлично знает, что он попросил.
И в (42) - точно верное решение.
47 Лошадка в пальто
 
05.09.05
20:35
(46) Завтра сделаю копи-пасте и проверю всё (42)...
48 Груздь
 
05.09.05
20:37
(42) Очень похоже на правду ...
Спасибо ОГРОМНОЕ!!!
49 NS
 
05.09.05
20:58
(48) Только я не написал контроли.
1) МинЗначение - целое
2) МаксЗначение - целое
3) МинЗначение<МаксЗначение
4) Вероятность может выйти за ноль (отрицательная) нет контроля на то, что срЗначение входит в допустимый диапазон.
50 Груздь
 
05.09.05
21:19
(49) Это ничего ...
Генератор будет использовать продвинутый программист и ему это не понадобится ...
51 Груздь
 
05.09.05
21:20
(49) А я в воскресенье попыжился часок ..., нифига толкового не вышло ... и я, как обычно, отложил задачку до лучших времён ... :((
52 NS
 
05.09.05
21:24
на срЗначение лучше поставить ограничение
|срЗначение - ((максЗначение+минЗначение) / 2)| <= (КоличествоЭлементов / 10);
53 NS
 
05.09.05
22:26
Плюс - из-за особенностей работы цел() в 1С -
(минЗначение+максЗначение)/2 должно быть >=0,либо должно быть целым (в случае, если меньше нуля)
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.