Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.02.03;
Скачать: [xml.tar.bz2];

Вниз

random   Найти похожие ветки 

 
antonn (work)   (2008-01-06 16:51) [0]

Фигня какая то:) На некоторых процессорах random() в цикле возвращает одни и теже значения. Насколько я понял, просто не успевает пересчитать из-за малого времени выполнения (фиг знает, как это объяснить, но слиип(1) возвращает к жизни функцию, но все тормозит с ним). Подскажите быструю функцию для получения случайного числа (интервал 0..1, например, шаг 1/360 - т.е. один градус для окружности), чтобы выдавала для 4-10 элементов более-менее случайные значения.


 
{RASkov} ©   (2008-01-06 17:01) [1]

> [0] antonn (work)   (06.01.08 16:51)
> На некоторых процессорах random() в цикле возвращает одни
> и теже значения.

Вообще-то такое поведение рэндома на всех процессорах....
И Рандамайз не помогает?


 
DVM ©   (2008-01-06 17:04) [2]

Попробуй использовать в паре с, например, QueryPerfomanceCounter


 
Loginov Dmitry ©   (2008-01-06 17:30) [3]

> Вообще-то такое поведение рэндома на всех процессорах....


procedure TForm1.Button1Click(Sender: TObject);
var
 a: array[1..20] of double;
 I: integer;
begin
 for I := 1 to 20 do
   a[i] := random;

 ShowMessage(floattostr(a[1]));
end;


В результате получаются совершенно разные элементы:
(2.3283064365e-10, 0.031379939523, 0.86104846722, 0.20258096512, 0.2729212672, 0.67165441858, 0.31869127112, 0.16179546528, 0.37223835872, 0.42567376746, 0.082012159517, 0.47479406465, 0.070569330128, 0.84085443476, 0.059724234743, 0.29329657182, 0.9172847087, 0.3679064787, 0.77466489724, 0.32792553585)


 
Loginov Dmitry ©   (2008-01-06 17:32) [4]

> На некоторых процессорах random() в цикле возвращает одни
> и теже значения.


А Randomize в этом цикле случайно не крутится?


 
{RASkov} ©   (2008-01-06 17:39) [5]

> [3] Loginov Dmitry ©   (06.01.08 17:30)
> В результате получаются совершенно разные элементы:

А ты, Дим, как проверял? с каждым новым запуском программы, или "тупо" несколько раз на кнопку понажимал...
? :)
И как это у тебя двойка-то вообще получилась - первый результат....


 
homm ©   (2008-01-06 17:39) [6]

> [0] antonn (work)   (06.01.08 16:51)
> На некоторых процессорах random() в цикле возвращает одни
> и теже значения.

почему одни и тедже значение перестали быть случайнми?


 
antonn (work)   (2008-01-06 17:40) [7]


> Вообще-то такое поведение рэндома на всех процессорах...

в том то и дело, что не на всех, я только сейчас столкнулся) на интелах с НТ и многоядерных такое не видел.


> А Randomize в этом цикле случайно не крутится?

вызывается перед циклом.
в принципе если добавить в цикл ничего не меняется%)


 
Anatoly Podgoretsky ©   (2008-01-06 17:45) [8]

> antonn (work)  (06.01.2008 16:51:00)  [0]

У тебя ошибка в программе.


 
Loginov Dmitry ©   (2008-01-06 17:46) [9]

> А ты, Дим, как проверял? с каждым новым запуском программы,
> или "тупо" несколько раз на кнопку понажимал...
> ? :)
> И как это у тебя двойка-то вообще получилась - первый результат....


С каждым запуском. Смысл какой в повторных нажиманиях кнопки?


 
{RASkov} ©   (2008-01-06 18:01) [10]

> [9] Loginov Dmitry ©   (06.01.08 17:46)

Хм... странно, Хотя и не совсем понятно, твой код [3] и там же список цифр - они не согласованны как-то(код и список) в коде видно показ первого элемента, но и сам список состоит из 20 элементов.... вообщем путанница. Вот у меня:
procedure TForm1.Button1Click(Sender: TObject);
var
a: array[1..20] of double;
I: integer;
S: String;
begin
for I := 1 to 20 do
  a[i] := random;
 S:="";
for I := 1 to 20 do
 S:=S+floattostr(a[i])+#13#10;
ShowMessage(S);
end;

всегда одно и то же :(
Естественно

> Смысл какой в повторных нажиманиях кнопки?

Никакого :)


> [7] antonn (work)   (06.01.08 17:40)
> в том то и дело, что не на всех

Тоже.... странно все это) Пробуй вариант из [2]...


 
Loginov Dmitry ©   (2008-01-06 18:05) [11]

