Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.07.2013, 15:31   #1
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию нелинейный рандом

rand() возвращает равномерное распределение (или так заявляется)
А как получить такую картинку распределения вероятности?

Smogg вне форума Ответить с цитированием
Старый 20.07.2013, 16:50   #2
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

То есть функция плотности должна быть определена в интервале (0;∞) ?
Например , X - равномерно распределенная величина на интервале (0;1).
Если взять какую-нибудь функцию от X: y:=f(x) , то плотность распределения Y будет
g(y) = |u'(y)| , где
u(y) - функция, обратная f(x).
Вот и подберите нужную f(x).

А если не обязательно (0;∞) , то можно проще.
Берете n равномерно распределенных чисел, упорядочиваете по возрастания, i-я по возрастанию величина будет иметь красивое горбатое распределение. Естественно, 1< i < n .

Непонятно, на каком языке вам надо.
Скачайте книгу " Вадзинский Р Н . Справочник по вероятностным распределениям ".
Посмотрите главу " Непрерывные распределения, с возможными распределениями на положительной полуоси ". Выберите распределение, которое вам лучше подходит. Там для каждого распределения есть раздел " Генерация случайных величин " . Используются r - стандартно равномерно распределенные случайные величины.
Стандартные значит Max = 0, Min = 1

Вот например:
x = a*(-Ln(r))^(1/b) ,
Параметры a,b сами выбирайте любые, но a>0 , b > 1

Последний раз редактировалось Stilet; 21.07.2013 в 11:32.
type_Oleg вне форума Ответить с цитированием
Старый 20.07.2013, 21:01   #3
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Спасибо, вот теперь понял!

Примерно, что берется "равномерно распределенная" величина, применяется формула, отчего изменяется "масштаб", т.е. при "уплотнении влево" отрезок слева будет соотнесен с большим отрезком "исходного распределения", а отрезок той же длины справа - с меньшим:

0(====)-----(====)1 :желаемое распределение
-|---------\-----\------|-
-|----------\------\----|-
0(======)------(==)1 :исходное распределение

Потом вернувшийся из функции random умножаем на MaxRange, округляем до целого и получаем желаемое.

Книжку почитаю.
Smogg вне форума Ответить с цитированием
Старый 20.07.2013, 22:20   #4
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

А зачем округляем до целого ?
Вам нужна дискретная что-ли случайная величина ?

1) Random без параметров возвращает равномерно распределенную величину (Max=0; Min = 1, то есть стандартную). Назовем ее r
варианты:
2) Вычисляем y = a*(-Ln(r))^(1/b)
Получаем случайную величину y, имеющюю распределение Вейбулла с параметрами a,b.
или
2) Берем несколько таких r, например m штук. r1,r2, ...., rm
Вычисляем y=-Ln(r1*r2*...*rm)/a
Получаем случайную величину y, имеющюю распределение Эрланга (или гамма-распределение) с параметрами a,m.
или
...

Но эти формулы ( с логарифмами ) - это не есть функции плотности распределение (Вейбулла или Эрланга или другая какая с горбом, как у вас на графике).
Между формулой плотности и формулой для преобразования не такая простая связь.

Последний раз редактировалось type_Oleg; 20.07.2013 в 22:27.
type_Oleg вне форума Ответить с цитированием
Старый 21.07.2013, 02:55   #5
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Цитата:
Сообщение от type_Oleg Посмотреть сообщение
А зачем округляем до целого ?
Вам нужна дискретная что-ли случайная величина ?
Ага, мне нужно целое от 0 до 200.000.000.
К тому ж рандомовский интегер сам по себе дискретный. И на таком большом интервале дискретность, по большей части, уходит в догматы математической строгости.
Цитата:
2) Вычисляем y = a*(-Ln(r))^(1/b)
Получаем случайную величину y, имеющюю распределение Вейбулла с параметрами a,b.
или
2) Берем несколько таких r, например m штук. r1,r2, ...., rm
Вычисляем y=-Ln(r1*r2*...*rm)/a
Получаем случайную величину y, имеющюю распределение Эрланга (или гамма-распределение) с параметрами a,m.
или
...
Между формулой плотности и формулой для преобразования не такая простая связь.
Это я еще попытаюсь понять.

А можете на пальцах объяснить, как получить распределение не такое округлое, а тупо прямое? Лишь бы в одном месте почаще, а в других пореже рандом срабатывал. C возможностью задания углов наклона, максимального получаемого значения и минимального, т.е. minRange,maxRange,maxFrequency. Нечто типа этого:
--|------------/x\----|----------------- МахFrequency
--|----------/xxxx\--|-----------
--|-------/xxxxxxxx\|-----------
--|----/xxxxxxxxxxx|\----------
--|/xxxxxxxxxxxxxx|--\--------
-/|xxxxxxxxxxxxxxx|----\------
-minRange---------maxRange--
Smogg вне форума Ответить с цитированием
Старый 21.07.2013, 03:39   #6
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

Только имейте ввиду, что должно соблюдаться условие нормировки.
Не всякая функция может быть функцией плотности для непрерывной СВ, и не всякий многоугольник может быть полигоном распределения для дискретной СВ.

Щас подумаю, напишу как.

PS Не понятно, МахFrequency по какой оси.
На АЧХ похоже.

Вот, например так.
Вложения
Тип файла: rar rA.rar (67.2 Кб, 8 просмотров)

Последний раз редактировалось Stilet; 21.07.2013 в 11:33.
type_Oleg вне форума Ответить с цитированием
Старый 21.07.2013, 21:43   #7
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Ага, значит через площадь все считается.
У меня мелькала мысль, чтобы разбить фигуру на квадратики, их пронумеровать и уже по рандому случайно выбирать номер квадратика. Тока реализация через switch() {case1: ... case 20000000:} - адова пытка)

Применил Вашу формулу, переделал рандом с ограниченного и половинчатого шорта на гигантский, с ничтожной дискретностью, дабл и...
Код:
#include <iostream>
#include <math.h>
#include <time.h>
#include <ios>

double rand_dbl (double const range_min, double const range_max)
{
	static unsigned long long const mant_mask53(9007199254740991);
	static double const i_to_d53(1.0/9007199254740992.0);
	unsigned long long const r( (unsigned long long(rand()) | (unsigned long long(rand()) << 15) | (unsigned long long(rand()) << 30) | (unsigned long long(rand()) << 45)) & mant_mask53 );
	return range_min + i_to_d53*double(r)*(range_max-range_min);
}


int generateRandom(){
	
	double x = rand_dbl(0, 1500);
	double outX;
	
	if (x<=1125)
	{
		outX = (sqrt((double)20 * x ));		
	}
	if (x>1125)
	{
		outX = (200 - (sqrt(3600 - 0.6*(4500+ x )))/0,3);
	}
	return (int)outX;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int rez[500];
	for (int i = 0; i < 500 ; i++)
	{
		rez[i] = 0;
	}
	
	srand(time(NULL));
	
	int g;
	for (int i = 0; i < 10000000 ; i++)
	{
		g = generateRandom();
		++rez[g];	
	}
	std::cout << "Result Frequency test:\n\n";

	for (int i = 0; i < 250 ; i++)
	{
		if (i<10) std::cout <<" ";
		if (i<100) std::cout <<" ";

		std::cout << i << " - " <<rez[i] <<"\n";
	}
	getchar();
	return 0;
}
Output:
0 - 327
1 - 1023
2 - 1734
3 - 2502360
4 - 3020
5 - 3611
6 - 4380
7 - 5047
8 - 5646
9 - 6284
.....
.....
.....
147 - 98509
148 - 99060
149 - 99584
150 - 0
151 - 0
152 - 0
......

"что я делаю не так?"©

больше 149 - не срабатывает. На тройку выпадает черте что.
Smogg вне форума Ответить с цитированием
Старый 21.07.2013, 22:53   #8
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

Я в C++ не понимаю. Могу на Delphi показать фрагмент. Проверял, работает
Код:
function FToX(f:Double):Double;
begin
 if f<=1125
  then Result:=Sqrt(20*f)
  else Result:=200-Sqrt(3600-0.6*(4500+f))/0.3;
end;

function UnToTrian:Double;
var F:Double;
begin
 F:=1500*Random;  // или можно F:=Random(1500) - только целые;
 Result:=FToX(F);
end;

// ......

Randomize;
Не знаю, что-то наверное с типами у вас.

Кстати, вот я подумал про
C возможностью задания углов наклона...
Наверное, не получистся. Углы зависят от масштабов по осям координат. Если сделать правильный масштаб, то есть выполнить условие нормировки, то надо сплюснуть этот треугольник в 1500 раз, чтобы его площадь была = 1. Соответственно углы изменятся.
Условие нормировки F(∞) = 1
type_Oleg вне форума Ответить с цитированием
Старый 22.07.2013, 13:49   #9
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Цитата:
Сообщение от type_Oleg Посмотреть сообщение
Не знаю, что-то наверное с типами у вас.
Вы совершенно во всем правы и все работает как надо, а виновата моя невнимательность:
outX = (200 - (sqrt(3600 - 0.6*(4500+ x )))/0,3);
там в 0,3 стоит запятая...
Цитата:
Кстати, вот я подумал про
C возможностью задания углов наклона...
Наверное, не получистся. Углы зависят от масштабов по осям координат. Если сделать правильный масштаб, то есть выполнить условие нормировки, то надо сплюснуть этот треугольник в 1500 раз, чтобы его площадь была = 1. Соответственно углы изменятся.
Условие нормировки F(∞) = 1
Но если изменять масштаб треугольника, то надо уменьшать его и по ширине и по высоте? Тогда и углы сохранятся.
Впрочем, это уже детали реализации.

Огромное спасибо за помощь!
Smogg вне форума Ответить с цитированием
Старый 22.07.2013, 18:24   #10
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

Цитата:
Сообщение от Smogg Посмотреть сообщение
...то надо уменьшать его и по ширине и по высоте? Тогда и углы сохранятся.
Увы, только высоту.
Например, берем плотность распределения роста людей.
По оси X - рост x(в м или см или футах, ...)
По оси Y - плотность вероятности f(в 1/м или 1/см или 1/ф соответственно).
Условие нормировки F(∞) = 1 то есть площадь фигуры, ограниченной графиком f(x).
Размерность площади м*1/м = см*1/см = ф*1/ф = .. = 1 , то есть безразмерная . Так как это есть вероятность P(-∞<x<∞)=1. Вероятность - безразмерная.
type_Oleg вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
РАНДОМ kilogram PHP 3 12.05.2012 14:24
Рандом Ya_Aston Помощь студентам 4 17.12.2010 22:43
Рандом mansp Общие вопросы C/C++ 1 12.12.2010 15:18
Рандом Syltan JavaScript, Ajax 0 07.05.2010 01:40
Нелинейный алгоритм (Pascal) DsDevis Помощь студентам 7 23.03.2009 11:48