вопрос по генератору случайных чисел - страница 2

 
elibrarius:
Спасибо, теперь есть чем генерить случайное число.
Вот про  GetTickCount я спрвку и не посмотрел. По названию подумал, что это с тиками связано, а оказывается это время)))

Тот-же код вставил в OnInit(), советник прикрепил к графику и три раза перезапустил терминал:

2015.12.12 21:33:04.186 TestEA (Si-12.15,H1)    OnInit; TimeLocal 2015.12.12 21:33:04; GetTickCount 15244765
2015.12.12 21:33:46.025 TestEA (Si-12.15,H1)    OnInit; TimeLocal 2015.12.12 21:33:46; GetTickCount 15286593
2015.12.12 21:34:15.078 TestEA (Si-12.15,H1)    OnInit; TimeLocal 2015.12.12 21:34:15; GetTickCount 15315656
 
Karputov Vladimir:
Выше вставил результат второго запуска.
в GetTickCount разница в 1 миллисекунду.
Интересно, есть ли риск того, что многопоточная оптимизация запустится с разницей во времени меньше 1 миллисекунды. Т.е. с одинаковым GetTickCount?
 
elibrarius:
в GetTickCount разница в 1 миллисекунду.
Интересно, есть ли риск того, что многопоточная оптимизация запустится с разницей во времени меньше 1 миллисекунды. Т.е. с одинаковым GetTickCount?

Да! Запускаются потоки с разницей меньше 1 мс.
Код советника

#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

input int i1=1;
int OnInit()
  {

   int t=GetTickCount();
   
   GlobalVariableSet("i"+IntegerToString(i1),t);
   
   MathSrand(t);int pref=MathRand();
   
   int handle=FileOpen(i1+".txt",FILE_WRITE|FILE_COMMON);
   FileSeek(handle,0,SEEK_END);
   FileWriteString(handle,i1+") "+GlobalVariableGet("i"+IntegerToString(i1))+" = "+t+" rand="+pref);
   
   FileClose(handle);

   return(INIT_SUCCEEDED);
  }

 

Запустил оптимизацию с параметрами i1 от 1 до 10

Результаты для 10 потоков (записаны в файлы в общей папке MetaQuotes\Terminal\Common\Files)

1) 370755548 = 370755548 rand=19589 = 5
2) 370755626 = 370755626 rand=19843
3) 370755564 = 370755564 rand=19641 = 9
4) 370755610 = 370755610 rand=19791 = 8
5) 370755548 = 370755548 rand=19589 = 1
6) 370755595 = 370755595 rand=19742
7) 370755548 = 370755548 rand=19589
8) 370755610 = 370755610 rand=19791 = 4
9) 370755564 = 370755564 rand=19641 = 3
10) 370755642 = 370755642 rand=19896

из 10  - 6 прогонов получат совпадающие GetTickCount и соответственно результат от генератора случайных чисел. Повторы случаются и при других запусках.

Кто-то знает? Глобальные переменные между разными потоками оптимизатора видны друг другу?
Если нет, тогда все это не важно.

Автоматический трейдинг и тестирование торговых стратегий
Автоматический трейдинг и тестирование торговых стратегий
  • www.mql5.com
MQL5: язык торговых стратегий для MetaTrader 5, позволяет писать собственные торговые роботы, технические индикаторы, скрипты и библиотеки функций
Файлы:
test3.mq5  1 kb
 
elibrarius: Кто-то знает? Глобальные переменные между разными потоками оптимизатора видны друг другу? Не сможет ли один поток имея имя глоб. переменную равной глоб. переменной из другого потока перезаписать друг друга? С терминальными они не пересекаются, а вот между собой?
Если нет, тогда все это не важно.

Проверил - не видны и не могут быть перезаписаны, хотя ранды и GetTickCount совпадают:

1) prev_g_var=0; my_g_var=372627092; GetTickCount = 372627092; rand=3648