> всегда одно и то же :(


Это как? При каждом нажатии на Button1 формируется один и тотже набор чисел? =-O


 
{RASkov} ©   (2008-01-06 18:15) [12]

> [11] Loginov Dmitry ©   (06.01.08 18:05)
> Это как? При каждом нажатии на Button1 формируется один
> и тотже набор чисел? =-O

Дим, перечитай мои посты или.... вот.... вот такой код все объяснит
procedure TForm1.FormCreate(Sender: TObject);
var
a: array[1..20] of double;
I: integer;
S: String;
begin
for I := 1 to 20 do
  a[i] := random;
 S:="";
for I := 1 to 20 do
 S:=S+floattostr(a[i])+#13#10;
ShowMessage(S);
Halt;
end;

:)


 
sniknik ©   (2008-01-06 18:20) [13]

> Это как? При каждом нажатии на Button1 формируется один и тотже набор чисел? =-O

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

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


 
Loginov Dmitry ©   (2008-01-06 18:21) [14]

> Дим, перечитай мои посты или.... вот.... вот такой код все
> объяснит


Хорошо. Тогда какое отношение [1] имеет к вопросу? То, что последовательность, генерируемая Random, при каждом запуске одинаковая - это и так понятно. В вопросе же почему-то на некоторых процессорах random() в цикле возвращает одни и теже значения.
Я бы, чесно говоря удивился, если бы мне эта функция выдала что-нибудь типа
(0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ...)


 
sniknik ©   (2008-01-06 18:24) [15]

{RASkov}
задавай "рандомсиид" одинаковым числом перед циклом, будет типа вызова рандомайз но с одним значением.
и получиш одинаковые последовательности, сколько бы ни жал на кнопку.
нагляднее будет. хальт не нужен.


 
{RASkov} ©   (2008-01-06 18:27) [16]

> [14] Loginov Dmitry ©   (06.01.08 18:21)
> Тогда какое отношение [1] имеет к вопросу?

Ах.... вон что...) Тогда значит я не правильно понял [0] :( Прошу сорри )
Конечно же я "всю дорогу" имел ввиду именно [12] т.е. даже [13].... Вотъ....


 
sniknik ©   (2008-01-06 18:29) [17]

> Я бы, чесно говоря удивился, если бы мне эта функция выдала что-нибудь типа
> (0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ...)
а я бы нет
цикл
for i:= 1 to 20 do begin
 randomize;
 a[i]:= random;
end;
примерно то и сделает, тем вероятнее чем быстрей процессор (больше тактов за одно и тоже время, от которого рандомайз и инициализируется, а рандом будет считать одно и тоже значение...)

а вообще чего тут обсуждать без кода? все что без кода это глюк в 17 строке! аминь.


 
{RASkov} ©   (2008-01-06 18:30) [18]

> [15] sniknik ©   (06.01.08 18:24)

Это понятно....) Мне не совсем понятно тогда [0] т.е. описываемая там трабла....
При таком раскладе как вообще тогда работают программы на тех процессорах..... которые(цпу) там чего-то не успевают :)


 
{RASkov} ©   (2008-01-06 18:31) [19]

> [17] sniknik ©   (06.01.08 18:29)
> а вообще чего тут обсуждать без кода? все что без кода это
> глюк в 17 строке! аминь.

Во-во... это верно )


 
homm ©   (2008-01-06 18:33) [20]

> [7] antonn (work)   (06.01.08 17:40)
> вызывается перед циклом.
> в принципе если добавить в цикл ничего не меняется%)

я думаю это ключевые слова. Это значит что собственно рандомайз (или аналог) и так стоит гдето в цикле, явно или не явно.


 
Loginov Dmitry ©   (2008-01-06 18:59) [21]

> а я бы нет
> цикл
> for i:= 1 to 20 do begin
> randomize;
> a[i]:= random;
> end;
> примерно то и сделает, тем вероятнее чем быстрей процессор
> (больше тактов за одно и тоже время, от которого рандомайз
> и инициализируется, а рандом будет считать одно и тоже значение...)
>


Я бы не стал так утверждать. Randomize сперва определяет текущее значение счетчика тактов (или чего-то там) процессора. Если счетчик отсутствует, то используется GetTickCount. Однако, если счетчик установлен, то два вызова QueryPerformanceCounter() (на одном процессоре) никак не смогут дать два одинаковых значения.


 
homm ©   (2008-01-06 19:04) [22]

> [21] Loginov Dmitry ©   (06.01.08 18:59)
> Я бы не стал так утверждать.

Какая разница, как утвержать? Сначала проверь, код с рандомайзом внутри цикла дает одинаковые значения. Думаю что на семпронах на АМ2 счетчик установлен, но я все равно получаю одинаковый результат. Так что либо рандомайз его не использует счетчик, либо все же QueryPerformanceCounter дает одинаковый результат.


 
Loginov Dmitry ©   (2008-01-06 19:10) [23]

