kursovik.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. unit Kursovik;
  2. INTERFACE
  3. type
  4. PSource = ^CSource;
  5. PDevice = ^CDevice;
  6. PBuffer = ^CBuffer;
  7. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  8. TReq = record
  9. Birth : real;
  10. Death : real;
  11. FromSource : PSource;
  12. ToDevice : PDevice;
  13. end;
  14. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  15. {$R-}
  16. TReqArray = array [0..1000] of TReq;
  17. PReqArray = ^TReqArray;
  18. TSourceArr = array [0..1000] of PSource;
  19. PSourceArr = ^TSourceArr;
  20. PReq = ^TReq;
  21. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  22. ESOURCES = (SOURCE_DUMMY,SOURCE_EASIEST,SOURCE_ERLANG); {Типы источников}
  23. CSource = object
  24. SType : ESOURCES; {Каков наш источник? }
  25. Name : integer; {А как его зовут ?}
  26. LastTime : real; {Время генерации последнего запроса}
  27. LastReq : TReq; {Последний сгенерированный запрос}
  28. NewTime : real; {Момент генерации нового запроса}
  29. Lambda : real;
  30. TotalReq : longInt; {Общее число заявок от источника}
  31. DoneReq : longInt; {число обработанных заявок от источника}
  32. RefusedReq:LongInt; {Число отклоненных заявок}
  33. WaitTime : real; {Общее время пребывания в системе}
  34. ProbRefuse:real; {Вероятность отказа}
  35. MatWait : real; {Математическое ожидание в буфере}
  36. Constructor Init(aName : Integer;aLambda:real); {Конструктор с именем}
  37. Procedure Reset; {Сброс всех счетчиков}
  38. Procedure GenNewReq; {Генерация нового запроса}
  39. Destructor Done;virtual;
  40. end;{CSource}
  41. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  42. CDevice = object {Объект - простейшее устойство массового обслуживания}
  43. LastTime : real; {Время последнего завершения обслуживания}
  44. BegTime : real; {Время начала обслуживания}
  45. DoneTime : real; {Время, в которое закончится обработка}
  46. Stoppage : real; {Общее время простоя прибора}
  47. IsWorking : boolean; {Осуществляется ли обслуживание ?}
  48. CurWorking : TReq; {Текущий обрабатываемый запрос}
  49. Lambda : real;
  50. Constructor Init(aLambda:real); {}
  51. Function AddReq(aCurReq : PReq;aCurTime:real):boolean; {Начало обработка запроса}
  52. Procedure Reset; {Сброс устр-ва}
  53. Function DoneWork:PReq; {Завершение обработки текущего запроса, с его возвратом}
  54. Destructor Done;
  55. end; {CDevice}
  56. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  57. EBuffers = (BUFFER_DUMMY, BUFFER_FIFO, BUFFER_LIFO, BUFFER_PRIOR);
  58. CBuffer = object {Буффер запросов}
  59. BufType : EBuffers; {Тип буфера}
  60. BufferLength : integer; {Длина буфера}
  61. CellCount : integer; {Индекс текущей свободной ячейки}
  62. Data : PReqArray; {Собственно сам буфер}
  63. Constructor Init(aBufLen:integer); {Инициализация буфера}
  64. Destructor Done;virtual;{Деструктор, он и есть}
  65. Function SetBufferSize(aNewSize:integer):boolean;{Изменение размера буфера}
  66. Procedure FreeBuffer; {Освобождение всего буфера сразу}
  67. Function AddReq(var aNew, rKicked:TReq):boolean; {Добавляется запрос в буфер.
  68. Если из буфера какой-то запрос удален, то ф-ция возвр. false, и в rKicked -
  69. запрос, который отклонен}
  70. Function GetReq(var rReq:TReq):boolean;virtual; {Вытащить из буфера запрос,
  71. если успешно - true}
  72. end; {CBuffer}
  73. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  74. CModel = object {Наша модель СМО}
  75. Sources : PSourceArr; {Источники}
  76. SourceCnt: integer; {Число источников}
  77. MaxSrc : integer; {Размерность массива источников}
  78. Buffer : PBuffer; {Буфер}
  79. Device : PDevice; {Устройство}
  80. CurTime : real; {Текущий момент времени}
  81. Delta : real;
  82. DovInt : real;
  83. NextSource:integer; {Какой из источников - быстрее}
  84. RealizSteps:LongInt; {Необх. число реализаций}
  85. CurStep : LongInt; {Текущий шаг}
  86. {}
  87. DoneCount, {Число обработанных заявок}
  88. RefusedCount, {Число отклоненных заявок}
  89. TotalCount : integer; {Общее число заявок}
  90. Working : boolean; {Работает ли модель ?}
  91. WorkReq : TReq;
  92. Constructor Init(aBegSrcCnt:integer;aDev:PDevice;aBuf:PBuffer;
  93. aDel,aDov:Real);
  94. Function SetSourceCount(aNewCnt:integer):boolean; {Установка нового числа
  95. источников, с сохранением старых}
  96. Function AddNewSource(aNewSrc:PSource):boolean; {Добавление нового источника}
  97. Procedure SetNextSource; {Находит NextSource}
  98. Function TestVer:boolean; {}
  99. Function RemoveSource(aName:integer):boolean; {Удаление источника из модели}
  100. Procedure Reset; {Сброс всех счетчиков}
  101. Procedure Start;
  102. Procedure PrintValues;
  103. Function Step:boolean; {Моделирует следующий шаг, если в }
  104. Destructor Done;
  105. end;
  106. {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  107. IMPLEMENTATION
  108. Constructor CSource.Init(aName : Integer;aLambda:real);
  109. Begin
  110. Name := aName;
  111. SType := SOURCE_EASIEST;
  112. Lambda := aLambda;
  113. Reset;
  114. end;{CSource.Init}
  115. {-------------------------------------------------------------------------}
  116. Procedure CSource.Reset;
  117. Begin
  118. LastTime :=0; NewTime:=0;
  119. TotalReq :=0;
  120. DoneReq :=0;
  121. RefusedReq:=0;
  122. WaitTime :=0;
  123. ProbRefuse:=0;
  124. MatWait :=0;
  125. end;{CSource.Reset}
  126. {-------------------------------------------------------------------------}
  127. Procedure CSource.GenNewReq;
  128. Begin
  129. LastTime := NewTime;
  130. NewTime := LastTime - Ln(Random)/Lambda;
  131. Inc(TotalReq);
  132. LastReq.Birth := NewTime;
  133. LastReq.Death := -1.0;
  134. LastReq.FromSource := @Self;
  135. end;{CSource.GenNewReq}
  136. {-------------------------------------------------------------------------}
  137. Destructor CSource.Done;
  138. begin
  139. end;
  140. {-------------------------------------------------------------------------}
  141. { CDevice }
  142. Constructor CDevice.Init(aLambda:real);
  143. begin
  144. Lambda := aLambda;
  145. Reset;
  146. end;{CDevice.Init}
  147. {=========================================}
  148. Procedure CDevice.Reset;
  149. begin
  150. LastTime := 0;
  151. DoneTime := 0;
  152. Stoppage := 0;
  153. IsWorking := false;
  154. end;{CDevice.Reset}
  155. {---------------------------}
  156. Function CDevice.AddReq(aCurReq : PReq;aCurTime:real):boolean; {Начало обработка запроса}
  157. begin
  158. AddReq := false;
  159. if not isWorking then
  160. begin
  161. BegTime := aCurTime;
  162. Stoppage := Stoppage + (BegTime-LastTime);
  163. DoneTime := BegTime - (Ln(Random) + Random)/Lambda;
  164. IsWorking := true;
  165. CurWorking := aCurReq^;
  166. CurWorking.ToDevice := @Self;
  167. AddReq := true;
  168. end;
  169. end;{CDevice.AddReq}
  170. {=========================================}
  171. Function CDevice.DoneWork:PReq;
  172. begin
  173. DoneWork := nil;
  174. if isWorking then
  175. begin
  176. LastTime := DoneTime;
  177. CurWorking.Death := DoneTime;
  178. DoneWork := @CurWorking;
  179. isWorking := false;
  180. end;
  181. end;{CDevice.DoneWork}
  182. {=========================================}
  183. Destructor CDevice.Done;
  184. begin
  185. end;{CDevice.Done}
  186. {=========================================}
  187. { CBuffer }
  188. Constructor CBuffer.Init(aBufLen:integer);
  189. begin
  190. BufType := BUFFER_PRIOR;
  191. BufferLength := aBufLen;
  192. CellCount := 0;
  193. GetMem(Data,Sizeof(TReq)*BufferLength);
  194. FillChar(Data^,Sizeof(TReq)*BufferLength,0);
  195. end;{CBuffer.Init}
  196. {-----------------------}
  197. Destructor CBuffer.Done;
  198. begin
  199. FreeMem(Data,Sizeof(TReq)*BufferLength); {Dispose(data)}
  200. BufferLength:=0;
  201. end;{CBuffer.Done}
  202. {-----------------------}
  203. Function CBuffer.SetBufferSize(aNewSize:integer):boolean;
  204. var
  205. NewBuf : PReqArray;
  206. begin
  207. SetBufferSize := false;
  208. if aNewSize > BufferLength then
  209. begin
  210. GetMem(NewBuf,Sizeof(TReq)*aNewSize);
  211. FillChar(NewBuf^,Sizeof(TReq)*aNewSize,0);
  212. Move(Data^,NewBuf^,Sizeof(TReq)*BufferLength);
  213. FreeMem(Data,Sizeof(TReq)*BufferLength);
  214. Data := NewBuf;
  215. BufferLength := aNewSize;
  216. SetBufferSize := true;
  217. end;
  218. end;{CBuffer.SetBufferSize}
  219. {-----------------------}
  220. Function CBuffer.AddReq(var aNew, rKicked:TReq):boolean;
  221. begin
  222. if CellCount=BufferLength then {На самом деле, т.к с 0, то больше}
  223. begin
  224. AddReq := false;
  225. rKicked := aNew;
  226. rKicked.Death := aNew.Birth; {Запрос отклонен, в момент, когда новый прибыл,
  227. т.е. когда тот был создан}
  228. end
  229. else
  230. begin
  231. AddReq := true;
  232. Data^[CellCount] := aNew;
  233. Inc(CellCount);
  234. end;
  235. end;{CBuffer.AddReq}
  236. {-----------------------}
  237. Function CBuffer.GetReq(var rReq:TReq):boolean;
  238. var
  239. i,n : byte;
  240. begin
  241. GetReq := false;
  242. if CellCount = 0 then Exit;
  243. n := 0;
  244. for i := 0 to CellCount-1 do if Data^[i].FromSource^.Name = 1 then
  245. begin
  246. n := i;
  247. break;
  248. end;
  249. rReq := Data^[n];
  250. Move(Data^[n+1],Data^[n],sizeof(TReq) * (CellCount-n-1));
  251. Dec(CellCount);
  252. GetReq := true;
  253. end;{CBuffer.GetReq}
  254. {---------------------------------------------}
  255. Procedure CBuffer.FreeBuffer;
  256. begin
  257. CellCount := 0;
  258. end;
  259. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  260. Constructor CModel.Init(aBegSrcCnt:integer;aDev:PDevice;aBuf:PBuffer;
  261. aDel,aDov:Real);
  262. Begin
  263. MaxSrc := aBegSrcCnt;
  264. GetMem(Sources,Sizeof(PSource)*MaxSrc);
  265. SourceCnt := 0;
  266. RealizSteps := 100;
  267. Buffer := aBuf;
  268. Device := aDev;
  269. Delta := aDel;
  270. DovInt := aDov;
  271. Reset;
  272. end;{CModel.Init}
  273. {---------------------------------------------------------}
  274. Procedure CModel.Reset;
  275. begin
  276. NextSource:=0;
  277. CurTime := 0;
  278. CurStep := 0;
  279. DoneCount := 0;
  280. RefusedCount := 0;
  281. RealizSteps := 100;
  282. TotalCount := 0;
  283. Working := false;
  284. end;{CModel.Reset}
  285. {------------------------------------------------------------------}
  286. Function CModel.SetSourceCount(aNewCnt:integer):boolean;
  287. var
  288. NewBuf : PSourceArr;
  289. Begin
  290. SetSourceCount := false;
  291. if aNewCnt > MaxSrc then
  292. begin
  293. GetMem(NewBuf,Sizeof(PSource)*aNewCnt);
  294. Move(Sources^,NewBuf^,Sizeof(PSource)*MaxSrc);
  295. FreeMem(Sources,Sizeof(PSource)*MaxSrc);
  296. Sources := NewBuf;
  297. MaxSrc := aNewCnt;
  298. SetSourceCount := true;
  299. end;
  300. end;{CModel.SetSourceCount}
  301. {------------------------------------------------------------------}
  302. Function CModel.AddNewSource(aNewSrc:PSource):boolean;
  303. Begin
  304. if SourceCnt >= MaxSrc then AddNewSource := SetSourceCount(MaxSrc+1);
  305. Sources^[SourceCnt] := aNewSrc;
  306. Inc(SourceCnt);
  307. end;{CModel.AddNewSource}
  308. {------------------------------------------------------------------}
  309. Function CModel.RemoveSource(aName:integer):boolean;
  310. var
  311. c : integer;
  312. Begin
  313. RemoveSource := false;
  314. if SourceCnt = 1 then exit;
  315. for c := 0 to SourceCnt-1 do if Sources^[c]^.Name = aName then break;
  316. if c = SourceCnt-1 then exit;
  317. Dispose(Sources^[c],Done);
  318. while c <> SourceCnt-1 do
  319. begin
  320. Sources^[c] := Sources^[c+1];
  321. inc(c);
  322. end;
  323. Dec(SourceCnt);
  324. end;{CModel.RemoveSource}
  325. {------------------------------------------------------------------}
  326. Procedure CModel.SetNextSource; {Находит NextSource}
  327. var
  328. c : integer;
  329. begin
  330. NextSource := 0;
  331. for c := 0 to SourceCnt-1 do
  332. begin
  333. if (Sources^[c]^.NewTime < Sources^[NextSource]^.NewTime) then
  334. NextSource := c;
  335. end;
  336. end;{CModel.SetNextSource}
  337. {------------------------------------------------------------------}
  338. Procedure CModel.Start;
  339. var
  340. c,First : integer;
  341. begin
  342. if (Device=nil) or (Buffer=nil) or (SourceCnt=0) then exit;
  343. Reset;
  344. Device^.Reset;
  345. Buffer^.FreeBuffer;
  346. First := 0;
  347. for c := 0 to SourceCnt-1 do
  348. begin
  349. Sources^[c]^.Reset;
  350. Sources^[c]^.GenNewReq;
  351. if (Sources^[c]^.NewTime < Sources^[First]^.NewTime) then
  352. First := c;
  353. end;
  354. WorkReq := Sources^[First]^.LastReq;
  355. Device^.AddReq(@WorkReq,Sources^[First]^.NewTime);
  356. Sources^[First]^.GenNewReq;
  357. SetNextSource;
  358. Working := true;
  359. end;
  360. {------------------------------------------------------------------}
  361. Function CModel.TestVer:boolean;
  362. var
  363. NewV,c,p:real;
  364. i : integer;
  365. begin
  366. NewV:=0;
  367. TestVer:=true;
  368. for i := 0 to SourceCnt-1 do if Sources^[i]^.RefusedReq <> 0 then
  369. begin
  370. p := 1.0 * Sources^[i]^.RefusedReq / Sources^[i]^.TotalReq;
  371. c := (DovInt*(1-p))/(Delta*Delta*p);
  372. if c > NewV then NewV := c;
  373. end;
  374. if NewV > RealizSteps then
  375. begin
  376. RealizSteps := round(NewV);
  377. TestVer := false;
  378. end;
  379. end;{CModel.TextVer}
  380. {------------------------------------------------------------------}
  381. Function CModel.Step:boolean;
  382. var
  383. Kicked : TReq;
  384. i : integer;
  385. ret : boolean;
  386. Begin
  387. Step := false;
  388. if Not Working then exit;
  389. ret := false; {Считаем, что продолжать не будем}
  390. for i:=0 to SourceCnt-1 do if Sources^[i]^.TotalReq < RealizSteps then
  391. ret:=true;
  392. if not ret then ret := not TestVer;
  393. if Device^.DoneTime < Sources^[NextSource]^.NewTime then
  394. begin
  395. CurTime := Device^.DoneTime;
  396. WorkReq := Device^.DoneWork^;
  397. inc(DoneCount);
  398. inc(TotalCount);
  399. inc(WorkReq.FromSource^.DoneReq);
  400. WorkReq.FromSource^.WaitTime := WorkReq.FromSource^.WaitTime +
  401. WorkReq.Death - WorkReq.Birth;
  402. if Buffer^.GetReq(WorkReq) then
  403. begin {В буфере находилась заявка}
  404. WorkReq.FromSource^.MatWait := WorkReq.FromSource^.MatWait +
  405. CurTime-WorkReq.Birth;
  406. Device^.AddReq(@WorkReq,CurTime);
  407. end
  408. else {Need to gen new req}
  409. begin
  410. Device^.AddReq(@Sources^[NextSource]^.LastReq,Sources^[NextSource]^.LastReq.Birth);
  411. Sources^[NextSource]^.GenNewReq;
  412. SetNextSource;
  413. end;
  414. end
  415. else {Ближайшее событие - генерация запроса}
  416. begin
  417. CurTime := Sources^[NextSource]^.NewTime;
  418. if not Buffer^.AddReq(Sources^[NextSource]^.LastReq,Kicked) then
  419. begin
  420. inc(Kicked.FromSource^.RefusedReq);
  421. {Kicked.FromSource^.WaitTime := Kicked.FromSource^.WaitTime +
  422. Kicked.Death-Kicked.Birth;}
  423. Inc(RefusedCount);
  424. Inc(TotalCount);
  425. end;
  426. Sources^[NextSource]^.GenNewReq;
  427. SetNextSource;
  428. end; {}
  429. inc(CurStep);
  430. Step := ret;
  431. end;{CModel.Step}
  432. {------------------------------------------------------------------}
  433. Procedure CModel.PrintValues;
  434. var
  435. i : integer;
  436. begin
  437. WriteLn('Отн. точность - ',Delta*100:0:0,'%, дов. инт в кв. - ',DovInt:0:2);
  438. WriteLn('Хар-ка потока прибора - ', Device^.Lambda:0:2);
  439. WriteLn('Ист.|Всг заяв.|Отк заяв.|Вып заяв.|P отк. |Мат. ож | Общ. вр.');
  440. for i := 0 to SourceCnt-1 do with Sources^[i]^ do
  441. begin
  442. write(Name:4,' ',TotalReq:9,' ',RefusedReq:9,' ',DoneReq:9,' ',100.0*RefusedReq/TotalReq:6:2,'% ');
  443. if DoneReq <> 0 then Write(MatWait/DoneReq:8:3,' ') else Write(' --- ');
  444. WriteLN(WaitTime:0:2);
  445. end;
  446. WriteLn('Коэффициент простоя прибора - ',100*Device^.Stoppage/CurTime:0:2,'%');
  447. WriteLN('---')
  448. end;{CModel.PrintValues}
  449. {------------------------------------------------------------------}
  450. Destructor CModel.Done;
  451. var
  452. c : integer;
  453. Begin
  454. for c:= 0 to SourceCnt-1 do Dispose(Sources^[c],Done);
  455. FreeMem(Sources,Sizeof(PSource)*MaxSrc);
  456. end;{CModel.Done}
  457. {------------------------------------------------------------------}
  458. END. {EOF}