Имя: Пароль:
IT
 
Случайное заполнение массива заданным количеством фиксированных значений
,
0 Sasha_1CK
 
03.03.19
15:44
Дано одномерный массив N элементов.
Необходимо случайно распределить   М значений = 1 и N-M значений =0
M может принимать значение от 0 до N.

Есть идеи?
Че то буксую.
1 RomanYS
 
03.03.19
16:23
N может быть большим?
2 Sasha_1CK
 
03.03.19
16:36
(1)  N -  где то 500 -2000

А какое это имеет значение?
3 Sasha_1CK
 
03.03.19
16:45
+(2) ну если перейти от математической абстракции к реальной задаче - то есть дегустация.
1000 человек в рамках промо мероприятия попробовали продукт - и оценили по принципу понравился/не понравился.
В реальной жизни попробовав колбасу - вряд ли кто будет расписываться в анкете.
Но тем не менее списать колбасу надо. А для этого надо заполнить акт списания, к которому приложить "анкету".
Соотвественно есть анкета в которой на 1000 строк надо поставить к примеру 800 случайных плюсиков и 200 минусиков.
Всем понятно что это "залепуха" и исполнителям и возможным проверяющим - но тем не менее даже "залепуха" не должна быть откровенной залепухой - то есть 200 подряд минусов в начале или в конце - не катят.
4 Sasha_1CK
 
03.03.19
16:47
+(3)
Пока примерно так получилось


    Для каждого Строка Из Объект.Товары Цикл
        Если Строка.ПроцентПоложительныхОтветов > 50 тогда
            Ответ = Ложь;
            КоличествоОтветов = Окр(Объект.КоличествоУчастников * (100 - Строка.ПроцентПоложительныхОтветов)/100, 0);
        Иначе
            Ответ = Истина;
            КоличествоОтветов = Окр(Объект.КоличествоУчастников * (Строка.ПроцентПоложительныхОтветов)/100, 0);
        КонецЕсли;    
        
        МассивУчастников = Новый массив;
        ПОка МассивУчастников.Количество() < КоличествоОтветов Цикл
            ГСЧ = Новый ГенераторСлучайныхЧисел;
            НомерУчастника = ГСЧ.СлучайноеЧисло(1, Объект.КоличествоУчастников);
            Если МассивУчастников.Найти(НомерУчастника) = Неопределено Тогда
            
                МассивУчастников.Добавить(НомерУчастника);    
            
            КонецЕсли;
        КонецЦикла;
        
        Для А = 1 По Объект.КоличествоУчастников Цикл
        
            НоваяСтрока = Объект.РезультатДегустации.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
            НоваяСтрока.НомерУчастника = А;
            Если МассивУчастников.Найти(А) = Неопределено Тогда
                НоваяСтрока.ПоложительныйОтвет = не ответ;
            Иначе
                НоваяСтрока.ПоложительныйОтвет = ответ;
            КонецЕсли;
        
        КонецЦикла;
    
    КонецЦикла;
5 Михаил Козлов
 
03.03.19
16:49
Если нужно 800 плюсов и 200 минусов, можно получить случайное целое в диапазоне (1:800+200).
Если полученное значение <=800 - ставим "+", иначе "-".
6 Sasha_1CK
 
03.03.19
17:22
(5) чего то не хватает в алгоритме - или я чего то не догоняю или у меня нет гарантии, что я получу именно 800 плюсов, а не 750 или 850
7 mszsuz
 
03.03.19
17:40
Для н = 1 по 1000 Цикл
        ЭтотОбъект.ТаблицаЗначений.Добавить().К = 1;
    КонецЦикла;    
    
    Пока ЭтотОбъект.ТаблицаЗначений.Итог("К") > 800 Цикл
        ЭтотОбъект.ТаблицаЗначений[ГСЧ.СлучайноеЧисло(0, ЭтотОбъект.Количество-1)].К = 0;
    КонецЦикла;
8 Sasha_1CK
 
03.03.19
17:45
(7) Интересно.
Спасибо.
9 RomanYS
 
03.03.19
17:49
(2) для небольших можно перенумеровать все расстановки и ГСЧ получать номер расстановки. В твоем случае - не вариант.
10 sieben
 
03.03.19
17:56
1) Записать в массив М значений = 1 и N - M значений = 0 подряд.
2) Перемешивать значения в массиве тупым обменом элементов со случайными индексами пока не надоест.
11 sieben
 
03.03.19
17:59
(7) Вместо
Пока ЭтотОбъект.ТаблицаЗначений.Итог("К") > 800
Надо
Для Индекс = 1 по (1000 - 800)

И в результате будет частный случай алгоритма (10)
12 RomanYS
 
03.03.19
18:10
(10) "пока не надоест" <> "случайно распределить"
13 sieben
 
03.03.19
18:17
(12) Ты еще забыл, что ГСЧ не аппаратный, поэтому результат будет фуфловый.
14 RomanYS
 
03.03.19
18:26
(13) Это понятно. В условиях доверия к ГСЧ неплохо бы обоснование(или хотя оценку) увидеть, когда "пока не надоест" приблизится к случайному(равновероятному) распределению.
15 Скиурус
 
03.03.19
18:35
Засовываем в таблицу M единичек и N - M ноликов, добавляем колонку со случайным числом, сортируем по этому числу

ГСЧ = Новый ГенераторСлучайныхЧисел;
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Значение");
ТЗ.Колонки.Добавить("Порядок");
Для й = 1 По M Цикл
Нстр = ТЗ.Добавить();
Нстр.Значение = 1;
Нстр.Порядок = ГСЧ.СлучайноеЧисло();
КонецЦикла;
Для й = M + 1 По N Цикл
Нстр = ТЗ.Добавить();
Нстр.Значение = 0;
Нстр.Порядок = ГСЧ.СлучайноеЧисло();
КонецЦикла;
ТЗ.Сортировать("Порядок");
Результат = ТЗ.ВыгрузитьКолонку("Значение");


Кстати, имей в виду, что инициализировать ГСЧ в цикле плохая идея. Лучше делать это один раз.
16 sieben
 
03.03.19
19:14
(14) При текущей постановке задачи это недостижимо. ТС изначально оперирует не вероятностью, а фиксированными N и M - какое уж тут нормальное распределение? А переформулировать задачу за него и что-то уточнять я не собираюсь.
17 RomanYS
 
03.03.19
19:30
(16) а что там уточнять? Желание получить каждое из C(M,N) = N!/(M!*(N-M)!) положений с равной вероятностью?
18 RomanYS
 
03.03.19
19:31
(15) хорошая идея
19 sieben
 
03.03.19
19:33
(17) Вот у ТС и спрашивай - то ли это, что он хочет. Хотя, подозреваю, ты ему сейчас мозг взорвал.