IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> СМО с ожиданием, нормальное распределение, динамика ets
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


Не посылайте в FAQ, плз. Я там была. Конкретно по этой теме там пару слов wink.gif

Только начала разбираться, и уже появилось несколько камней преткновения.

Условие. Необходимо создать СМО с ожиданием из 10 элементов, где:
- время прибытия и время обслуживания - случайные числа с нормальным распределением (просто random не подходит)
- остальные компоненты просчитываются, но об этом позже
- соблюдается принцип очереди FIFO в динамике

Код (это не все, только то, что вызывает вопросы):
type
TPClient=^TClient; {описание элементов очереди}
TClient=record
t1:real; {время прибытия}
t2:real; {время ожидания}
next:TPClient;
end;
var
head,node:TPClient;
naf: boolean;
nay: real;
{процедура вывода на экран}
procedure Print1;
var
curr:TPClient;
n:integer;
begin
curr:=head;
while (curr<>NIL)do
begin
writeln(curr^.t1,' ',curr^.t2);
curr:=curr^.next;
end;
end;
{функция генерирования случайных чисел по закону норм.распределения}
function nrandom:real; {вопрос 1}
var u1,u2:real;
begin
naf:=not naf; if naf then nrandom:=nay
else begin
repeat
u1:=random;
until u1>0;
u1:=sqrt(-2*ln(u1));
u2:=random*pi*2;
nay:=u1*cos(u2);
nrandom:=u1*sin(u2);
end;
end;
{создание очереди}
procedure Queure;
var
node:TPClient;
curr:TPClient;
pred:TPClient;
n:integer;
begin
n:=0;
naf:=true;
while n<10 do begin
new(node);
node^.t1:=nrandom;
node^.t2:=nrandom; {вопрос 3}
curr:=head;
pred:=NIL;
while (curr<>NIL) and (node^.t1>curr^.t1) do {вопрос 2}
begin
pred:=curr;
curr:=curr^.next;
end;
if pred=NIL
then
begin
node^.next:=head;
head:=node;
end
else
begin
node^.next:=pred^.next;
pred^.next:=node;
end;
n:=n+1; end;
end;

begin
Queure;
Print1;
readln;
end.

Вопросы:
1. Во всех алгоритмах норм.распределения генерируемые числа - вещественные, а мне необходимы целые. Плюс - числа должны быть >=0. Как грамотно их преобразовать?
2. В первой колонке сформированых чисел, по-моему, должен быть порядок - этот пришел в 0-ой момент времени, этот в 1-ый и т.д. Во второй - упорядочивание не должно проводиться. Как разобраться с этим?
3. Во второй колонке не должен попадаться 0 (время обслуживания не может быть таковым). Достаточно ли просто прибавить 1?
И самый главный вопрос. После прогона получаются ОДИНАКОВЫЕ наборы чисел! Мне необходимо отразить результаты нескольких прогонов, а какой с них толк, если они одинаковые!

Помогите разобраться unsure.gif

Сообщение отредактировано: volvo -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 8)
сообщение
Сообщение #2


Бывалый
***

Группа: Пользователи
Сообщений: 206
Пол: Мужской

Репутация: -  3  +


Если идет речь о нормально распределенных случайных числах, то они ведь распределены на каком-то интервале, верно?
Итак, имеем
Fi - очередное сгенерированное Вашей функцией вещественное случайное число. Видимо, оно будет в интервале от 0 до 1? Или, в общем случае, от F1 до F2.
TPi - очередное время прибытия. Тоже, надо полагать в некотором интервале - от TP1 до ТP2.
TOi - очередное время обслуживания. В некотором интервале - от TО1 до ТО2.
Тогда
Код
TPi := TP1 + (TP2-TP1)*(Fi-F1)/(F2-F1);
TOi := TO1 + (TO2-TO1)*(Fi-F1)/(F2-F1);

Если Fi лежит в интервале от 0 до 1, тогда формулы упрощаются.
Код
TPi := TP1 + (TP2-TP1)*Fi;
TOi := TO1 + (TO2-TO1)*Fi;

Если нужны именно целые числа (integer), то результат вычислений округляем (TPi := round(...)).
По поводу наборов чисел. Поскольку Ваша функция случайных чисел использует стандартный random, то перед каждым прогоном один раз вызываем процедуру randomize - и будет счастье.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


Так, с этим разобралась smile.gif Спасибо smile.gif
Кст, отдельное спасибо за randomize - вылетело из головы smile.gif

Тут другой вопрос возник. Динамика. Что-то я с ней никак подружиться не могу unsure.gif

Как грамотно при закрытии проги уничтожать очередь, чтоб мусора не оставалось?


Сообщение отредактировано: Jill -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата(Jill @ 26.07.2006 15:23)
Как грамотно при закрытии проги уничтожать очередь, чтоб мусора не оставалось?
Наверное, так:

procedure Clear;
var curr, deleting: TPClient;
begin
curr := head;
while curr <> nil do begin
deleting := curr;
dispose(deleting);
curr := curr^.next;
end;
head := nil;
end;

begin
writeln('before: ', memavail); { Проверяем: доступная память в начале работы }

Queure;
Print1;
Clear; { <--- Очищаем очередь }

writeln('after: ', memavail); { Доступная память после удаления очереди }
readln;
end.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


Ок, с мусором разобрались. Спасибо smile.gif

Тут еще вопрос возник. Переписала процедуру построения очереди - мне кажется, предыдущая версия (вставка элементов в упорядоченный список) была мухляжом wink.gif

Так честнее:
procedure Queure;
var
node:TPClient;
n:integer;
F1,F2:real;
begin
n:=0;
naf:=true;
while (n<10) do begin {вроде, можно тут поменять, но ведь node еще не создан...}
new(node);
F1:=nrandom;
F2:=nrandom;
curr:=head;
pred:=NIL;
while (curr<>NIL) do
begin
pred:=curr;
curr:=curr^.next;
end;
if pred=NIL
then
begin
node^.next:=head;
head:=node;
node^.t1:=Abs(round(F1));
end
else
begin
node^.next:=pred^.next;
pred^.next:=node;
node^.t1:=Abs(round(F1))+pred^.t1;
end;
n:=n+1;
node^.t2:=Abs(round(1+(10-1)*(F2-1)/(10-1)))+1;
end;
end;


Суть вопроса. По-моему, я ошиблась в условии - работа системы ограничена во времени, а не по количеству требований. Получается, система должна работать 10 единиц времени (без учета задержки из-за последнего требования). То бишь, до момента, когда node^.t1=10. Как организовать этот цикл? По-моему, repeat в динамике нельзя использовать...? unsure.gif

И еще один глупый вопрос (не ругайте, мне и так стыдно unsure.gif ). Как прервать работу программы при зацикливании?

Сообщение отредактировано: volvo -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата(Jill @ 28.07.2006 13:13)
По-моему, repeat в динамике нельзя использовать...? unsure.gif

blink.gif Это почему? В смысле, почему ты думаешь, что Repeat нельзя, а While - можно? Кстати, даже если ты не хочешь переделывать цикл на Repeat, то всегда можно сделать так:

while naf do begin
...
naf := (node^.t1 < 10)
{ Как только node^.t1 станет = или больше 10, цикл прервется на следующей итерации }
end;


Цитата(Jill @ 28.07.2006 13:13)
Как прервать работу программы при зацикливании?
В смысле, как программно определить зацикливание и выйти из цикла, или у тебя запущенная программа зациклилась, и ты хочешь прервать ее работу?

P.S.
Цитата(Jill @ 28.07.2006 13:13)
Так честнее:
Еще честнее было бы не бегать все время по очереди, а сделать в TClient ссылку не только на Next, но и на Prev... rolleyes.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


Цитата
Это почему? В смысле, почему ты думаешь, что Repeat нельзя, а While - можно?

Понятия не имею... Один препод (не по этому предмету...фух wink.gif ) почему-то жутко ругается на repeat в динамике. Это не так, да?

Цитата
В смысле, как программно определить зацикливание и выйти из цикла, или у тебя запущенная программа зациклилась, и ты хочешь прервать ее работу?

Второе - какими кнопками прервать wink.gif

Цитата
Еще честнее было бы не бегать все время по очереди, а сделать в TClient ссылку не только на Next, но и на Prev...

volvo, это больной вопрос sad.gif Они мне снятся уже, эти динамические переменные!!! Я уже не знаю, с какой стороны подойти, чтоб не обжечься...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Цитата(Jill @ 28.07.2006 13:59)
Это не так, да?
Не так, конечно... Применять или нет Repeat/Until программист должен НЕ там, где используются (или не используются) динамические переменные, а там, где это удобно...

Цитата(Jill @ 28.07.2006 13:59)
Второе - какими кнопками прервать
Иногда помогает Ctrl+Break, но это срабатывает в Турбо-Паскале 7.0 далеко не всегда, а только во время выполнения операций ввода/вывода... В остальное время вряд ли у тебя получится что-то сделать...

Цитата(Jill @ 28.07.2006 13:59)
volvo, это больной вопрос sad.gif Они мне снятся уже, эти динамические переменные!!! Я уже не знаю, с какой стороны подойти, чтоб не обжечься...
Если ты готова пожертвовать 4-мя байтами памяти на каждый элемент очереди, чтобы было проще (и быстрее, насколько я понимаю) работать с этой самой очередью, то добавь ссылку на предыдущий элемент. Если программа критична к использованию памяти, а скорость ее работы менее важна - то этого делать не стОит... А ошибаться не бойся: "Не ошибается только тот, кто ничего не делает" (С)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


Еще вопрос. По поводу вывода требований и течения смоделированного времени +это самое время, правда поединично надо тоже выводить (0,1,2,3,.....10)

Вывод списка требований производится с задержкой, если предыдущий и текущий элемент отличаются:
 if (pred<>NIL)and(pred^.t1<>curr^.t1) then Delay(1000); 


Как обработать данные, чтобы, например, если элементы отличаются на 2 - единицы времени - задержка вывода списка - в два раза больше {с этим вроде разобралась...}, а вывод текущего времени - продолжается? {а вот с этим - нет sad.gif}

Надеюсь, не слишком запутанно...

Сообщение отредактировано: volvo -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 4:20
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name