Генератор случайных чисел без дубликатов

29.12.17

Разработка - Универсальные функции

Хочу рассказать о своем первом опыте работы с Генератором Случайных Чисел без дублей.

Вся проблема в том, что ГенераторСлучайныхЧисел на производительных компьютерах так быстро генерит число, что получается много дубликатов даже в больших числах в конце интервала. Что я имею в виду? Например, мне необходимо было сгенерировать случайным образом 10-ти значные ИНН пусть 20 штук, сделал так:

    

Для н=1 по 20 Цикл
        Код = "";
        Для у=1 по 10 Цикл
            ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
            Число = ГСЧ.СлучайноеЧисло(0,9);
            Код = Код + Формат(Число,"ЧЦ=1; ЧН=0; ЧВН=; ЧГ=0");
        КонецЦикла;
        Сообщить(Код);
    КонецЦикла;   

 
 

Результат

5555333333
3333333333
3333333333
3333333333
3444444444
4444444444
4999999999
9999999999
9555555555
5555555555
2222222222
2222222222
6666666666
6666666666
2222222222
2222222222
3333333333
3333333333
1111111111
1111111115

Как видите, получилось много дубликатов. В публикации //infostart.ru/public/553616/ говорится о регистре сведений, в котором все хранится и происходит проверка на наличие дублей, я бы тоже использовал такой вариант при необходимости, но мне просто нужно было нагенерить ИНН, и я использовал Массив, в котором проверяю уже существующие коды

    

Массив = Новый Массив();
    Для н=1 по 20 Цикл
        Найден = Истина;
        Пока Найден Цикл
            ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
            Код = "";
            Для у=1 по 10 Цикл
                Число = ГСЧ.СлучайноеЧисло(0,9);
                Код = Код + Формат(Число,"ЧЦ=1; ЧН=0; ЧВН=; ЧГ=0");
            КонецЦикла;
            Результат = Массив.Найти(Код);
            Если Результат=Неопределено Тогда
                Найден = Ложь;
                Массив.Добавить(Код);
            КонецЕсли;    
        КонецЦикла;    
        Сообщить(Код);
    КонецЦикла;    


 

Результат

8043056388
9102338554
6249282932
1198388359
0526412897
7009103148
0571174217
8993611720
3929803898
7864312503
9471210028
0252270828
4561671060
9351136286
3376451113
7216940055
4858606383
3378262630
6057792110
0900779364

 

Может, кому-то поможет!

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2670    0    John_d    8    

54

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4606    atdonya    22    

45

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3960    ke.92@mail.ru    16    

61

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8818    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2071    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16143    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7243    quazare    8    

109
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. andrusevich 30.12.17 15:22 Сейчас в теме
Я бы по привычке (с 7.7 начинал) пошел бы списком значений, Отсюда вопрос. Массив быстрее работает чтоли?

И вашем случае я бы чуток по другому сделал

Массив = Новый Массив();

// Незачем в цикле создавать каждый раз
ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());

Для н=1 по 20 Цикл
        Найден = Истина;
       
        Пока Найден Цикл
            
            // уберем лишний цикл
            Число = ГСЧ.СлучайноеЧисло(0,9999999999);
            Код = Прав("0000000000" + Формат(Число,"ЧЦ=1; ЧН=0; ЧВН=; ЧГ=0"), 10);

            Результат = Массив.Найти(Код);

            Если Результат = Неопределено Тогда
                Найден = Ложь;
                Массив.Добавить(Код);
            КонецЕсли;    

        КонецЦикла; 
   
        Сообщить(Код);
    КонецЦикла;    
Показать
2. Alexey_ 26 30.12.17 17:54 Сейчас в теме
выкинь костыли и вынеси инициализацию ГСЧ за пределы цикла:
ГСЧ = Новый ГенераторСлучайныхЧисел();
Для н = 1 по 20 Цикл
	Код = "";
	Для у = 1 по 10 Цикл
		Число = ГСЧ.СлучайноеЧисло(0, 9);
		Код = Код + Формат(Число, "ЧЦ=1; ЧН=0; ЧВН=; ЧГ=0");
	КонецЦикла;
	Сообщить(Код);
КонецЦикла;
Показать
Alien_job; scarabey2006; eden_gmail; viptextil; DrAku1a; ltfriend; +6 Ответить
3. gavrilov_dv 31.12.17 01:30 Сейчас в теме
Лучше использовать соответствие. Он индексируется по умолчанию и работает быстрее (ощутите разницу на больших генерациях).
А в целом статья на статью не оч.тянет честно говоря.
4. ltfriend 954 31.12.17 10:01 Сейчас в теме
(3) Выше уже дали правильный ответ. Ни каких массивов, списков значений, соответствий и прочей лабуды не нужно. Нужно просто вынести инициализацию за пределы цикла.
blackijan; DrAku1a; ger_kar; +3 Ответить
5. ltfriend 954 31.12.17 10:09 Сейчас в теме
Подробнее, почему у автора так происходит.

Из синтаксис-помощника:
Последовательность случайных чисел для одного и того же начального числа будет одинакова.


У вас инициализация происходит прямо в цикле. За счёт того, что генерация происходит очень быстро, значение ТекущаяУниверсальнаяДатаВМиллисекундах() на следующей итерации такое же как и на предыдущей и получается та же самая последовательность псевдослучайных чисел.
А совет автора из разряда вредных.
Eskimos; DrAku1a; wolfsoft; +3 Ответить
6. DrAku1a 1679 03.01.18 16:51 Сейчас в теме
Автор, Вам уже указали в чём ошибка. Рекомендую воспользоваться информацией и описать это как "типичную ошибку новичка", или как-то так. Иначе - не вижу смысла плюсовать.
Если уж нужно проверять на отсутствие дублей - используйте соответствие, будет быстрее.
И ещё: если количество вариантов будет меньше, чем диапазон чисел (например, надо 20 вариантов целого числа от 0 до 9), то подобная процедура приведёт к зацикливанию.
7. eugeniezheludkov 43 15.01.18 01:56 Сейчас в теме
Поскольку в задаче ИНН, то он как минимум будет храниться где-то? не проще ли считать следующий на основе предыдущего?
8. scarabey2006 28 24.08.18 10:23 Сейчас в теме
2 работает норм, но нет проверки на дубли
9. Неопределено 90 24.08.18 10:31 Сейчас в теме
(8) Если включить его в цикле, со временем он перестанет выдавать случайные числа и зациклится на одинаковых.
10. Неопределено 90 27.08.18 05:48 Сейчас в теме
(8) Чтобы не быть голословным, я провёл визуальный эксперимент:
У нас есть внешняя обработка, на форме которой находится табличный документ. При открытии формы делаем ячейки квадратными с помощью
Экран.Область("R1C1:R80C80").ШиринаКолонки = 2;

и подключаем обработчик ожидания, который выдаёт координаты случайной ячейки табличного документа, а затем окрашивает её в случайный цвет. Я сделал это вот так:
&НаКлиенте
Процедура СлучайныеКоординаты()

	Х = 0;
	У = 0;
	Пока Х = 0 Цикл
		Х = СлЧисло(2)%40;
	КонецЦикла; 
	
	Пока У = 0 Цикл
		У = СлЧисло(2)%40;
	КонецЦикла;
	
	К = СлЧисло(3)%256;
	С = СлЧисло(3)%256;
	З = СлЧисло(3)%256;
	
	Экран.Область(Х, У).ЦветФона = Новый Цвет(К, С, З);
	
	ПодключитьОбработчикОжидания("СлучайныеКоординаты", 0.1, Истина);

КонецПроцедуры
 
&НаКлиенте
Функция СлЧисло(Макс)

	Для н = 1 по 20 Цикл
	    Код = "";
	    Для у = 1 по Макс Цикл
	        Число = ГСЧ.СлучайноеЧисло(0, 9);
	        Код = Код + Формат(Число, "ЧЦ=1; ЧН=0; ЧВН=; ЧГ=0");
	    КонецЦикла;
	    Возврат Число(Код);
	КонецЦикла;

КонецФункции
Показать

Я попробовал два варианта: в одном из них ГСЧ создаётся при открытии формы, а в другом в начале процедуры СлучайныеКоординаты(). Что должно получиться с табличным документом через несколько минут?

Нечто подобное. Такой результат получается если использовать стандартный ГСЧ, или тот что представлен в комментарии (2). Это получается вне зависимости от того, создаём мы генератор при открытии формы, или же каждый раз создаём его при необходимости сгенерировать случайное число. Он привязан к текущей универсальной дате, поэтому я не беспокоюсь об уникальности, ведь он вызывается не чаще 10 раз в секунду. Самое интересное происходит со временем. Вот результат стандартного ГСЧ, который создавался каждый раз при необходимости сгенерировать случайно число, он сдался быстрее всех:

Это тоже стандартный, но генератор был создан единожды при открытии формы. Он продержался дольше

Ниже представлен результат работы ГСЧ из второго комментария, который создавался каждый раз при необходимости получить случайное число. ПРодержался значительно дольше двух предыдущих

И наконец, ГСЧ из второго комментария, который был создан при открытии формы. Продержался дольше всех


Но на этом не заканчиваются фокусы. Когда ломается генератор, ломается интерфейс. Не только платформы, но и винды (во всяком случае семёрки):

1. Слетают шрифты в панели с подсистемами. Картинки в ней исчезают.
2. В открытой обработке появились кнопки из открытого документа, причём кривые.
3. В то время как открыта обработка, активна вкладка документа, но работать мы можем с обработкой.
4. Ломается кнопка "Пуск".

Интересно, почему всё серое? Диапазон цветов состоит из трёх значений, каждое из которых может быть равно числу от 0 до 255, т.е. всего 256 значений. Серый цвет -- это самый усреднённый цвет. Его значение равно 128, 128, 128 (3 раза 256/2). Единственное чего я не понимаю так это почему он стабильно выдаёт среднее значение от 0 до 255, но закрашивает клетки не по диагонали, или не в одном месте.
Оставьте свое сообщение