Главная страница
    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;
...


 
antonn ©   (2008-01-06 21:20) [41]

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


 
antonn ©   (2008-01-06 21:21) [42]

кстати, дома на коре2дуо пашет даже с рандомизе в цикле :((


 
homm ©   (2008-01-06 21:28) [43]

> [41] antonn ©   (06.01.08 21:20)
> Я думал это процессорная инструкция

:)))

Это функция, изменяющая значение рандомсида в зависимости от псевдо-случайной величины — времени или количетва тиков


 
sniknik ©   (2008-01-06 22:44) [44]

> кстати, дома на коре2дуо пашет даже с рандомизе в цикле :((
перечитай ветку. на этот раз внимательно...
и почему пашет/не пашет не раз объяснялось и примеры давали (имхо, понятные такие примеры...).


 
antonn ©   (2008-01-06 23:12) [45]


> перечитай ветку. на этот раз внимательно...
> и почему пашет/не пашет не раз объяснялось и примеры давали
> (имхо, понятные такие примеры...).

это не вопрос был :) Это было нытье и оправдание, почему я не сталкивался с этим ранее %)
большое спасибо за объяснения :)

еще могу поныть, почему у Tbitmap перевернуты строки, так хотелось по голове надовать тому, кто это придумал :(


 
homm ©   (2008-01-06 23:18) [46]

> [45] antonn ©   (06.01.08 23:12)
> еще могу поныть, почему у Tbitmap перевернуты строки, так
> хотелось по голове надовать тому, кто это придумал :(

Это тоже вроде как от многово зависит



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

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

Наверх





Память: 0.58 MB
Время: 0.044 c
15-1198754643
vajo
2007-12-27 14:24
2008.02.03
Посоветуйте с Raid


2-1199304844
aha
2008-01-02 23:14
2008.02.03
зашился в вычислениях CRC , полистал кучу литературы, пообращался


15-1196091261
Космос
2007-11-26 18:34
2008.02.03
Проблема ИИ


15-1198268743
homm
2007-12-21 23:25
2008.02.03
Какая чушь :)


15-1198361045
linkomizin
2007-12-23 01:04
2008.02.03
нужно к 24.12.07..





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский