Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Общие темы > Болтовня

Болтовня Разговоры на любые темы (думайте, о чем пишите)

Ответ
 
Опции темы
Старый 11.10.2005, 21:17   #1
Diplomat
Дэвелопер
 
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений
(для 164 пользователей)
Забавная задачка:
Используя генератор Rnd, написать ф-ю, которая возвращала бы значения 1, 2 или 3 с равной вероятностью.
Код для подсчета вероятностей можно использовать вроде этого:
Dim Value(4)
For q=0 To 10000
 X=Rnd(3)
 Value(X)=Value(X)+1
Next
For q=0 To 4
 Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()
End
P.S. Я не свихнулся, попробуйте сами.
(Offline)
 
Ответить с цитированием
Старый 11.10.2005, 22:09   #2
SubZer0
Администратор
 
Аватар для SubZer0
 
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений
(для 996 пользователей)
хммм, ну вероятность ты подсчитал, а где сама функция генерации самого числа по подсчитанным результатам?...

есть кривая (не помню какого ученого) показывающая, что числа в середине промежутка выпадают чаще, чем по краям, это уже давно всем известно...
__________________
Как минимум я помог многим (с)
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 00:06   #3
Diplomat
Дэвелопер
 
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений
(для 164 пользователей)
хммм, ну вероятность ты подсчитал, а где сама функция генерации самого числа по подсчитанным результатам?...
В выводе формулы и заключалась задачка.
Формулу надо бы по идее вписать вместо "Rnd(3)"

числа в середине промежутка выпадают чаще, чем по краям, это уже давно всем известно...
Вот заче-е-ем было это говори-и-ить? Вот всю интригу испо-о-ортил! :'((


Ладно, раз номер не прошел, тогда так:
Создать, на основе Rnd() ф-ю, которая возвращала бы 1,2 или 3 с близкой вероятностью.

P.S. Сядьте и потестите варианты; не зря ведь говорю, не просто прикалываюсь: последовательности вероятностей можно получить очень интригующие.
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 00:26   #4
SubZer0
Администратор
 
Аватар для SubZer0
 
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений
(для 996 пользователей)
ну, я бы увеличил бы границы допустим в 10 раз (чем больше, тем мы больше растянем график, и сделаем его плавней), и пустил бы цикл, пока результат бы не попадал в нужные пределы... типа:

Dim Value(4)
For q=0 To 10000
 X=aRnd(1,4)
 Value(X)=Value(X)+1
Next
For q=0 To 4
 Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()
End


function arnd%(b%,e%)

b1%=-b%*10
e1%=e%*10

repeat

 r%=rnd(b1%,e1%)

until r%>=b% and r%<=e%

return r%

end function
вот, накидал в броузере... хз пойдет или нет... но алгоритм думаю ясен...

в алгоритме есть охренительный недостаток... будет очень медленно работать...

можно еще разорвать этот график и сложить его... порвать посередине и первый после среднего элемента прибавить к первому сначала и т.п... но это только графически, а как это кодом замутить - хз...
__________________
Как минимум я помог многим (с)
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 00:36   #5
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ну если использовать счетчики как в первом примере, то можно найти в них наибольщую и наименьшую вероятность и если они отличаются друг от друга больше ну скажем чем на заданную величину (например 5%) то возвращать число которое соответствует наименьшей вероятности, а если разница меньше заданной то использовать оператор Rand()

Больше ничего в голову не лезет
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 00:48   #6
SubZer0
Администратор
 
Аватар для SubZer0
 
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений
(для 996 пользователей)
ага, придумал как график рвать:

Dim Value(4)
For q=0 To 10000
X=aRnd(1,4)
Value(X)=Value(X)+1
Next
For q=0 To 4
Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()
End


function arnd%(b%,e%)

r%=rnd(b%,e%*2)

if r>e then r=r-e

return r%
end function
по скорости работы побыстрей и график гораздо ровнее чем в простом rnd

надо теперь совместить два метода и все.
__________________
Как минимум я помог многим (с)
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 00:54   #7
Diplomat
Дэвелопер
 
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений
(для 164 пользователей)
Вах, хитрые методы! У меня всё намного прозаичнее, даже стыдно становится выкладывать свою идею...
Давайте, еще подожду пару идей- и раскроюсь, если не отгадаете...
А если придумаете лучше- выдам за свою идею!/шутка/)

P.S. Задачка хоть и прикол, но ИМХО вопрос довольно важен. Многое делается с помощью псевдослучайных чисел Rnd(), и важно, чтоб они были действительно хоть и псевдо-, но случайными...
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 00:54   #8
SubZer0
Администратор
 
Аватар для SubZer0
 
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений
(для 996 пользователей)
совместив два метода получил следующий:
Dim Value(4)
For q=0 To 10000
X=aRnd(1,4)
Value(X)=Value(X)+1
Next
For q=0 To 4
Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()
End


function arnd%(b%,e%)



b1%=-b%*10
e1%=e%*20

repeat

r%=rnd(b1%,e1%)

until r%>=b% and r%<=e%

if r>e then r=r-e

return r%
end function
результат - супер! скорость работы - подбирается коэффициентами умножения... тут типа движок <Скорость> -----0----- <Ровнее график> чемто надо жертвовать..
__________________
Как минимум я помог многим (с)
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 01:04   #9
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
А вот что я придумал :
Dim Value(4)
For q=0 To 1000000
X=arnd(1,4)
Value(X)=Value(X)+1
Next
For q=0 To 4
Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()
End


Function arnd%(b%,e%)
If Rand(0,1) Then
	Return Rnd(b%,e%/2)
Else
	Return Rnd(e%/2+1,e%)
EndIf
End Function
На большом количестве испытаний показывает почти одинаковые результаты
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 08:41   #10
Jet
ПроЭктировщик
 
Регистрация: 04.09.2005
Сообщений: 139
Написано одно полезное сообщение
последние коды - в ФАК однозначно!
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 09:43   #11
alcosholik
 
Сообщений: n/a
http://community.boolean.name/index.php?ac...&st=0#entry1582
 
Ответить с цитированием
Старый 12.10.2005, 13:13   #12
Diplomat
Дэвелопер
 
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений
(для 164 пользователей)
1. Прост до глупости. Работает соответственно.
Dim Value(4)
For q=0 To 100000
 X=Rnd(3000)
 X=X/1000+1
 Value(X)=Value(X)+1
Next
For q=0 To 4
 Print q+" возвращалось приблизительно в "+ Value(q)/1000+"% случаев..."
Next
WaitKey()
2. Работает на основе исправления "глюков" округления
Dim Value(4)
For q=0 To 10000
 X=aRnd(2)+1
 Value(X)=Value(X)+1
Next
For q=0 To 4
 Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()

Function aRnd(RndValue#)
	RndCounter=Rnd(RndValue+1)
	If RndCounter=RndValue+1 Then RndCounter=0
	Return RndCounter
End Function
Вот такие пироги...
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 22:14   #13
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
По моему вообже не надо никаких новых функций, до этого мы еще вчера с SubZer0 додумались, надо просто вызывать функцию Rnd следующим образом:

Rnd(0.5,3.5)
или
Rand(1,3)
и все, а на счет вероятностей появления того или иного числа, то в блитце, по моему, нет никакой кривой и все появляющиеся цифры равновероятны.

Просто в твоем первом примере на числа 1 и 2 отводился промежуток в два раза меньше, чем на 2 (от 1 до 1.5 - для единици, от 1.5 до 2.5 - для двойки и 2.5 до 3 для тройки).
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.10.2005, 23:49   #14
SubZer0
Администратор
 
Аватар для SubZer0
 
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений
(для 996 пользователей)
кстати в задаче был маленький подвох, я только сейчас додумался...

попробуйте запустить вот такой код...

seedrnd millisecs()

Dim Value(20)
For q=0 To 10000
X=Rnd(20)
Value(X)=Value(X)+1
Next
For q=0 To 20
Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()
end
оказывается генератор целых случайных чисел освобожден от этого графика распределения вероятностей. Странно почему он дает кривые значения на малых диапазонах... (не считая крайние значения)
__________________
Как минимум я помог многим (с)
(Offline)
 
Ответить с цитированием
Старый 13.10.2005, 00:20   #15
Diplomat
Дэвелопер
 
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений
(для 164 пользователей)
)
Не считая крайних, он и не дает. Но на малом диапазоне эти крайние могут сильно портить нервы, если не юзать "хитрометоды". Зато теперь таких приемов предостаточно: и больше никто не будет ломать голову и ценное оборудование.

Кстати, если генератор случайных, работающий в заданом узком диапазоне, вызывается изредка и асинхронно (к примеру, для выбора фразы-ответа юнита или там анимации падения врага), то проще вообще юзать что то подобное:
Dim Value(4)
While q<10000
 RndCounter= RndCounter+1
 If RndCounter>3 Then RndCounter=1
 If Rnd(10)<2 Then;эта строка иммитирует асинхронные вызовы.
 q=q+1
 X=RndCounter
 Value(X)=Value(X)+1
 EndIf
Wend
For q=0 To 4
Print q+" возвращалось приблизительно в "+ Value(q)/100+"% случаев..."
Next
WaitKey()
P.S. Потому я задачку и называл "забавной" и поселил в Болтовню, что в ней мирно уживаются два маленьких подвоха.
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 01:31.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com