> Какая разница, как утвержать? Сначала проверь, код с рандомайзом
> внутри цикла дает одинаковые значения.


У меня все значения - разные.


> Так что либо рандомайз его не использует счетчик, либо все
> же QueryPerformanceCounter дает одинаковый результат.


При выполнении кода
if QueryPerformanceCounter(Counter) then
 RandSeed := Counter


RandSeed может теоретически принимать одинаковые результаты (с Атлоном 4600+ - примерно каждые 5 секунд) :)


 
homm ©   (2008-01-06 19:20) [24]

> [23] Loginov Dmitry ©   (06.01.08 19:10)
> У меня все значения - разные.

У меня в 2006 тоже :)
Отсюда вывод, не полагаемся на наличие счетчика и серсию дельфей, считаем что все же значения одинаковые.


 
homm ©   (2008-01-06 19:26) [25]

Кстати, действительно, получается зависимость от процессора :)


 
antonn (work)   (2008-01-06 19:34) [26]

код:
procedure TGFX_effect.SetPointGFX(x,y,ty:integer);
var Cadr:pGFX_effectE; i:integer;
begin
randomize;
for i:=FList.Count-1 downto 0 do begin
  Cadr:=pGFX_effectE(FList.Items[i]);

  cadr.timer:=0;
  cadr.angle:=(random(314)/314)*pi*2;
end;
end;

даже если убрать все классы и вывести обычной функцией - вот этот card.angle всегда одни и теже. Глупо смотрится, когда частицы разлетаются толпой в одну строну. Причем не понять, как я раньше с таким не сталкивался. До этого у меня были селероны 433/1200/2400, пни с НТ и сейчас стоит коре2дуо - нет таких заскоков (на одной и той же скомпилированной программе, ОС - ВинХП). Щас на работе дай думаю покодю - а тут такая попа. Причем сейчас тоже вроде вдухядерник (но на Вин2к - она держит многоядерность?) Е2160, пробывал на интелах 1,8-2,4 без НТ - так же в циклах одни и теже значения.
Я даже пойму, что расчет слишком быстро идет и все такое, но как можно это исправить? Sleep дает слишком ощутиму паузу.


 
antonn (work)   (2008-01-06 19:35) [27]

[26]+ Дельфи5,6,7 без сервис паков


 
homm ©   (2008-01-06 19:39) [28]

> [26] antonn (work)   (06.01.08 19:34)
> даже если убрать все классы и вывести обычной функцией -
> вот этот card.angle всегда одни и теже

еше бы. Тут же одна переменная, ты ей в цикле присваиваешь значение, прои выходе из цткла у не будет лишь одно значение ;)


 
homm ©   (2008-01-06 19:41) [29]

Не всматривался в код, ссори.
Надо весь код смотреть.
Ты уверен, что здесь
Cadr:=pGFX_effectE(FList.Items[i]);
выбираются валидные элементы? Может ты мусор собираешь из листа, а потом чудо что без AV пишеш что то куда то.


 
antonn (work)   (2008-01-06 19:45) [30]

да, разные, я там еще порядковый номер из i брал - cadr.timer:=i;

уже пол дня удивляюсь, пол кода перекомментировал :)


 
homm ©   (2008-01-06 19:48) [31]

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


 
sniknik ©   (2008-01-06 19:49) [32]

> Если счетчик отсутствует, то используется GetTickCount.
ну так, вопрос то как раз про то что "на некоторых компьютерах", предположительно с отсутствующим ...

проверяем
procedure TForm1.Button1Click(Sender: TObject);
var
 a: array[1..20] of double;
 i: integer;
begin
 for i:= 1 to 20 do begin
   //randomize; //проверка раз, счетчик или есть или нет
   RandSeed:= GetTickCount; //проверка два, эмуляция отсутствия, даже если он есть
   a[i]:= random;
 end;

 Memo1.Lines.Clear;
 for i:= 1 to 20 do
   Memo1.Lines.Add(FloatToStr(a[i]));
end;


в первом варианте у меня тоже все значения разные (атлон 3200+)
второй - повторы. о которых и говорил в [17]. а для железа которое не поддерживает этого счетчика вариант 1 будет подобен второму.

в итоге все одно ошибка в 17 строке. т.к. обсуждаемый код это то как делать нельзя. в нормальном варианте randomize вызывается 1 раз. и тогда неважно есть там чтото или нет, повторов не будет.


 
antonn (work)   (2008-01-06 19:56) [33]

хм... я возможно начинаю разгребать) рандомизе у меня вроде вызывается то один раз, она вне цикла.
Просто сама функция вызова стоит после другой, очень напряжной, и когда первая тормозит - рандом начинает выдавать одинаковые значения. Вроде так (просто чтобы проверить приходится остервенело тыкать мышкой и вызывать функцию :)). Вызов этой функции в цикле 100% приводит к одинаковым значениям. Но если убрать рандомизе и сделать его только при старте программы, то значения разные, однако часто эти получаются пучком каким то (в смысле выдает близкие значения, а не на полном диапазоне 0-314, кол-во элеметов - 14)


 
antonn (work)   (2008-01-06 19:58) [34]

короче, я в печали %(


 
homm ©   (2008-01-06 19:59) [35]

> [32] sniknik ©   (06.01.08 19:49)

Что то из сказанного до этого было не выяснено?
> [33] antonn (work)   (06.01.08 19:56)
> однако часто эти получаются пучком каким то (в смысле выдает
> близкие значения, а не на полном диапазоне 0-314, кол-во
> элеметов - 14)

Часто это как, в соответствии со случайным распределением? Не понимаю, какие проблемы, если это случаное распределение, а не равномерное.


 
sniknik ©   (2008-01-06 20:01) [36]

procedure TGFX_effect.SetPointGFX(x,y,ty:integer);
var Cadr:pGFX_effectE; i:integer;
begin
randomize;
for i:=FList.Count-1 downto 0 do begin
 Cadr:=pGFX_effectE(FList.Items[i]);

 cadr.timer:=0;
 cadr.angle:=(random(314)/314)*pi*2;
end;
end;

вопрос, сколько раз вызывается SetPointGFX? т.е. вообщето, по названию, это установка точки, а выше идет речь о разлетающихся частицах, траектория которых похоже высчитывается с помощью задаваемых точек. так?
а раз так то выше у тебя есть еще цикл, может неявный, может ты там по таймеру вызываешь, главное цикл есть и внутри цикла randomize... т.е. ситуация о которой так много говорят. присутствует. и не исправлена...


 
Zeqfreed ©   (2008-01-06 20:08) [37]

> antonn (work)   (06.01.08 19:56) [33]

Ну все верно. Получается, что если ты успеваешь за секунду нажать мышь несколько раз, то у тебя Randomize инициализирует (как выше выяснилось лишь на некоторых процессорах) генератор одинаковым значением и соответственно выдает одинаковые последовательности. Одного вызова Randomize в начале программы будет достаточно.


 
antonn (work)   (2008-01-06 20:15) [38]


> sniknik ©   (06.01.08 20:01) [36]

вызов по таймеру (ГетТикКоунт должен быть не менее 15 от предыдущего срабатывания) (сорри, что пишу функции по-русски, у меня инет через дамваре, на третьем компе, очень трудно менять язык тыкая в иконку в трее:)), таймер как бесконечный цикл со слипами(1) . Или по клику, тогда предыдущее срабатывание применяется к текущему (ну в смысле сдвигается:)). Если очень быстро тыкать (хотя я не понимаю, я что терминатор, долбить быстрее чем компутер обсчитывает (только он там еще и рисует эти частицы, самая нагруженная функция, которая идет перед вызовом этой с рандомом)) то получается фигня :(


> homm ©   (06.01.08 19:59) [35]

если быстро ее вызывать, то либо пучком, либо одинаковые :)
если вызывать только "вручную" - все рандомно.


 
antonn (work)   (2008-01-06 20:18) [39]


> Одного вызова Randomize в начале программы будет достаточно.

убил все рандомы, оставил только при создании классов (они редко, но пересоздаются, на всякий случай%)). Вроде помогло, щас еще постестирую. Обидно, что на других компах все работало всегда, и я только сейчас такое заметил...

ЗЫ домой уже пора, а я все мучаю этот комп %)


 
turbouser ©   (2008-01-06 20:29) [40]


> antonn (work)   (06.01.08 20:18) [39]
>
> убил все рандомы, оставил только при создании классов

Достаточно один раз прописать в проекте:
program Project1;
...
begin
 Randomize;
...



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.02.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.169 c
15-1198421299
общества
2007-12-23 17:48
2008.02.03
ООО, ОАО, ЗАО


10-1142832134
Alex_C
2006-03-20 08:22
2008.02.03
Создание многопоточных приложений на COM


15-1198324676
Kostafey
2007-12-22 14:57
2008.02.03
К вопросу о культурном проектировании реляционных БД


15-1198582880
Kolan
2007-12-25 14:41
2008.02.03
RxLib и EhLib для BDS2006 где взять?


11-1182271513
Vladimir Kladov
2007-06-19 20:45
2008.02.03
Секреты Delphi IDE - пополнения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский