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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 05.06.2013, 12:37   #1
Symba
Пользователь
 
Регистрация: 02.03.2011
Сообщений: 31
Сообщение rand() бьет в один из интервалов в два раза чаще

Всем привет!
ниже полностью код, под ним описание проблемы.
Код:
#include <iostream>
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

using namespace std;
int main()
{
	srand((unsigned)time(NULL));

	int x = 100;

	int t = 8760*x;

	int tvn1 = 33000,
		tvn2 = 29000,
		tvn3 = 34000,
		tvn4 = 35000,
		tvn5 = 19000,
		tvn6 = 7000,
		tvn7 = 7000,
		tvn8 = 3500;

	int tv1=29,
		tv2=22,
		tv3=24,
		tv4=25,
		tv5=37,
		tv6=60,
		tv7=47,
		tv8=135;

	double	notk1 = double(t)/double(tvn1+tv1),
			notk2 = double(t)/double(tvn2+tv2),
			notk3 = double(t)/double(tvn3+tv3),
			notk4 = double(t)/double(tvn4+tv4),
			notk5 = double(t)/double(tvn5+tv5),
			notk6 = double(t)/double(tvn6+tv6),
			notk7 = double(t)/double(tvn7+tv7),
			notk8 = double(t)/double(tvn8+tv8);

	double	votk1 = notk1/t,
			votk2 = notk2/t,
			votk3 = notk3/t,
			votk4 = notk4/t,
			votk5 = notk5/t,
			votk6 = notk6/t,
			votk7 = notk7/t,
			votk8 =	notk8/t;

	double	interval1 = votk1,
			interval2 = interval1+votk2,
			interval3 = interval2+votk3,
			interval4 = interval3+votk4,
			interval5 = interval4+votk5,
			interval6 = interval5+votk6,
			interval7 = interval6+votk7,
			interval8 = interval7+votk8,
			interval9 = 1.00000000;
	double prn;
	
	
	 do{
	 int	     i1 = 0,
				 i2 = 0,
				 i3 = 0,
				 i4 = 0,
				 i5 = 0,
				 i6 = 0,
				 i7 = 0,
				 i8 = 0,
				 i9 = 0;
	  for (int i=1;i<=t;i++){
		  prn = (double)rand() / RAND_MAX;

		  if (prn<=interval1){
			  i=i+tv1;
			  i1=i1+tv1;
		  }else if (prn<=interval2){
			  i=i+tv2;
			  i2=i2+tv2;
		  }else if (prn<=interval3){
			  i=i+tv3;
			  i3=i3+tv3;
		  }else if (prn<=interval4){
			  i=i+tv4;
			  i4=i4+tv4;
		  }else if (prn<=interval5){
			  i=i+tv5;
			  i5=i5+tv5;
		  }else if (prn<=interval6){
			  i=i+tv6;
			  i6=i6+tv6;
		  }else if (prn<=interval7){
			  i=i+tv7;
			  i7=i7+tv7;
		  }else if (prn<=interval8){
			  i=i+tv8;
			  i8=i8+tv8;
		  }else if (prn<=interval9){
			  i9++;
		  }
	  }
	  double	v1 = (double)i1/t,
				v2 = (double)i2/t,
				v3 = (double)i3/t,
				v4 = (double)i4/t,
				v5 = (double)i5/t,
				v6 = (double)i6/t,
				v7 = (double)i7/t,
				v8 = (double)i8/t,
				v9 = (double)i9/t;

				cout << "===============" << endl;
				cout << v1 << " " << (double)i1/x << endl;
				cout << v2 << " " << (double)i2/x << endl;
				cout << v3 << " " << (double)i3/x << endl;
				cout << v4 << " " << (double)i4/x << endl;
				cout << v5 << " " << (double)i5/x << endl;
				cout << v6 << " " << (double)i6/x << endl;
				cout << v7 << " " << (double)i7/x << endl;
				cout << v8 << " " << (double)i8/x << endl;
				cout << v9 << " " << (double)i9/x << endl;
				cout << "===============" << endl;
	  } while (getch()!=0x1B);
}
проблема в том, что ПСЧ попадает во второй интервал чаще в два раза, чем задумано, а в пятый реже в два раза, чем задумано.
Это каким способом решить?
СПАСИБО!
P.S. что это реализуемо через массивы, мне известно, код нужен именно в таком виде =)
Symba вне форума Ответить с цитированием
Старый 05.06.2013, 12:48   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
проблема в том, что ПСЧ попадает во второй интервал чаще в два раза, чем задумано, а в пятый реже в два раза, чем задумано.
Это каким способом решить?
Использовать другой генератор случайных чисел. Относительно этого никто и не обещал, что он будет работать нормально.
Abstraction вне форума Ответить с цитированием
Старый 05.06.2013, 13:00   #3
Symba
Пользователь
 
Регистрация: 02.03.2011
Сообщений: 31
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
Использовать другой генератор случайных чисел. Относительно этого никто и не обещал, что он будет работать нормально.
пример, пожалуйста, или ссылку.
Symba вне форума Ответить с цитированием
Старый 05.06.2013, 13:26   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Попробуйте
rand() % range
хотя это тоже не очень правильный способ.
Еще лучше:
rand() * range / RAND_MAX
waleri вне форума Ответить с цитированием
Старый 05.06.2013, 13:44   #5
Symba
Пользователь
 
Регистрация: 02.03.2011
Сообщений: 31
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Попробуйте
rand() % range
хотя это тоже не очень правильный способ.
Еще лучше:
rand() * range / RAND_MAX
как же мне это реализовать, если мне на промежутке [0,1] ПСЧ нужно?
я так понял range - это интервал?
и по ходу вся проблема в компиляторе...компилю код в VS C++ Express...
только что попробовал в Linux с++ компилировать и QtCreator' ом - все работает как надо....

под Windows 7 и MinGW работает криво....не подскажите компилятор под Win ? =]

Последний раз редактировалось Symba; 05.06.2013 в 14:09.
Symba вне форума Ответить с цитированием
Старый 05.06.2013, 19:29   #6
Igor95
Форумчанин
 
Регистрация: 03.01.2013
Сообщений: 388
По умолчанию

Visual Studio 2012
Igor95 вне форума Ответить с цитированием
Старый 05.06.2013, 19:54   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

тут не компиль виноват а реализация ГПСЧ.
возьмите стороннюю реализация, например с буста.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 06.06.2013, 00:11   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Не гони волну на студийный компилятор, и ищи косяк в своем коде.

Стандартный виндузятный rand() дает равномерное покрытие по всему диапазону (сам лично проверял как работает студийный, когда изобретал свой собственный рандом).

http://codepad.org/HvSIuKpX

Последний раз редактировалось _Bers; 06.06.2013 в 00:15.
_Bers вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
С++, BMP-файлы, растянуть в два раза изображение. Alendorff Помощь студентам 5 21.05.2012 11:29
Как обобщить функцию с двух интервалов на один? Lyubimov Помощь студентам 2 17.05.2011 06:00
Sql запрос. Из одной таблицы два раза templton SQL, базы данных 2 20.04.2011 17:47
два раза к одной таблице Kolik317 SQL, базы данных 2 26.12.2009 13:58
слово пишется два раза INDY-SAVER Microsoft Office Word 2 18.11.2009 23:49