3) prev_g_var=0; my_g_var=372627092; GetTickCount = 372627092; rand=3648

В общем для моих задач этот баг / особенность (очень быстрого <1 мс, запуска потоков оптимизации) не имеет значения.

Файлы:
test3.mq5  1 kb
 
elibrarius:

... хотя ранды и GetTickCount совпадают...

Совпадают. Жутко неудобно. Поднимала эту тему ранее.
 
Oksana Berenko:
Совпадают. Жутко неудобно. Поднимала эту тему ранее.
Делал однажды давно, ещё на старой четвёрке, генерацию уникального имени. Вернее - постфикса для имени. Пришлось костыли делать - если после генерации имя существует, то в цикле while() добавлять цифру к сгенерированному имени, пока имена совпадают.
 
Artyom Trishkin:
Делал однажды давно, ещё на старой четвёрке, генерацию уникального имени. Вернее - постфикса для имени. Пришлось костыли делать - если после генерации имя существует, то в цикле while() добавлять цифру к сгенерированному имени, пока имена совпадают.
Так я также сначала решила вопрос: генерация, и если имя существует, то плюс цифра. Потом подумала и убрала генерацию. А смысл? Если имя существует, то плюс цифра.
 
Oksana Berenko:
Так я также сначала решила вопрос: генерация, и если имя существует, то плюс цифра. Потом подумала и убрала генерацию. А смысл? Если имя существует, то плюс цифра.
Дело в том, что имя всегда начинается с префикса - чтобы советник знал свои объекты, дабы правильно за собой подчистить при его (советника) удалении с графика. Далее идёт имя, которое используется алгоритмом перемещения нужных объектов на новые координаты, изменении цвета, и т.п. - его я, как программист, обязан знать однозначно, а далее идёт уже постфикс чтобы имя было уникальным, иначе некоторые объекты просто не создаются - уже существует такой, и программа его может лишь изменить, но не добавить новый.
 
elibrarius:
в GetTickCount разница в 1 миллисекунду.
Интересно, есть ли риск того, что многопоточная оптимизация запустится с разницей во времени меньше 1 миллисекунды. Т.е. с одинаковым GetTickCount?

А как винда захочет, так и запустит. Если не будет нагрузки в системе, запустит потоки процесса с минимальной задержкой. А потоков в системе несколько тысяч, все непредсказуемо. У Рихтера все хорошо расписано. Кстати, есть же GetMicrosecondCount(), там точность выше в 1000 раз.

А вообще, если надо гарантированно уникальный счетчик, надо использовать счетчик тактов процессора, но это уже dll с ассемблерной вставкой. Если надо,  кину ссылку на мой код на другом форуме, там это сделано.

 
elibrarius:

нужно "гарантированное получение неповторяющейся последовательности  MathSrand()"
В оптимизаторе получается, что все будет повторяющимся. И TimeLocal() и GetTickCount и TimeCurrent() - будут одинаковы при запусках каждого прогона (если верить справке)

Вы немного неправильно понимаете значение функции MathSrand. Начнем с того, что сама последовательность псевдослучайных чисел выдаваемая MathRand конечна и повторяется. т.е. это ни какие не бесконечные случайные числа, а просто большой ряд последовательности чисел (которые выглядят как якобы случайные). Когда ряд заканчивается, MathRand начинает выдавать числа сначала этой последовательности, и значения начинают повторятся вновь.

MathSrand просто указывает функции MathRand, с какого места последовательности псевдослучайных чисел их необходимо выдавать.

В Вашем вопросе не видно необходимости использования случайных чисел.  Почему вместо случайных чисел не использовать обычный счетчик 1, 2, 3...? - Значения никогда не повторятся.

Если так необходимо использовать именно случайное число, то могу порекомендовать посмотреть в сторону симметричного шифрования счетчика - вероятность образования коллизии равна нулю, т.е. Вы гарантировано получите уникальное, нормально-распределенное число, характеризующее прогон.  

Причина обращения: