Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Можно ли усовершенствовать функцию Random? 
V
    Опции темы
valerchi
Дата 4.10.2011, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Добрый всем день. У меня появилась проблемма с гсч в делфи. Дело в том, что когда гсч генерирует мало цифр, всё вроде бы нормально, но когда нужно очень много цифр, то начинаются повторения. Я хочу спросить, можно ли как то усовершенствовать гсч, или может есть какая-то функция в делфи, которая работает без повторений?
PM MAIL   Вверх
AndreyIQ
Дата 4.10.2011, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 5.2.2007

Репутация: 1
Всего: 8



Randomize перед Random вызываете?
PM MAIL   Вверх
valerchi
Дата 4.10.2011, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Цитата(AndreyIQ @ 4.10.2011,  11:28)
Randomize перед Random вызываете?

Да, вызываю.
PM MAIL   Вверх
Snowy
Дата 4.10.2011, 11:57 (ссылка) |  (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 31
Всего: 484



Ну, понятие случайности не исключает повторений.
Что выдаёт стандартный Random - зависит от процессора.
Если родной рэндом не нравится, то можно использовать другой алгоритм.
Вот коллекция генераторов случайных чисел.
PM MAIL   Вверх
valerchi
Дата 4.10.2011, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Цитата(Snowy @ 4.10.2011,  11:57)
Ну, понятие случайности не исключает повторений.
Что выдаёт стандартный Random - зависит от процессора.
Если родной рэндом не нравится, то можно использовать другой алгоритм.
Вот коллекция генераторов случайных чисел.

Спасибо, сейчас попробую...  А использовал ли их кто- нибудь в работе? Они лучше, чем стандартный гсч? ..... Просто не хочется повторять одно и тоже.
PM MAIL   Вверх
valerchi
Дата 4.10.2011, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Скачал , начал разбираться и ничего не могу понять... Я так понял, что функции написаны в текстовом файле, но вставить хотя бы одну из них в делфи не получается, - выдаёт ошибки. Объясните, что нужно делать, пожалуйста.
PM MAIL   Вверх
Snowy
Дата 4.10.2011, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 31
Всего: 484



В текстовом файле функции на фортране.
Для паскаля в pas файлах - просто подключи нужный файл к проекту и пользуйся.
Пример:
Код
uses MRNG;

procedure TForm3.Button1Click(Sender: TObject);
var
  i: integer;
begin
  MRandSeed(GetTickCount); // Randomize
  for i := 0 to 999 do
    Memo1.Lines.Add(IntToStr(MRandInt(0, 1000000000))); // случайное число от 0 до 1000000000
end;

PM MAIL   Вверх
valerchi
Дата 4.10.2011, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Цитата(Snowy @ 4.10.2011,  15:43)
В текстовом файле функции на фортране.
Для паскаля в pas файлах - просто подключи нужный файл к проекту и пользуйся.
Пример:
Код
uses MRNG;

procedure TForm3.Button1Click(Sender: TObject);
var
  i: integer;
begin
  MRandSeed(GetTickCount); // Randomize
  for i := 0 to 999 do
    Memo1.Lines.Add(IntToStr(MRandInt(0, 1000000000))); // случайное число от 0 до 1000000000
end;

Спасибо, понял, файл подключил, начал пользоваться. Очень интересно, какой будет результат.
PM MAIL   Вверх
valerchi
Дата 6.10.2011, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Всё нормально, получилорсь. Использовал функцию "MRandSeed(GetTickCount)" как  "Randomize", а функцию "MRandInt(0, 50)" как  случайное число от 0 до 50. Гонял программу полтора суток. За это время ни одного повторения... Скорость генерации чисел, правда, уменьшилась где- то процентов на 30, зато качество увеличилось на 100%. Большое спасибо, ещё раз.
PM MAIL   Вверх
Ne1tr1n0
Дата 6.10.2011, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 1.3.2009

Репутация: нет
Всего: 8



А я ещё когда-то когда карты писал в школе, сохранял сгенеренные числа в массиве, и при каждой новой генерации пробегался по нему и если был повтор заново генерил число. Затем снова пробегался по массиву и т.д.
PM MAIL   Вверх
Gwire
Дата 6.10.2011, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 216
Регистрация: 7.8.2007
Где: Николаев

Репутация: 1
Всего: 4



1)
Цитата(Snowy @  4.10.2011,  11:57 Найти цитируемый пост)
Что выдаёт стандартный Random - зависит от процессора.

Следующее значение зависит не от процессора, а от алгоритма генерации псевдо-случайних чисел. Именно псевдо-случайних 
А также если в пременную RandSeed перед вызовом Random вставлать одно итоже число то результат Random-а будет одно итоже число.
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
    AllocConsole;
end;

procedure TForm1.sButton1Click(Sender: TObject);
begin
    RandSeed:= 1234;
    Writeln(     DWord(   Random( High(DWord) )   )     );  // High(DWord) = 4294967295
    // Результат 3104595994 
    // DWord(число) преобразует число в тип DWord. (для тех кто не знал)
end;

Прислеживается зависимость.

2) Random с параметром имеет тип Integer. 
Параметр может быть DWord (тобишь больше 2147483647). Random будет возвращать числа со знаком переполнения ("-")
Используя преобразование DWord(число) получаем диапазон от 0 до 4294967295 (32 бита). 

3) Если 32 бита мало можно использовать Int64.
Код

function Random64: Int64;
var R: Int64Rec absolute Result; 
begin
    R.Lo := Random(High(DWord));
    R.Hi := Random(High(DWord));
end;

Покривает диаразон от -9223372036854775808 до 9223372036854775807

4) Если и 64 бита мало то используй 128 бит. Функция CreateGUID, но это уже структура (record) увы. Тут прийдется попарится над преобразованием =\
Рекомендую остановится на 64.


Это сообщение отредактировал(а) Gwire - 6.10.2011, 16:31
PM MAIL   Вверх
valerchi
Дата 6.10.2011, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Цитата(Gwire @  6.10.2011,  16:28 Найти цитируемый пост)
Покривает диаразон от -9223372036854775808 до 9223372036854775807
 Ничего себе! Спасибо за информацию.

PM MAIL   Вверх
valerchi
Дата 6.10.2011, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Цитата(Gwire @  6.10.2011,  16:28 Найти цитируемый пост)
Если 32 бита мало можно использовать Int64.
Код

function Random64: Int64;
var R: Int64Rec absolute Result; 
begin
    R.Lo := Random(High(DWord));
    R.Hi := Random(High(DWord));
end;


А как, конкретно Это сделать не подскажешь?



Это сообщение отредактировал(а) valerchi - 6.10.2011, 20:30
PM MAIL   Вверх
Gwire
Дата 7.10.2011, 06:18 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 216
Регистрация: 7.8.2007
Где: Николаев

Репутация: 1
Всего: 4



Цитата(valerchi @  6.10.2011,  20:29 Найти цитируемый пост)
А как, конкретно Это сделать не подскажешь?

Функция  Random64, приведенная выше в этой теме, возвращает значение Int64.
Для её использования...
Код

var R: Int64;
begin
    R:= Random64;


Если нужно из указанного диапазона:
Код

function Random64(Min, Max: Int64): Int64;
var R: Int64Rec absolute Result;
    M: Int64;
    Mr: Int64Rec absolute M; // Если есть желание смотрите help Delphi для absolute
begin
    M:= Max - Min;
    R.Lo := Random( Mr.Lo );
    R.Hi := Random( Mr.Hi );
    Result:= Result + Min;
end;

Код

begin
    R:= Random64(1000, 10000);
    // или
    R:= Random64(0, High(Int64)); // 0..9223372036854775807
    // или
    R:= Random64(Low(Int64), 0); // -9223372036854775808..0


PM MAIL   Вверх
valerchi
Дата 7.10.2011, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Gwire,  Благодарю.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0732 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.