Skip to content

Commit ee44a60

Browse files
committed
M: lab 4 5 6 7
1 parent 0ddaaa1 commit ee44a60

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1339
-3
lines changed

Modeling/4/main.py

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from system.model import Model
2+
from system.generator import *
3+
from system.queue import Queue
4+
from system.service import Service
5+
6+
from PyQt6 import uic
7+
from PyQt6.QtCore import pyqtSlot
8+
from PyQt6.QtWidgets import QApplication, QWidget, QMessageBox
9+
10+
11+
class MainWindow(QWidget):
12+
def __init__(self):
13+
super().__init__()
14+
self.ui = uic.loadUi('main.ui', self)
15+
self.init_ui()
16+
17+
def init_ui(self):
18+
ui = self.ui
19+
ui.a.setValue(2)
20+
ui.b.setValue(8)
21+
ui.m.setValue(5)
22+
ui.sigma.setValue(1)
23+
ui.return_factor.setValue(0.1)
24+
ui.dt.setValue(10e-3)
25+
26+
ui.n_tasks.setRange(5, 5000)
27+
ui.n_tasks.setValue(100)
28+
ui.run.setStyleSheet('background-color:#388e3c')
29+
30+
@pyqtSlot(name='on_run_clicked')
31+
def on_run(self):
32+
ui = self.ui
33+
try:
34+
a = ui.a.value()
35+
b = ui.b.value()
36+
m = ui.m.value()
37+
sigma = ui.sigma.value()
38+
n_tasks = ui.n_tasks.value()
39+
return_factor = ui.return_factor.value()
40+
dt = ui.dt.value()
41+
42+
g_uniform = UniformGenerator(a, b)
43+
g_normal = NormalGenerator(m, sigma)
44+
queue = Queue()
45+
46+
print('Принцип Δt')
47+
generator = RequestGenerator(g_uniform, n_tasks)
48+
service = Service(g_normal, return_factor)
49+
model = Model(generator, queue, service)
50+
t, completed_tasks, queue_len_max = model.time_based(n_tasks, dt)
51+
self.show_result(self.ui.result_time, t, completed_tasks, completed_tasks-n_tasks, queue_len_max)
52+
53+
print()
54+
55+
print('Событийный принцип')
56+
generator = RequestGenerator(g_uniform, n_tasks)
57+
service = Service(g_normal, return_factor)
58+
model = Model(generator, queue, service)
59+
t, completed_tasks, queue_len_max = model.event_based(n_tasks)
60+
self.show_result(self.ui.result_event, t, completed_tasks, completed_tasks-n_tasks, queue_len_max)
61+
62+
except Exception as e:
63+
QMessageBox.critical(self, 'Error', str(e))
64+
65+
@staticmethod
66+
def show_result(text_edit, t, completed_tasks, returned_tasks, queue_len_max):
67+
result_str = f'Обработанные заявки: {completed_tasks}\n\n'\
68+
f'Повторно обработанные заявки: {returned_tasks}\n\n'\
69+
f'Максимальная длина очереди: {queue_len_max}\n\n'\
70+
f'Время работы: {t:.2f}'
71+
72+
text_edit.setPlainText(result_str)
73+
74+
75+
if __name__ == '__main__':
76+
import sys
77+
78+
app = QApplication(sys.argv)
79+
window = MainWindow()
80+
window.show()
81+
app.exec()

Modeling/4/main.ui

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>Form</class>
4+
<widget class="QWidget" name="Form">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>451</width>
10+
<height>490</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<widget class="QWidget" name="gridLayoutWidget">
17+
<property name="geometry">
18+
<rect>
19+
<x>10</x>
20+
<y>10</y>
21+
<width>431</width>
22+
<height>151</height>
23+
</rect>
24+
</property>
25+
<layout class="QGridLayout" name="gridLayout">
26+
<item row="3" column="0">
27+
<widget class="QLabel" name="label_4">
28+
<property name="text">
29+
<string>Вероятность возврата заявки</string>
30+
</property>
31+
</widget>
32+
</item>
33+
<item row="0" column="0">
34+
<widget class="QLabel" name="label_2">
35+
<property name="text">
36+
<string>Генератор U(a,b)</string>
37+
</property>
38+
</widget>
39+
</item>
40+
<item row="4" column="0">
41+
<widget class="QLabel" name="label_5">
42+
<property name="text">
43+
<string>Δt</string>
44+
</property>
45+
</widget>
46+
</item>
47+
<item row="1" column="0">
48+
<widget class="QLabel" name="label_3">
49+
<property name="text">
50+
<string>Обслуживающий аппарат N(m,σ^2)</string>
51+
</property>
52+
</widget>
53+
</item>
54+
<item row="2" column="0">
55+
<widget class="QLabel" name="label">
56+
<property name="text">
57+
<string>Количество заявок</string>
58+
</property>
59+
</widget>
60+
</item>
61+
<item row="0" column="1">
62+
<widget class="QDoubleSpinBox" name="a"/>
63+
</item>
64+
<item row="0" column="2">
65+
<widget class="QDoubleSpinBox" name="b"/>
66+
</item>
67+
<item row="1" column="1">
68+
<widget class="QDoubleSpinBox" name="m"/>
69+
</item>
70+
<item row="1" column="2">
71+
<widget class="QDoubleSpinBox" name="sigma"/>
72+
</item>
73+
<item row="3" column="1" colspan="2">
74+
<widget class="QDoubleSpinBox" name="return_factor"/>
75+
</item>
76+
<item row="4" column="1" colspan="2">
77+
<widget class="QDoubleSpinBox" name="dt"/>
78+
</item>
79+
<item row="2" column="1" colspan="2">
80+
<widget class="QSpinBox" name="n_tasks"/>
81+
</item>
82+
</layout>
83+
</widget>
84+
<widget class="QPushButton" name="run">
85+
<property name="geometry">
86+
<rect>
87+
<x>120</x>
88+
<y>190</y>
89+
<width>211</width>
90+
<height>31</height>
91+
</rect>
92+
</property>
93+
<property name="text">
94+
<string>Моделировать</string>
95+
</property>
96+
</widget>
97+
<widget class="QWidget" name="gridLayoutWidget_2">
98+
<property name="geometry">
99+
<rect>
100+
<x>10</x>
101+
<y>250</y>
102+
<width>431</width>
103+
<height>221</height>
104+
</rect>
105+
</property>
106+
<layout class="QGridLayout" name="gridLayout_2">
107+
<item row="0" column="0">
108+
<widget class="QLabel" name="label_6">
109+
<property name="text">
110+
<string>Принцип Δt</string>
111+
</property>
112+
</widget>
113+
</item>
114+
<item row="0" column="1">
115+
<widget class="QLabel" name="label_7">
116+
<property name="text">
117+
<string>Событийный принцип</string>
118+
</property>
119+
</widget>
120+
</item>
121+
<item row="1" column="0">
122+
<widget class="QPlainTextEdit" name="result_time"/>
123+
</item>
124+
<item row="1" column="1">
125+
<widget class="QPlainTextEdit" name="result_event"/>
126+
</item>
127+
</layout>
128+
</widget>
129+
</widget>
130+
<resources/>
131+
<connections/>
132+
</ui>

Modeling/4/system/__init__.py

Whitespace-only changes.

Modeling/4/system/generator.py

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from numpy.random import default_rng
2+
3+
4+
class IGenerator:
5+
generator = default_rng()
6+
7+
def generate(self) -> float:
8+
raise NotImplementedError
9+
10+
11+
class UniformGenerator(IGenerator):
12+
def __init__(self, low, high):
13+
if low > high: low, high = high, low
14+
self.low = low
15+
self.high = high
16+
17+
def generate(self):
18+
return self.generator.uniform(self.low, self.high)
19+
20+
21+
class NormalGenerator(IGenerator):
22+
def __init__(self, loc, scale):
23+
self.loc = loc
24+
self.scale = scale
25+
26+
def generate(self):
27+
return self.generator.normal(self.loc, self.scale)
28+
29+
30+
class RequestGenerator:
31+
def __init__(self, generator: IGenerator, n_task: int):
32+
self._generator = generator
33+
self._remaining_time = 0
34+
self._is_ready = False
35+
self._generated_tasks = 0
36+
self._n_task = n_task
37+
38+
def generate(self):
39+
r = -1
40+
while r <= 0:
41+
r = self._generator.generate()
42+
self._remaining_time = r
43+
self._is_ready = True
44+
self._generated_tasks += 1
45+
return self._remaining_time
46+
47+
def elapse(self, time):
48+
if not self._is_ready:
49+
if self._generated_tasks == self._n_task:
50+
return 0
51+
r = self._remaining_time - time
52+
if r <= 10e-4:
53+
r = self.generate() - r # suppose >0
54+
self._remaining_time = r
55+
return self._remaining_time
56+
57+
def pop(self):
58+
if self._is_ready:
59+
self._is_ready = False
60+
return self._generated_tasks # task id
61+
return None
62+
63+
@property
64+
def is_ready(self):
65+
return self._is_ready
66+
67+
@property
68+
def generated_tasks(self):
69+
return self._generated_tasks

Modeling/4/system/model.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from .generator import RequestGenerator
2+
from .queue import Queue
3+
from .service import Service
4+
5+
6+
LOG_FREQ = 5
7+
8+
9+
class Model:
10+
def __init__(self, generator: RequestGenerator, queue: Queue, service: Service):
11+
self._generator = generator
12+
self._queue = queue
13+
self._service = service
14+
15+
def time_based(self, n_tasks, dt=10e-3):
16+
generator, queue, service = self._generator, self._queue, self._service
17+
t_current = 0
18+
n_tasks_for_logging = n_tasks // LOG_FREQ
19+
20+
while generator.generated_tasks < n_tasks \
21+
or not queue.is_empty or not service.is_ready:
22+
generator.elapse(dt)
23+
_, return_task = service.elapse(dt)
24+
25+
if return_task:
26+
queue.enqueue(return_task)
27+
28+
if generator.is_ready:
29+
task = generator.pop()
30+
queue.enqueue(task)
31+
32+
if service.is_ready and not queue.is_empty:
33+
if service.completed_tasks % n_tasks_for_logging == 0:
34+
print(f'Processed {service.completed_tasks:3d} tasks, t = {t_current:.4f}')
35+
task = queue.dequeue()
36+
service.process(task)
37+
38+
t_current += dt
39+
40+
return t_current, service.completed_tasks, queue.len_max
41+
42+
def event_based(self, n_tasks):
43+
"""
44+
events: task_generated, task_completed
45+
"""
46+
generator, queue, service = self._generator, self._queue, self._service
47+
t_current = 0
48+
n_tasks_for_logging = n_tasks // LOG_FREQ
49+
dt = 0
50+
51+
while generator.generated_tasks < n_tasks \
52+
or not queue.is_empty or not service.is_ready:
53+
t_current += dt
54+
t_remain_task_generated = generator.elapse(dt)
55+
t_remain_task_completed, return_task = service.elapse(dt)
56+
57+
if return_task:
58+
queue.enqueue(return_task)
59+
60+
if generator.is_ready:
61+
task = generator.pop()
62+
queue.enqueue(task)
63+
64+
if service.is_ready and not queue.is_empty:
65+
if service.completed_tasks % n_tasks_for_logging == 0:
66+
print(f'Processed {service.completed_tasks:4d} tasks, t = {t_current:.4f}')
67+
68+
task = queue.dequeue()
69+
t_remain_task_completed = service.process(task)
70+
71+
t_list = [t_remain_task_generated, t_remain_task_completed]
72+
t_list = list(filter(lambda x: x > 0, t_list))
73+
dt = min(t_list) if t_list else 0
74+
75+
return t_current, service.completed_tasks, queue.len_max

Modeling/4/system/queue.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from collections import deque
2+
3+
4+
class Queue:
5+
6+
def __init__(self, maxlen=None):
7+
self._queue = deque(maxlen=maxlen)
8+
self._len_max = 0
9+
self._len = 0
10+
11+
def enqueue(self, item):
12+
self._queue.append(item)
13+
self._len += 1
14+
if self._len > self._len_max:
15+
self._len_max = self._len
16+
17+
def dequeue(self):
18+
if self._len > 0:
19+
self._len -= 1
20+
return self._queue.pop()
21+
else:
22+
return None
23+
24+
@property
25+
def is_empty(self):
26+
return self._len <= 0
27+
28+
@property
29+
def len_max(self):
30+
return self._len_max
31+
32+
@property
33+
def len(self):
34+
return self._len

0 commit comments

Comments
 (0)