Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.16;
Скачать: CL | DM;

Вниз

Еще задачка :)   Найти похожие ветки 

 
}|{yk ©   (2004-04-22 15:51) [40]

Все это ламерство - написание никому не нужного кода
и решение задач, решаемых элементарно другими средствами
причем эти средства бесплатны, и позволяют ответит на куда большее число вопросов. Вот добавьте в свою программу функцию выдачи максимальной очереди, которая возникнет за день. Слабо?


 
Verg ©   (2004-04-22 16:22) [41]


> }|{yk ©   (22.04.04 15:51) [40]


Чтно говоря, я не очень понимаю целей ваших утверждений... Если  код никомуненужен, то ваши утверждения еще менее кому-то нужны. Хотя, если вам будет от этого спокойнее, то можете меня считать ламером - мне абсолютно фиалетово.

Насчет "слабо":
Берем тот же код, меняем два места

 TBathRoom = class
 private
   FCount : integer;
   Cs : TCriticalSection;
   MenWait,
   WMenWait : TEvent;
   MQueSize, WMQueSize : integer;
   procedure ProcessFCount;
 public
   MQMax,             // Макс размер мужской очереди
   WMQMax : integer;
// Макс размер женской
   constructor Create;
   destructor  Destroy; override;
   procedure  ManEnter(MSex : integer);
   procedure  ManLeave;
 end;

............
procedure TBathRoom.ManEnter(MSex : integer);
var Que : boolean;
begin
 if MSex = 0 then exit;
 Que := false;
 repeat
   Cs.Enter;
   try
     if (FCount = 0) or
        not ((FCount < 0) xor (MSex < 0)) then
     begin
       Inc(FCount, MSex);
       ProcessFCount;
       if Que then
        if Msex < 0 then Dec( WMQueSize ) else Dec( MQueSize );
       break;
     end;
     if Msex < 0 then Inc( WMQueSize ) else Inc( MQueSize );
     Que := true;
     if WMQueSize > WMQMax then WMQMax := WMQueSize;
     if MQueSize  > MQMax  then MQMax := MQueSize;
   finally
     Cs.Leave;
   end;
   if MSex < 0 then
    WMenWait.WaitFor(INFINITE)
   else
    MenWait.WaitFor(INFINITE);
 until false;
end;


 
}|{yk ©   (2004-04-22 16:33) [42]

ОК, добавьте в программу распределение нагруженности "линии" в зависимости от часа дня


 
mrcat ©   (2004-04-22 16:34) [43]

>Игорь Шевченко ©   (22.04.04 11:05)
хм. где бы такую книжку приобрести ?


 
Verg ©   (2004-04-22 16:38) [44]


> }|{yk ©   (22.04.04 16:33) [42]
> ОК, добавьте в программу распределение нагруженности "линии"
> в зависимости от часа дня


Все, бесплатный цирк закончился... Каков гонорар?


 
}|{yk ©   (2004-04-22 16:42) [45]

Зачем гонорар? Я завтра могу принести условие задачи и ее решение с помощью GPSS. Попробуйте решить ту же задачу на Delphi. Рискнете?


 
Reindeer Moss Eater ©   (2004-04-22 16:45) [46]

Дурь какая-то.
Откуда некий могучий GPSS знает лучше Delphi про интенсивность посещения ванной студентами в течении дня.


 
Игорь Шевченко ©   (2004-04-22 16:49) [47]

mrcat ©   (22.04.04 16:34)

Эндрю Таненбаум, Современные операционные системы, 2-ое издание

http://www.findbook.ru


 
}|{yk ©   (2004-04-22 16:56) [48]

Этот инструмент предназначен специально для решения задач подобного типа. У нас в универе его изучают, правда слабее чем раньше (раньше еще и курсак по моделированию процессов на производстве писали). Почему юзают именно его? Просто завкаф для рассчетов в своей докторской его использовал


 
Verg ©   (2004-04-22 16:57) [49]


> }|{yk ©   (22.04.04 16:42) [45]
> Зачем гонорар? Я завтра могу принести условие задачи и ее
> решение с помощью GPSS. Попробуйте решить ту же задачу на
> Delphi. Рискнете?


Вы все еще сомневаетесь? :))
Или вам нужно ее решить при помощи Дельфи, а у вас никак не получается?
Или Вы таким образом рекламируете GPSS на сайте www.delphimaster.ru?

Или просто мозг поклевать захотелось? :)))


 
Reindeer Moss Eater ©   (2004-04-22 16:57) [50]

Распределение загруженности линии в течении дня - это четыре арифметических действия. Возможно даже меньше чем четыре.


 
McSimm ©   (2004-04-22 17:03) [51]

хм. где бы такую книжку приобрести ?

http://www.delphimaster.ru/books/978531800299/


 
Verg ©   (2004-04-22 17:08) [52]

Ладно, все, оставляю исходник с демкой:

unit Room;

interface
uses Windows, Classes, SysUtils, SyncObjs;

type
 TBathRoom = class
 private
   FCount : integer;
   Cs : TCriticalSection;
   MenWait,
   WMenWait : TEvent;
   MQueSize, WMQueSize : integer;
   procedure ProcessFCount;
 public
   MCount, WCount : integer;
   MQMax, WMQMax : integer;
   constructor Create;
   destructor  Destroy; override;
   procedure  ManEnter(MSex : integer);
   procedure  ManLeave;
   procedure  PrintState(MAdd, WAdd : integer);
 end;

implementation

constructor TBathRoom.Create;
begin
 inherited Create;
 Cs := TCriticalSection.Create;
 MenWait := TEvent.Create(nil, true, true, "");
 WMenWait := TEvent.Create(nil, true, true, "");
end;

destructor  TBathRoom.Destroy;
begin
 MenWait.Free;
 WMenWait.Free;
 Cs.Free;
 inherited;
end;

procedure  TBathRoom.PrintState(MAdd, WAdd : integer);
begin
 Cs.Enter;
 try
   Inc(MCount, MAdd);
   Inc(WCount, WAdd);
   Writeln("Man : ", MCount," WMen : ",WCount," FC : ", FCount,
           " MaxMQue ", MQMax, " MaxWQSize ", WMQMax );
   if (MCount<>0) and (WCount<>0) then
   begin
     Windows.Beep(1000, 50);
     ReadLn;
   end;
 finally
   Cs.Leave;
 end;
end;

procedure TBathRoom.ProcessFCount;
begin
 if FCount < 0 then MenWait.ResetEvent else MenWait.SetEvent;
 if FCount > 0 then WMenWait.ResetEvent else WMenWait.SetEvent;
end;

procedure TBathRoom.ManEnter(MSex : integer);
var Que : boolean;
begin
 if MSex = 0 then exit;
 Que := false;
 repeat
   Cs.Enter;
   try
     if (FCount = 0) or
        not ((FCount < 0) xor (MSex < 0)) then
     begin
       Inc(FCount, MSex);
       ProcessFCount;
       if MSex < 0 then
          PrintState(0, 1)
       else
          PrintState(1, 0);
       if Que then
        if Msex < 0 then Dec( WMQueSize ) else Dec( MQueSize );
       break;
     end;
     if not Que then
     begin
       if Msex < 0 then Inc( WMQueSize ) else Inc( MQueSize );
       Que := true;
       if WMQueSize > WMQMax then WMQMax := WMQueSize;
       if MQueSize  > MQMax  then MQMax := MQueSize;
     end;
   finally
     Cs.Leave;
   end;
   if MSex < 0 then
    WMenWait.WaitFor(INFINITE)
   else
    MenWait.WaitFor(INFINITE);
 until false;
end;

procedure TBathRoom.ManLeave;
var F : boolean;
begin
 Cs.Enter;
 try
   F := FCount < 0;
   if FCount = 0 then
     Windows.Beep(1000, 50);
   if FCount <> 0 then
     if FCount < 0 then Inc(FCount) else Dec(FCount);
   ProcessFCount;
   if F then
     PrintState(0, -1)
   else
     PrintState(-1, 0);
 finally
   Cs.Leave;
 end;
end;

end.


 
Verg ©   (2004-04-22 17:09) [53]

program BathRoom;

{$APPTYPE CONSOLE}

uses
 Windows,
 Classes,
 SysUtils,
 Room;

type
 TMan = class(TThread)
   FSex : integer;
   Br : TBathRoom;
   constructor Create(ASex : integer; Abr : TBathRoom);
   procedure Execute; override;
 end;

 constructor TMan.Create(ASex : integer; Abr : TBathRoom);
 begin
   FSex := ASex;
   Br := Abr;
   FreeOnTerminate := true;
   inherited Create(False);
 end;

 procedure TMan.Execute;
 begin
   Sleep(random(500));
   Br.ManEnter(FSex);
   Sleep(random(50));
   Br.ManLeave;
 end;

var BtRoom : TBathRoom;
   I : integer;
begin
 Randomize;
 BtRoom := TBathRoom.Create;
 For I := 1 to 2000 do
 begin
   if Random(100) < 50 then
     TMan.Create(1, BtRoom)
   else
     TMan.Create(-1, BtRoom)
 end;
 sleep(INFINITE);
end.


 
}|{yk ©   (2004-04-22 17:19) [54]

Таки принесу завтра задание и решение. посмотрим...


 
Reindeer Moss Eater ©   (2004-04-22 17:26) [55]

Знал я одного зав. вычислительно кафедрой. Доцент, КТН.
Свёл в конечном итоге весь учебный процесс на кафедре фактически к подготовке пользователей MS Office.

Тоже по страшной силе тащился от GPSS. До дрожи в руках.


 
Игорь Шевченко ©   (2004-04-22 17:41) [56]

GPSS  (GENERAL  PURPOSE  SIMULATING  SYSTEM)  -  система
симуляции генерала  Пурпоса  (генерал  Пурпос  -  сотрудник
фирмы IBM).


 
Юрий Зотов ©   (2004-04-22 20:15) [57]

Иными словами, GPSS - это как бы компонент, который надо только кинуть на форму и чуть-чуть настроить.

Но приходит момент, когда модель усложняется... и GPSS начинает решать ее неделями. Не потому, что он плохой, а потому что он - GENERAL purpose. И нет возможности заставить считать его быстрее.

Аналог - MathLab. Выход - руки + компилятор.

P.S.
Все то, что не превращается в конечный машинный код, языком программирования НЕ является.
(с) Юрий Зотов.
:о)


 
Sha ©   (2004-04-22 20:48) [58]

unit SexRoomU; // :)

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, StdCtrls;

const
 MY_MESSAGE = WM_USER + 101;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Timer1: TTimer;
   procedure FormCreate(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
   procedure ButtonClick(Sender: TObject);
   procedure MyMessage(var Msg : TMessage); message MY_MESSAGE;
 private
   Count: array[boolean] of integer;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin;
 Timer1.Enabled:=false;
 end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin;
 SendMessage(Self.Handle,MY_MESSAGE,0,0);
 end;

procedure TForm1.ButtonClick(Sender: TObject);
begin;
 SendMessage(Self.Handle,MY_MESSAGE,1,ord(Sender=Button2));
 end;

procedure TForm1.MyMessage(var Msg: TMessage);
const
 sex: array[boolean] of string= ("женщин","мужчин");
 place: array[boolean] of string= ("в очереди","в бане");
var
 IsMan: boolean;
begin;
 Msg.Result:=-1;
 if Msg.WParam=0 then begin;
   IsMan:=(Count[true]<0);
   inc(Count[IsMan]);
   end
 else begin;
   IsMan:=(Msg.LParam<>0);
   if Count[IsMan]>=0 then begin;
     inc(Count[IsMan]);
     IsMan:=not IsMan;
     end
   else dec(Count[IsMan]);
   end;
 IsMan:=IsMan xor (Count[IsMan]=0);
 if Count[IsMan]>0 then Count[IsMan]:=-Count[IsMan];
 Timer1.Enabled:=(Count[IsMan]<>0);
 Button1.Caption:=Format("%d %s %s",[abs(Count[false]),sex[false],place[Count[false]<0]]);
 Button2.Caption:=Format("%d %s %s",[abs(Count[true]),sex[true],place[Count[true]<0]]);
 end;

end.

object Form1: TForm1
 Left = 294
 Top = 103
 Width = 253
 Height = 109
 Caption = "Form1"
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 PixelsPerInch = 96
 TextHeight = 13
 object Button1: TButton
   Left = 8
   Top = 16
   Width = 225
   Height = 25
   Caption = "0 женщин в очереди "
   TabOrder = 0
   OnClick = ButtonClick
 end
 object Button2: TButton
   Left = 8
   Top = 48
   Width = 225
   Height = 25
   Caption = "0 мужчин в очереди "
   TabOrder = 1
   OnClick = ButtonClick
 end
 object Timer1: TTimer
   OnTimer = Timer1Timer
   Left = 24
   Top = 32
 end
end


 
Sha ©   (2004-04-22 21:01) [59]

PS Забыл сказать: это мой симулятор, только к поставленной задаче он отношения не имеет.


 
Сергей Суровцев.   (2004-04-23 00:00) [60]

>Reindeer Moss Eater ©   (22.04.04 14:02) [33]
>Остается придумать реализацию выхода из ванной.

Возможно я глубоко не прав, но вроде бы две простые глобальные переменные спасут отца русской демократии. :))
Два числовых счетчика М и Ж. Вошел: +1, вышел -1. Каждый при входе проверяет счетчик другого пола - если он 0, входит сам.
И все.
А уж к этому принципу столько статистики подвязать можно, насколько фантазии хватит. И по времени, и по количеству. А можно и ограничения подвязать на максимум внутри одновременно.
Код писать не буду ибо лень, а идею и так видно.  :))

>}|{yk ©   (22.04.04 15:51) [40]
>Все это ламерство - написание никому не нужного кода
>и решение задач, решаемых элементарно другими средствами

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


 
Aristarh ©   (2004-04-23 00:21) [61]

>Сергей Суровцев.   (23.04.04 00:00) [60]

Стек на каждую ванну


 
Aristarh ©   (2004-04-23 00:23) [62]

Подделка?
Ник-то не зарегистрированный. Суровцев с точкой в конце никогда не подписывался.


 
Юрий Зотов ©   (2004-04-23 06:47) [63]

> Сергей Суровцев.   (23.04.04 00:00) [60]
> Два числовых счетчика М и Ж. Вошел: +1, вышел -1. Каждый при
> входе проверяет счетчик другого пола - если он 0, входит сам.

А если он не ноль, то что? Ждет?

Ждет, вероятно. Вот только чего именно он ждет и как именно он ждет? В чем весь фокус и есть.

Надеюсь, такой вариант Вы даже и предлагать не станете:
while OtherCount > 0 do Sleep(0)


 
Verg ©   (2004-04-23 07:21) [64]

Допустим ванная комната вообще пуста....


> если он 0,(вот тут происходит переключение конекста на такой >же поток но противоположного пола, котрый тоже получается >обнаружит 0) входит сам (и  второй тоже входит).


Эти (такие) задачи не на логику.


 
Reindeer Moss Eater ©   (2004-04-23 08:38) [65]

В общем к модели [33] надо добавить один счетчик количества людей в ванной.

Каждый выходящий перед тем как покинуть ванную проверяет, не выходит ли он последним (перед этим сделав waitforsingleobject для семафора входной двери)
Заняв семафор двери, смотрим, равен ли счетчик единице.
Если да, то делаем OpenSemaphore семафору своего пола (если заходили не первым и не заняли его. Тогда его хендл у нас уже есть) после чего делаем релис этому семафору. После этого уменьшаем счетчик посетителей до нуля, и освобождаем семафор у двери (релис).


 
Reindeer Moss Eater ©   (2004-04-23 08:46) [66]

Правда выходящих из ванной не получится синхронизировать тем же семафором двери что и входящих. Если снаружи стоят тётки и курят, ожидая помывки, то семафор входной двери уже занят.

Четыре семафора нужно.


 
Сергей Суровцев.   (2004-04-23 10:11) [67]

>Aristarh ©   (23.04.04 00:23) [62]
Я это. Я. После смены паролей мой работать перестал. А так проще всего было. :))

>Юрий Зотов ©   (23.04.04 06:47) [63]
>А если он не ноль, то что? Ждет?
>Ждет, вероятно. Вот только чего именно он ждет и как именно он >ждет? В чем весь фокус и есть.

Очередь возникает ведь в любом случае. По условию. А в условии не сказано, что комната не должна пустовать ни мгновения. Если она может пустовать, то при входе вполне подойдет и вариант с переодическим опросом состояния (раз в 1-3 секунды), Если не должна вообще, то выходящий сам должен оповестить всю очередь, что он вышел и тогда вся очередь активизирует проверки.
По моему так! (с) Винний Пух.

P.S.
Загнал в "Сократ":
woman wants to enter, man wants to enter, woman leaves, man leaves.

и получил:

женщина хочет вводить, мужчины хочет вводить, женщину оставляет, листы человека.

Прямо Басё какой-то. :))


 
}|{yk ©   (2004-04-23 10:45) [68]

>Иными словами, GPSS - это как бы компонент, который надо только
>кинуть на форму и чуть-чуть настроить.
Вранье или же непонимание

>Но приходит момент, когда модель усложняется... и GPSS начинает
>решать ее неделями. Не потому, что он плохой, а потому что он -
>GENERAL purpose. И нет возможности заставить считать его быстрее.

Да в GPSS такие модели реализованы даже в демках (я давал ссылку, скачайте и посмотрите), которые универсальными методами вы будете неделями реализовывать. Правда бесплатна только student-версия


 
Матлабист   (2004-04-23 11:50) [69]

> Аналог - MathLab

Наверное MATLAB (MATrix LABoratory)


 
Юрий Зотов ©   (2004-04-25 14:09) [70]

> }|{yk ©   (23.04.04 10:45) [68]

> Вранье или же непонимание

Непонимание. Но, извините, не мое.

Инструмент готовый? Готовый. Вот это я и назвал - как бы компонент.

Модель и всякие там условия задать требуется? Требуется. Вот это я и назвал - настроить.

Нельзя же все понимать буквально.

> Да в GPSS такие модели реализованы даже в демках (я давал
> ссылку, скачайте и посмотрите), которые универсальными
> методами вы будете неделями реализовывать.

Неделями - это еще очень мало. Сложную модель запросто можно и год реализовывать. Но только для действительно сложных моделей другого пути реально нет, потому что универсальные инструменты интерпретирующего типа под такой моделью просто умрут. То есть - и за месяц непрерывного счета можно не дождаться результатов.


 
Sha ©   (2004-04-25 20:08) [71]

Если решать эту задачу применительно к потокам нескольких сортов,
то достаточно одного объекта синхронизации - критической секции
диспетчеризации, символизирующей банщика, впускающего/выпускающего
посетителей, сортирующего их по кабинкам (всех лиц одного пола -
в одну кабинку) и дающего воду в одну выбранную кабинку :)
Все остальное у потоков для старта/стопа (Resume/Suspend) уже есть.
Нам остается лишь вести список потоков и запоминать их сорт.

Реализация процедур примерно следующая:

Посетитель пришел
 Баншик.Начать
 Поместить посетителя в кабинку, запомнив в списке его данные
 Если это единственный посетитель в бане, подать воду в эту кабинку
 Если в кабинке есть вода
   то разрешить ему мыться
   иначе - запретить :)
 Банщик.Кончить

Посетитель помылся
 Баншик.Начать
 Выпустить посетителя, исключив из списка его данные
 Если это был последний посетитель в кабинке,
   то если это был последний посетитель в бане
        то выключить воду
        иначе переключить воду в заполненную кабинку
             и разрешить находящимся там мыться
 Банщик.Кончить


 
Sha ©   (2004-04-27 14:02) [72]

Verg ©   (22.04.04 17:08) [52]

Похоже, твой вариант - оптимальный.
Я тут немного его переделал (добавил GUI, обобщил на случай большего количества полов :)

unit RoomU;

interface

uses
 Windows, Classes, SysUtils, SyncObjs;

type
 TRoom = class(TObject)
 private
   FSection: TCriticalSection;
   FEvents: array of TEvent;
   FCurrentType: integer;
 protected
   FCabinetsCount: integer;
   FCabinets: array of integer;
   FTotal: integer;
 public
   OnEnter: TNotifyEvent;
   OnLeave: TNotifyEvent;
   OnThreadTerminate: TNotifyEvent;
   constructor Create(ACabinetsCount: integer);
   destructor Destroy; override;
   end;

 TRoomThread = class(TThread)
 protected
   FType: integer;
   FRoom: TRoom;
   procedure Execute; override;
   procedure DoEnter;
   procedure DoLeave;
   procedure EnterRoom;
   procedure LeaveRoom;
 public
   constructor Create(ARoom: TRoom; AType: integer);
   end;

implementation

constructor TRoom.Create(ACabinetsCount: integer);
var
 i: integer;
begin;
 inherited Create;
 FSection:=TCriticalSection.Create;
 SetLength(FEvents,ACabinetsCount);
 for i:=0 to ACabinetsCount-1 do FEvents[i]:=TEvent.Create(nil,true,false,"");
 SetLength(FCabinets,ACabinetsCount);
 FillChar(FCabinets[0],SizeOf(FCabinets[0])*ACabinetsCount,0);
 FCabinetsCount:=ACabinetsCount;
 FCurrentType:=-1;
 end;

destructor TRoom.Destroy;
var
 i: integer;
begin;
 FSection.Free;
 for i:=FCabinetsCount-1 downto 0 do FEvents[i].Free;
 FEvents:=nil;
 FCabinets:=nil;
 inherited;
 end;

constructor TRoomThread.Create(ARoom: TRoom; AType: integer);
begin;
 FRoom:=ARoom;
 FType:=AType;
 Self.OnTerminate:=ARoom.OnThreadTerminate;
 FreeOnTerminate:=true;
 inherited Create(false);
 end;

procedure TRoomThread.Execute;
begin;
 EnterRoom;
 if not Terminated then Sleep(300);
 LeaveRoom;
 end;

procedure TRoomThread.DoEnter;
begin;
 FRoom.OnEnter(Self);
 end;

procedure TRoomThread.DoLeave;
begin;
 FRoom.OnLeave(Self);
 end;

procedure TRoomThread.EnterRoom;
begin;
 with FRoom do begin;
   FSection.Enter;

   inc(FTotal);
   inc(FCabinets[FType]);
   if FCurrentType=-1 then begin;
     FCurrentType:=FType;
     FEvents[FCurrentType].SetEvent;
     end;

   if Assigned(OnEnter) then Synchronize(DoEnter);
   FSection.Leave;

   while not Terminated do if FEvents[FType].WaitFor(1000)=wrSignaled then break;
   end;
 end;

procedure TRoomThread.LeaveRoom;
var
 MaxCount, i: integer;
begin;
 with FRoom do begin;
   FSection.Enter;

   dec(FTotal);
   dec(FCabinets[FType]);
   if (FCabinets[FType]=0) and (FType=FCurrentType) then begin;
     FEvents[FCurrentType].ResetEvent;
     FCurrentType:=-1;
     if FTotal>0 then begin;
       MaxCount:=0;
       for i:=0 to FCabinetsCount-1 do if MaxCount<FCabinets[i] then begin;
         FCurrentType:=i; MaxCount:=FCabinets[i];
         end;
       FEvents[FCurrentType].SetEvent;
       end;
     end;

   if Assigned(OnLeave) then Synchronize(DoLeave);
   FSection.Leave;
   end;
 end;

end.


 
Sha ©   (2004-04-27 14:03) [73]

unit RoomTestU;

interface

uses
 SyncObjs, RoomU,
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   Label1: TLabel;
   Label2: TLabel;
   Label3: TLabel;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure RoomEnter(Sender: TObject);
   procedure RoomLeave(Sender: TObject);
   procedure ThreadTermitate(Sender: TObject);
   procedure ShowResults(Sender: TObject);
 private
   Room: TRoom;
   ThreadCount: integer;
   ThreadToEnter: integer;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin;
 Room:=TRoom.Create(10);
 Room.OnEnter:=RoomEnter;
 Room.OnLeave:=RoomLeave;
 Room.OnThreadTerminate:=ThreadTermitate;
 Randomize;
 end;

procedure TForm1.FormDestroy(Sender: TObject);
begin;
 Room.Free;
 end;

procedure TForm1.RoomEnter(Sender: TObject);
begin;
 dec(ThreadToEnter);
 ShowResults(Sender);
 end;

procedure TForm1.RoomLeave(Sender: TObject);
begin;
 ShowResults(Sender);
 end;

procedure TForm1.ThreadTermitate(Sender: TObject);
begin;
 dec(ThreadCount);
 ShowResults(nil);
 end;

type
 TMyRoom = class(TRoom);
 TMyThread = class(TRoomThread);
procedure TForm1.ShowResults(Sender: TObject);
var
 Text: string;
 i: integer;
begin;
 Label1.Caption:=IntToStr(ThreadToEnter)+" входят в баню";
 Label2.Caption:=IntToStr(TMyRoom(Room).FTotal)+" в бане";
 Label3.Caption:=IntToStr(ThreadCount-TMyRoom(Room).FTotal-ThreadToEnter)+" выходят из бани";
 if Sender<>nil then begin;
   Text:="";
   for i:=0 to TMyRoom(TMyThread(Sender).FRoom).FCabinetsCount-1 do
     Text:=Text+IntToStr(TMyRoom(TMyThread(Sender).FRoom).FCabinets[i])+#13#10;
   Memo1.Lines.Text:=Text;
   end;
 end;

procedure TForm1.Button1Click(Sender: TObject);
var
 i: integer;
begin;
 for i:=1 to 100 do begin;
   TRoomThread.Create(Room, Random(TMyRoom(Room).FCabinetsCount));
   inc(ThreadCount);
   inc(ThreadToEnter);
   ShowResults(nil);
   end;
 end;

end.

--------

object Form1: TForm1
 Left = 168
 Top = 292
 Width = 253
 Height = 211
 Caption = "Form1"
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 OnDestroy = FormDestroy
 PixelsPerInch = 96
 TextHeight = 13
 object Label1: TLabel
   Left = 136
   Top = 48
   Width = 6
   Height = 13
   Caption = "0"
 end
 object Label2: TLabel
   Left = 136
   Top = 64
   Width = 6
   Height = 13
   Caption = "0"
 end
 object Label3: TLabel
   Left = 136
   Top = 80
   Width = 6
   Height = 13
   Caption = "0"
 end
 object Button1: TButton
   Left = 136
   Top = 8
   Width = 105
   Height = 25
   Caption = "+100 посетителей"
   TabOrder = 0
   OnClick = Button1Click
 end
 object Memo1: TMemo
   Left = 8
   Top = 8
   Width = 113
   Height = 169
   TabOrder = 1
 end
end


 
}|{yk ©   (2004-04-27 14:46) [74]

2Юрий Зотов ©   (25.04.04 14:09) [70]

>Модель и всякие там условия задать требуется? Требуется. Вот это
> я и назвал - настроить.
Модель в GPSS не задаются тривиальными методами. Посмотрите скрипты

> То есть - и за месяц непрерывного счета можно не дождаться
>результатов.
Не знаю. Неслабенькая задача о б обслуживании в супермаркете решалалась до 5 секунд на моем слабо 500 Мгц


 
Sha ©   (2004-04-27 14:53) [75]

}|{yk ©   (27.04.04 14:46) [74]

Тут цель другая: создать систему, а не модель.


 
}|{yk ©   (2004-04-27 15:29) [76]

Вообще-то нужны не дрели а дырки :)


 
Юрий Зотов ©   (2004-04-27 16:30) [77]

> }|{yk
> Модель в GPSS не задаются тривиальными методами.

Ну, если задание НЕтривиальными методами - это как бы уже и не задание вовсе, то, конечно, дело меняется в корне.


 
nikkie ©   (2004-04-27 16:37) [78]

нету сил прочитать все выше написанное :)

по-моему, достаточно простое решение такое.

один счетчик (0 - никого нет, >0 - количество мужчин, <0 - количество женщин), защищенный критической секцией или мьютексом (в зависимости от того, как мы реализуем людей - отдельным процессом или отдельным потоком), при изменении счетчика в положение 0 - возбуждается event.


 
Reindeer Moss Eater ©   (2004-04-27 16:41) [79]

Кол-во женщин и кол-во мужчин знать не нужно.
Достаточно знать кол-во людей в ванной вообще.


 
nikkie ©   (2004-04-27 16:50) [80]

>[79] Reindeer Moss Eater
>Кол-во женщин и кол-во мужчин знать не нужно.
>Достаточно знать кол-во людей в ванной вообще.

если ты это мне, то один счетчик, как я предложил, именно так и делает. абсолютное значение - количество людей в ванной, знак - признак мужчины/женщины. если я пропустил и такое уже предлагалось выше - прошу прощения.



Страницы: 1 2 вся ветка

Текущий архив: 2004.05.16;
Скачать: CL | DM;

Наверх




Память: 0.67 MB
Время: 0.035 c
8-1077984929
Spartak
2004-02-28 19:15
2004.05.16
TMediaPlayer


11-1068996521
DeF
2003-11-16 18:28
2004.05.16
Дочерние окна


1-1083527200
DeOptric
2004-05-02 23:46
2004.05.16
Ссылка в Richedit


1-1083134768
WondeRu
2004-04-28 10:46
2004.05.16
Потоки!


9-1072859108
Elf
2003-12-31 11:25
2004.05.16
вопрос от чайника





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский