feat: updated questions
2
.gitignore
vendored
@ -2057,3 +2057,5 @@ games/unreal/BulletHellGame/BulletHellCPP/Linux/BulletHellCPP/Saved/Config/Crash
|
||||
games/unreal/BulletHellGame/BulletHellCPP/Linux/BulletHellCPP/Saved/Config/CrashReportClient/UECC-Linux-FADD9F04A90C410CB79783BFCA90A515/CrashReportClient.ini
|
||||
games/unreal/BulletHellGame/BulletHellCPP/Linux/BulletHellCPP/Saved/Config/CrashReportClient/UECC-Linux-FECA3347009644AEBA22F337CEDFE2FD/CrashReportClient.ini
|
||||
games/unreal/BulletHellGame/BulletHellCPP/Linux/BulletHellCPP/Saved/Config/CrashReportClient/UECC-Linux-FECA3347009644AEBA22F337CEDFE2FD/CrashReportClient.ini
|
||||
|
||||
data/publications/
|
||||
|
||||
146
pytania/generate_q18_diagrams.py
Normal file
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate EOQ diagrams for PYTANIE 18: Zarządzanie zapasami w łańcuchu dostaw.
|
||||
Monochrome, A4-printable PNGs (300 DPI).
|
||||
"""
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
DPI = 300
|
||||
BG = 'white'
|
||||
LN = 'black'
|
||||
OUTPUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'img')
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
|
||||
def generate_sawtooth_inventory():
|
||||
"""Sawtooth inventory diagram showing Q dropping to 0 across cycles,
|
||||
with Q/2 average line and delivery markers."""
|
||||
|
||||
fig, ax = plt.subplots(figsize=(7, 3.5), dpi=DPI, facecolor=BG)
|
||||
|
||||
Q = 1000
|
||||
n_cycles = 4
|
||||
cycle_len = 1.0 # arbitrary time unit per cycle
|
||||
|
||||
for i in range(n_cycles):
|
||||
t_start = i * cycle_len
|
||||
t_end = (i + 1) * cycle_len
|
||||
ax.plot([t_start, t_end], [Q, 0], color=LN, lw=2, solid_capstyle='round')
|
||||
# Vertical jump at delivery (except the very first which starts at t=0)
|
||||
if i > 0:
|
||||
ax.plot([t_start, t_start], [0, Q], color=LN, lw=2,
|
||||
linestyle='--', alpha=0.5)
|
||||
|
||||
# Average inventory line
|
||||
ax.axhline(y=Q / 2, color='gray', linestyle='-.', lw=1.2, zorder=0)
|
||||
ax.text(n_cycles * cycle_len * 1.02, Q / 2,
|
||||
f'średni zapas = Q/2 = {Q // 2}',
|
||||
va='center', ha='left', fontsize=8, color='gray')
|
||||
|
||||
# Delivery markers
|
||||
for i in range(n_cycles):
|
||||
ax.plot(i * cycle_len, Q, 'ko', markersize=5, zorder=5)
|
||||
ax.annotate('dostawa', xy=(i * cycle_len, Q),
|
||||
xytext=(i * cycle_len + 0.05, Q + 60),
|
||||
fontsize=7, ha='left', color='black',
|
||||
arrowprops=dict(arrowstyle='->', color='black', lw=0.8))
|
||||
|
||||
# Labels
|
||||
ax.set_xlabel('Czas', fontsize=10)
|
||||
ax.set_ylabel('Poziom zapasu', fontsize=10)
|
||||
ax.set_title('Model EOQ — piłokształtny przebieg zapasu', fontsize=11,
|
||||
fontweight='bold', pad=10)
|
||||
|
||||
ax.set_xlim(-0.1, n_cycles * cycle_len + 0.6)
|
||||
ax.set_ylim(-50, Q + 150)
|
||||
ax.set_yticks([0, Q // 2, Q])
|
||||
ax.set_yticklabels(['0', 'Q/2', 'Q'], fontsize=9)
|
||||
ax.set_xticks([i * cycle_len for i in range(n_cycles + 1)])
|
||||
ax.set_xticklabels([f'T{i}' for i in range(n_cycles + 1)], fontsize=9)
|
||||
|
||||
ax.spines['top'].set_visible(False)
|
||||
ax.spines['right'].set_visible(False)
|
||||
|
||||
fig.tight_layout()
|
||||
path = os.path.join(OUTPUT_DIR, 'q18_eoq_sawtooth.png')
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f'Saved: {path}')
|
||||
|
||||
|
||||
def generate_cost_curves():
|
||||
"""EOQ cost curve: ordering cost, holding cost, and total cost
|
||||
with optimum Q* marked."""
|
||||
|
||||
fig, ax = plt.subplots(figsize=(7, 4.5), dpi=DPI, facecolor=BG)
|
||||
|
||||
D = 10000
|
||||
K = 100
|
||||
h = 2
|
||||
Q_star = np.sqrt(2 * K * D / h) # 1000
|
||||
|
||||
Q = np.linspace(200, 2500, 500)
|
||||
ordering = K * D / Q
|
||||
holding = h * Q / 2
|
||||
total = ordering + holding
|
||||
|
||||
ax.plot(Q, ordering, color='black', lw=1.8, linestyle='--',
|
||||
label='Koszt zamawiania K·D/Q')
|
||||
ax.plot(Q, holding, color='black', lw=1.8, linestyle=':',
|
||||
label='Koszt utrzymania h·Q/2')
|
||||
ax.plot(Q, total, color='black', lw=2.5, linestyle='-',
|
||||
label='Koszt całkowity TC(Q)')
|
||||
|
||||
# Mark optimum
|
||||
TC_star = np.sqrt(2 * K * D * h)
|
||||
ax.plot(Q_star, TC_star, 'ko', markersize=8, zorder=5)
|
||||
ax.annotate(f'Q* = {int(Q_star)}\nTC* = {int(TC_star)} PLN',
|
||||
xy=(Q_star, TC_star),
|
||||
xytext=(Q_star + 300, TC_star + 600),
|
||||
fontsize=9, fontweight='bold', ha='left',
|
||||
arrowprops=dict(arrowstyle='->', color='black', lw=1.2),
|
||||
bbox=dict(boxstyle='round,pad=0.3', facecolor='#F0F0F0',
|
||||
edgecolor='black', lw=0.8))
|
||||
|
||||
# Vertical dashed line from Q* to x-axis
|
||||
ax.plot([Q_star, Q_star], [0, TC_star], color='gray', linestyle='-.',
|
||||
lw=0.8, zorder=0)
|
||||
|
||||
# Show that ordering = holding at Q*
|
||||
cross_y = K * D / Q_star # = h * Q_star / 2 = 1000
|
||||
ax.annotate('koszt zamawiania\n= koszt utrzymania',
|
||||
xy=(Q_star, cross_y),
|
||||
xytext=(Q_star - 500, cross_y + 800),
|
||||
fontsize=7.5, ha='center', style='italic',
|
||||
arrowprops=dict(arrowstyle='->', color='gray', lw=0.8),
|
||||
color='gray')
|
||||
|
||||
ax.set_xlabel('Wielkość zamówienia Q [szt]', fontsize=10)
|
||||
ax.set_ylabel('Koszt roczny [PLN]', fontsize=10)
|
||||
ax.set_title('Model EOQ — krzywe kosztów', fontsize=11,
|
||||
fontweight='bold', pad=10)
|
||||
|
||||
ax.legend(loc='upper right', fontsize=8.5, framealpha=0.9,
|
||||
edgecolor='black')
|
||||
ax.set_xlim(100, 2600)
|
||||
ax.set_ylim(0, 5500)
|
||||
|
||||
ax.spines['top'].set_visible(False)
|
||||
ax.spines['right'].set_visible(False)
|
||||
|
||||
fig.tight_layout()
|
||||
path = os.path.join(OUTPUT_DIR, 'q18_eoq_cost_curves.png')
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f'Saved: {path}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
generate_sawtooth_inventory()
|
||||
generate_cost_curves()
|
||||
print('Done — all Q18 diagrams generated.')
|
||||
636
pytania/generate_q26_jacobi_diagrams.py
Normal file
@ -0,0 +1,636 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate diagrams explaining WHY parallel Jacobi needs ghost cells
|
||||
and neighbor communication.
|
||||
Output: A4-compatible, black & white, laser-printer-friendly PNG files.
|
||||
|
||||
Diagrams:
|
||||
1. q26_jacobi_stencil.png — 1D Jacobi stencil: x_new[i] depends on x[i-1] and x[i+1]
|
||||
2. q26_domain_decomposition.png — domain split across processes, showing the boundary problem
|
||||
3. q26_ghost_cell_exchange.png — ghost cell exchange with Send/Recv
|
||||
4. q26_deadlock_vs_solution.png — deadlock scenario vs Sendrecv solution
|
||||
"""
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as mpatches
|
||||
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
# --- Common settings ---
|
||||
DPI = 300
|
||||
BG_COLOR = 'white'
|
||||
LINE_COLOR = 'black'
|
||||
FONT_SIZE = 10
|
||||
TITLE_SIZE = 13
|
||||
OUTPUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'img')
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
LIGHT_GRAY = '#D0D0D0'
|
||||
MED_GRAY = '#A0A0A0'
|
||||
DARK_GRAY = '#606060'
|
||||
VERY_LIGHT = '#F0F0F0'
|
||||
HIGHLIGHT = '#404040'
|
||||
|
||||
|
||||
def draw_cell(ax, x, y, w, h, text, fill='white', edgecolor='black',
|
||||
lw=1.5, fontsize=FONT_SIZE, fontweight='normal', textcolor='black'):
|
||||
"""Draw a rectangular cell with text."""
|
||||
rect = plt.Rectangle((x, y), w, h, lw=lw, edgecolor=edgecolor,
|
||||
facecolor=fill, zorder=2)
|
||||
ax.add_patch(rect)
|
||||
ax.text(x + w/2, y + h/2, text, ha='center', va='center',
|
||||
fontsize=fontsize, fontweight=fontweight, color=textcolor, zorder=3)
|
||||
|
||||
|
||||
def draw_arrow(ax, x1, y1, x2, y2, color='black', lw=1.5, style='->', zorder=4):
|
||||
ax.annotate("", xy=(x2, y2), xytext=(x1, y1),
|
||||
arrowprops=dict(arrowstyle=style, color=color, lw=lw),
|
||||
zorder=zorder)
|
||||
|
||||
|
||||
def draw_curvy_arrow(ax, x1, y1, x2, y2, color='black', lw=1.5,
|
||||
connectionstyle="arc3,rad=0.3"):
|
||||
ax.annotate("", xy=(x2, y2), xytext=(x1, y1),
|
||||
arrowprops=dict(arrowstyle='->', color=color, lw=lw,
|
||||
connectionstyle=connectionstyle),
|
||||
zorder=4)
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# 1. JACOBI STENCIL — why x_new[i] needs neighbors
|
||||
# =========================================================================
|
||||
def generate_jacobi_stencil():
|
||||
fig, ax = plt.subplots(figsize=(10, 5.5))
|
||||
ax.set_xlim(-0.5, 10)
|
||||
ax.set_ylim(-2.5, 4.5)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_title("Szablon Jacobiego 1D — dlaczego potrzebujesz sąsiadów",
|
||||
fontsize=TITLE_SIZE, fontweight='bold', pad=15)
|
||||
|
||||
# Draw the 1D array: x[0], x[1], ..., x[7]
|
||||
cw = 1.0 # cell width
|
||||
ch = 0.8
|
||||
y_old = 2.5 # y for old array
|
||||
y_new = 0.0 # y for new array
|
||||
n = 8
|
||||
|
||||
# Label rows
|
||||
ax.text(-0.4, y_old + ch/2, "Stara\niteracja:", ha='right', va='center',
|
||||
fontsize=FONT_SIZE, fontweight='bold')
|
||||
ax.text(-0.4, y_new + ch/2, "Nowa\niteracja:", ha='right', va='center',
|
||||
fontsize=FONT_SIZE, fontweight='bold')
|
||||
|
||||
for i in range(n):
|
||||
x = i * cw
|
||||
# Old values row
|
||||
fill_old = LIGHT_GRAY if i in (2, 4) else 'white'
|
||||
if i == 3:
|
||||
fill_old = MED_GRAY
|
||||
draw_cell(ax, x, y_old, cw, ch, f"x[{i}]", fill=fill_old)
|
||||
|
||||
# New values row
|
||||
fill_new = 'white'
|
||||
if i == 3:
|
||||
fill_new = DARK_GRAY
|
||||
draw_cell(ax, x, y_new, cw, ch, f"x'[{i}]", fill=fill_new,
|
||||
textcolor='white', fontweight='bold')
|
||||
else:
|
||||
draw_cell(ax, x, y_new, cw, ch, f"x'[{i}]", fill=fill_new)
|
||||
|
||||
# Arrows from x[2] and x[4] to x'[3]
|
||||
# x[2] → x'[3]
|
||||
draw_arrow(ax, 2*cw + cw/2, y_old, 3*cw + cw/2, y_new + ch, lw=2.5)
|
||||
# x[4] → x'[3]
|
||||
draw_arrow(ax, 4*cw + cw/2, y_old, 3*cw + cw/2, y_new + ch, lw=2.5)
|
||||
|
||||
# Formula
|
||||
ax.text(4.0, -1.2,
|
||||
r"$x'[i] = \frac{1}{2}\,(x[i\!-\!1] + x[i\!+\!1])$",
|
||||
ha='center', va='center', fontsize=14,
|
||||
bbox=dict(boxstyle='round,pad=0.4', facecolor=VERY_LIGHT,
|
||||
edgecolor='black', lw=1.5))
|
||||
|
||||
# Concrete example
|
||||
ax.text(4.0, -2.0,
|
||||
r"$x'[3] = \frac{1}{2}\,(x[2] + x[4])$"
|
||||
" — aby obliczyć nową wartość x'[3],\n"
|
||||
"potrzebujemy wartości lewego i prawego sąsiada.",
|
||||
ha='center', va='center', fontsize=9)
|
||||
|
||||
fig.tight_layout()
|
||||
path = os.path.join(OUTPUT_DIR, 'q26_jacobi_stencil.png')
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG_COLOR)
|
||||
plt.close(fig)
|
||||
print(f" ✓ {path}")
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# 2. DOMAIN DECOMPOSITION — the boundary problem
|
||||
# =========================================================================
|
||||
def generate_domain_decomposition():
|
||||
fig, axes = plt.subplots(2, 1, figsize=(11, 7.5),
|
||||
gridspec_kw={'height_ratios': [1, 1.5]})
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
fig.suptitle("Dekompozycja domeny — dlaczego proces potrzebuje danych od sąsiada",
|
||||
fontsize=TITLE_SIZE, fontweight='bold', y=0.98)
|
||||
|
||||
# ---------- TOP: Full domain (single process) ----------
|
||||
ax = axes[0]
|
||||
ax.set_xlim(-1, 13)
|
||||
ax.set_ylim(-1, 3)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
|
||||
ax.text(-0.8, 1.4, "Jeden proces\n(cała domena):", ha='right', va='center',
|
||||
fontsize=9, fontweight='bold')
|
||||
|
||||
cw, ch = 1.0, 0.8
|
||||
for i in range(12):
|
||||
draw_cell(ax, i, 1, cw, ch, f"x[{i}]", fontsize=8)
|
||||
|
||||
ax.text(6, 0.2, "← Jeden proces ma WSZYSTKIE wartości → brak problemu",
|
||||
ha='center', fontsize=9, style='italic')
|
||||
|
||||
# ---------- BOTTOM: Split across 3 processes ----------
|
||||
ax = axes[1]
|
||||
ax.set_xlim(-2.5, 14)
|
||||
ax.set_ylim(-3.5, 4.5)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
|
||||
ax.text(6, 4.2, "Trzy procesy (domena podzielona):", ha='center',
|
||||
fontsize=11, fontweight='bold')
|
||||
|
||||
# Process colors
|
||||
p_colors = [VERY_LIGHT, LIGHT_GRAY, '#E8E8E8']
|
||||
p_labels = ['Proces 0', 'Proces 1', 'Proces 2']
|
||||
p_ranges = [(0, 4), (4, 8), (8, 12)]
|
||||
|
||||
y_proc = 2.5
|
||||
for pi, (start, end) in enumerate(p_ranges):
|
||||
# Background box for process
|
||||
bx = start * cw - 0.15
|
||||
bw = (end - start) * cw + 0.3
|
||||
bg = plt.Rectangle((bx, y_proc - 0.3), bw, ch + 0.6,
|
||||
lw=2, edgecolor='black', facecolor=p_colors[pi],
|
||||
linestyle='--', zorder=1)
|
||||
ax.add_patch(bg)
|
||||
ax.text(bx + bw/2, y_proc + ch + 0.55, p_labels[pi],
|
||||
ha='center', va='center', fontsize=9, fontweight='bold')
|
||||
|
||||
for i in range(start, end):
|
||||
fill = 'white'
|
||||
fw = 'normal'
|
||||
# Highlight boundary cells
|
||||
if i == end - 1 and pi < 2: # right boundary
|
||||
fill = MED_GRAY
|
||||
fw = 'bold'
|
||||
if i == start and pi > 0: # left boundary
|
||||
fill = MED_GRAY
|
||||
fw = 'bold'
|
||||
draw_cell(ax, i * cw, y_proc, cw, ch, f"x[{i}]",
|
||||
fill=fill, fontsize=8, fontweight=fw)
|
||||
|
||||
# Show the PROBLEM: Process 0 computing x'[3]
|
||||
# x'[3] needs x[2] (has it) + x[4] (does NOT have it!)
|
||||
# Highlight the dependency
|
||||
y_explain = 0.3
|
||||
|
||||
# Box showing calculation
|
||||
ax.text(2, y_explain + 0.6,
|
||||
"Proces 0 oblicza x'[3]:",
|
||||
ha='center', va='center', fontsize=10, fontweight='bold')
|
||||
|
||||
ax.text(2, y_explain - 0.1,
|
||||
r"$x'[3] = \frac{1}{2}\,(x[2] + x[4])$",
|
||||
ha='center', va='center', fontsize=12,
|
||||
bbox=dict(boxstyle='round,pad=0.3', facecolor='white',
|
||||
edgecolor='black', lw=1.5))
|
||||
|
||||
# Arrow from x[2] — "ma"
|
||||
draw_arrow(ax, 2.5, y_proc, 1.5, y_explain + 1.1, color='black', lw=1.5)
|
||||
ax.text(1.3, y_proc - 0.6, "MA ✓", ha='center', fontsize=9, fontweight='bold')
|
||||
|
||||
# Arrow from x[4] — "NIE MA!"
|
||||
draw_arrow(ax, 4.5, y_proc, 3.0, y_explain + 1.1, color='black', lw=1.5)
|
||||
ax.text(4.5, y_proc - 0.6, "NIE MA ✗", ha='center', fontsize=9,
|
||||
fontweight='bold', color='black')
|
||||
|
||||
# Explanation below
|
||||
ax.text(6, -1.2,
|
||||
"Problem: x[4] należy do Procesu 1, ale Proces 0 potrzebuje go\n"
|
||||
"do obliczenia x'[3]. → Proces 0 musi POPROSIĆ Proces 1 o wartość x[4].\n"
|
||||
"T\u0119 dodatkow\u0105 kopi\u0119 nazywamy \u201Ekom\u00F3rk\u0105-duchem\u201D (ghost cell).",
|
||||
ha='center', va='center', fontsize=9,
|
||||
bbox=dict(boxstyle='round,pad=0.5', facecolor=VERY_LIGHT,
|
||||
edgecolor='black', lw=1))
|
||||
|
||||
# Similarly for Process 1 needing x[3] from Process 0
|
||||
ax.text(6, -2.7,
|
||||
"Analogicznie: Proces 1 obliczając x'[4] potrzebuje x[3] od Procesu 0.\n"
|
||||
"→ Każda para sąsiadów musi wymienić po jednej wartości granicznej (w obie strony).",
|
||||
ha='center', va='center', fontsize=9,
|
||||
bbox=dict(boxstyle='round,pad=0.5', facecolor=VERY_LIGHT,
|
||||
edgecolor='black', lw=1))
|
||||
|
||||
fig.tight_layout(rect=[0, 0, 1, 0.95])
|
||||
path = os.path.join(OUTPUT_DIR, 'q26_domain_decomposition.png')
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG_COLOR)
|
||||
plt.close(fig)
|
||||
print(f" ✓ {path}")
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# 3. GHOST CELL EXCHANGE — the communication pattern
|
||||
# =========================================================================
|
||||
def generate_ghost_cell_exchange():
|
||||
fig, ax = plt.subplots(figsize=(12, 7))
|
||||
ax.set_xlim(-2.5, 15)
|
||||
ax.set_ylim(-4.5, 5.5)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_title("Wymiana komórek-duchów (ghost cell exchange) między procesami",
|
||||
fontsize=TITLE_SIZE, fontweight='bold', pad=15)
|
||||
|
||||
cw, ch = 1.0, 0.8
|
||||
|
||||
# === BEFORE exchange ===
|
||||
y_before = 3.0
|
||||
ax.text(-2.0, y_before + ch/2, "PRZED\nwymianą:", ha='right', va='center',
|
||||
fontsize=9, fontweight='bold')
|
||||
|
||||
# Process 0: x[0..3]
|
||||
for i in range(4):
|
||||
fill = MED_GRAY if i == 3 else 'white'
|
||||
draw_cell(ax, i * cw, y_before, cw, ch, f"x[{i}]", fill=fill, fontsize=8)
|
||||
# Empty ghost cell slot
|
||||
draw_cell(ax, 4 * cw, y_before, cw, ch, "?",
|
||||
fill=VERY_LIGHT, edgecolor=MED_GRAY,
|
||||
fontsize=10, fontweight='bold')
|
||||
ax.text(4.5, y_before + ch + 0.2, "ghost", ha='center', fontsize=7,
|
||||
style='italic', color=DARK_GRAY)
|
||||
|
||||
# Gap
|
||||
ax.text(5.8, y_before + ch/2, "│", ha='center', fontsize=16, color=MED_GRAY)
|
||||
|
||||
# Process 1: x[4..7]
|
||||
# Empty ghost cell slot
|
||||
draw_cell(ax, 6 * cw, y_before, cw, ch, "?",
|
||||
fill=VERY_LIGHT, edgecolor=MED_GRAY,
|
||||
fontsize=10, fontweight='bold')
|
||||
ax.text(6.5, y_before + ch + 0.2, "ghost", ha='center', fontsize=7,
|
||||
style='italic', color=DARK_GRAY)
|
||||
for i in range(4, 8):
|
||||
fill = MED_GRAY if i == 4 else 'white'
|
||||
draw_cell(ax, (i + 3) * cw, y_before, cw, ch, f"x[{i}]", fill=fill, fontsize=8)
|
||||
|
||||
# Process labels
|
||||
ax.text(2, y_before - 0.5, "Proces 0", ha='center', fontsize=9, fontweight='bold')
|
||||
ax.text(9, y_before - 0.5, "Proces 1", ha='center', fontsize=9, fontweight='bold')
|
||||
|
||||
# === ARROWS: the exchange ===
|
||||
y_mid = 1.3
|
||||
|
||||
# x[3] → ghost of Process 1
|
||||
draw_curvy_arrow(ax, 3.5, y_before, 6.5, y_before,
|
||||
connectionstyle="arc3,rad=-0.6", lw=2)
|
||||
ax.text(5, y_before + 1.8, "Send x[3]", ha='center', fontsize=9,
|
||||
fontweight='bold',
|
||||
bbox=dict(boxstyle='round,pad=0.2', facecolor='white',
|
||||
edgecolor='black'))
|
||||
|
||||
# x[4] → ghost of Process 0
|
||||
draw_curvy_arrow(ax, 7.5, y_before, 4.5, y_before,
|
||||
connectionstyle="arc3,rad=-0.6", lw=2)
|
||||
ax.text(5, y_before - 1.5, "Send x[4]", ha='center', fontsize=9,
|
||||
fontweight='bold',
|
||||
bbox=dict(boxstyle='round,pad=0.2', facecolor='white',
|
||||
edgecolor='black'))
|
||||
|
||||
# === AFTER exchange ===
|
||||
y_after = -1.5
|
||||
ax.text(-2.0, y_after + ch/2, "PO\nwymianie:", ha='right', va='center',
|
||||
fontsize=9, fontweight='bold')
|
||||
|
||||
# Process 0: x[0..3] + ghost x[4]
|
||||
for i in range(4):
|
||||
fill = MED_GRAY if i == 3 else 'white'
|
||||
draw_cell(ax, i * cw, y_after, cw, ch, f"x[{i}]", fill=fill, fontsize=8)
|
||||
draw_cell(ax, 4 * cw, y_after, cw, ch, "x[4]",
|
||||
fill=LIGHT_GRAY, edgecolor='black',
|
||||
fontsize=8, fontweight='bold')
|
||||
ax.text(4.5, y_after + ch + 0.2, "ghost ✓", ha='center', fontsize=7,
|
||||
style='italic', fontweight='bold')
|
||||
|
||||
ax.text(5.8, y_after + ch/2, "│", ha='center', fontsize=16, color=MED_GRAY)
|
||||
|
||||
# Process 1: ghost x[3] + x[4..7]
|
||||
draw_cell(ax, 6 * cw, y_after, cw, ch, "x[3]",
|
||||
fill=LIGHT_GRAY, edgecolor='black',
|
||||
fontsize=8, fontweight='bold')
|
||||
ax.text(6.5, y_after + ch + 0.2, "ghost ✓", ha='center', fontsize=7,
|
||||
style='italic', fontweight='bold')
|
||||
for i in range(4, 8):
|
||||
fill = MED_GRAY if i == 4 else 'white'
|
||||
draw_cell(ax, (i + 3) * cw, y_after, cw, ch, f"x[{i}]", fill=fill, fontsize=8)
|
||||
|
||||
ax.text(2, y_after - 0.5, "Proces 0", ha='center', fontsize=9, fontweight='bold')
|
||||
ax.text(9, y_after - 0.5, "Proces 1", ha='center', fontsize=9, fontweight='bold')
|
||||
|
||||
# Explanation
|
||||
ax.text(5.5, -3.5,
|
||||
"Teraz Proces 0 ma kopię x[4] (ghost cell) i może obliczyć x'[3] = ½(x[2] + x[4]).\n"
|
||||
"Proces 1 ma kopię x[3] (ghost cell) i może obliczyć x'[4] = ½(x[3] + x[5]).\n"
|
||||
"→ Ta wymiana musi się powtarzać W KAŻDEJ iteracji Jacobiego.",
|
||||
ha='center', va='center', fontsize=9,
|
||||
bbox=dict(boxstyle='round,pad=0.5', facecolor=VERY_LIGHT,
|
||||
edgecolor='black', lw=1))
|
||||
|
||||
fig.tight_layout()
|
||||
path = os.path.join(OUTPUT_DIR, 'q26_ghost_cell_exchange.png')
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG_COLOR)
|
||||
plt.close(fig)
|
||||
print(f" ✓ {path}")
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# 4. DEADLOCK vs SOLUTION — side by side
|
||||
# =========================================================================
|
||||
def generate_deadlock_vs_solution():
|
||||
fig, axes = plt.subplots(1, 2, figsize=(14, 6.5))
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
fig.suptitle("Zakleszczenie (deadlock) vs rozwiązanie MPI_Sendrecv",
|
||||
fontsize=TITLE_SIZE, fontweight='bold', y=0.98)
|
||||
|
||||
# ---- LEFT: Deadlock ----
|
||||
ax = axes[0]
|
||||
ax.set_xlim(-1, 11)
|
||||
ax.set_ylim(-1, 11)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title("DEADLOCK — oba procesy w Ssend", fontsize=11, fontweight='bold')
|
||||
|
||||
# Timeline
|
||||
# Proc 0 column at x=2, Proc 1 column at x=8
|
||||
px0, px1 = 2.5, 8.5
|
||||
y_top = 9.5
|
||||
y_bot = 1.0
|
||||
|
||||
# Process headers
|
||||
draw_cell(ax, px0 - 1.2, y_top, 2.4, 0.8, "Proces 0",
|
||||
fill=LIGHT_GRAY, fontweight='bold', fontsize=10)
|
||||
draw_cell(ax, px1 - 1.2, y_top, 2.4, 0.8, "Proces 1",
|
||||
fill=LIGHT_GRAY, fontweight='bold', fontsize=10)
|
||||
|
||||
# Timeline lines
|
||||
ax.plot([px0, px0], [y_top, y_bot], color='black', lw=2, zorder=1)
|
||||
ax.plot([px1, px1], [y_top, y_bot], color='black', lw=2, zorder=1)
|
||||
|
||||
# Time arrow on the left
|
||||
ax.annotate("", xy=(0, y_bot), xytext=(0, y_top - 0.5),
|
||||
arrowprops=dict(arrowstyle='->', color=MED_GRAY, lw=1.5))
|
||||
ax.text(0, 5.5, "czas", ha='center', va='center', fontsize=8,
|
||||
rotation=90, color=DARK_GRAY)
|
||||
|
||||
# Step 1: Both call Ssend
|
||||
y1 = 8.0
|
||||
draw_cell(ax, px0 - 1.3, y1 - 0.3, 2.6, 0.6, "Ssend(→P1)",
|
||||
fill='white', fontsize=9, fontweight='bold')
|
||||
draw_cell(ax, px1 - 1.3, y1 - 0.3, 2.6, 0.6, "Ssend(→P0)",
|
||||
fill='white', fontsize=9, fontweight='bold')
|
||||
|
||||
# Arrows showing they wait for each other
|
||||
draw_curvy_arrow(ax, px0 + 1.3, y1, px1 - 1.3, y1,
|
||||
connectionstyle="arc3,rad=0.15", lw=1.5)
|
||||
ax.text(5.5, y1 + 0.5, "czeka na\nRecv P1", ha='center', fontsize=7,
|
||||
style='italic')
|
||||
draw_curvy_arrow(ax, px1 - 1.3, y1 - 0.1, px0 + 1.3, y1 - 0.1,
|
||||
connectionstyle="arc3,rad=0.15", lw=1.5)
|
||||
ax.text(5.5, y1 - 0.8, "czeka na\nRecv P0", ha='center', fontsize=7,
|
||||
style='italic')
|
||||
|
||||
# Blocked indicators
|
||||
y2 = 5.5
|
||||
for px in [px0, px1]:
|
||||
ax.plot([px - 0.5, px + 0.5], [y2 - 0.3, y2 + 0.3],
|
||||
color='black', lw=3, zorder=5)
|
||||
ax.plot([px - 0.5, px + 0.5], [y2 + 0.3, y2 - 0.3],
|
||||
color='black', lw=3, zorder=5)
|
||||
ax.text(5.5, y2, "DEADLOCK!", ha='center', fontsize=14,
|
||||
fontweight='bold', color='black',
|
||||
bbox=dict(boxstyle='round,pad=0.3', facecolor=LIGHT_GRAY,
|
||||
edgecolor='black', lw=2))
|
||||
|
||||
# Recv never reached
|
||||
y3 = 3.5
|
||||
draw_cell(ax, px0 - 1.3, y3 - 0.3, 2.6, 0.6, "Recv(←P1)",
|
||||
fill=VERY_LIGHT, edgecolor=MED_GRAY, fontsize=9)
|
||||
draw_cell(ax, px1 - 1.3, y3 - 0.3, 2.6, 0.6, "Recv(←P0)",
|
||||
fill=VERY_LIGHT, edgecolor=MED_GRAY, fontsize=9)
|
||||
ax.text(5.5, y3, "nigdy nie\nosiągnięte", ha='center', fontsize=8,
|
||||
style='italic', color=DARK_GRAY)
|
||||
|
||||
# ---- RIGHT: Solution with MPI_Sendrecv ----
|
||||
ax = axes[1]
|
||||
ax.set_xlim(-1, 11)
|
||||
ax.set_ylim(-1, 11)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title("ROZWIĄZANIE — MPI_Sendrecv", fontsize=11, fontweight='bold')
|
||||
|
||||
# Process headers
|
||||
draw_cell(ax, px0 - 1.2, y_top, 2.4, 0.8, "Proces 0",
|
||||
fill=LIGHT_GRAY, fontweight='bold', fontsize=10)
|
||||
draw_cell(ax, px1 - 1.2, y_top, 2.4, 0.8, "Proces 1",
|
||||
fill=LIGHT_GRAY, fontweight='bold', fontsize=10)
|
||||
|
||||
# Timeline lines
|
||||
ax.plot([px0, px0], [y_top, y_bot], color='black', lw=2, zorder=1)
|
||||
ax.plot([px1, px1], [y_top, y_bot], color='black', lw=2, zorder=1)
|
||||
|
||||
# Time arrow
|
||||
ax.annotate("", xy=(0, y_bot), xytext=(0, y_top - 0.5),
|
||||
arrowprops=dict(arrowstyle='->', color=MED_GRAY, lw=1.5))
|
||||
ax.text(0, 5.5, "czas", ha='center', va='center', fontsize=8,
|
||||
rotation=90, color=DARK_GRAY)
|
||||
|
||||
# Step 1: Both call Sendrecv
|
||||
y1 = 7.5
|
||||
draw_cell(ax, px0 - 1.5, y1 - 0.4, 3.0, 0.8, "Sendrecv\n(→P1, ←P1)",
|
||||
fill='white', fontsize=9, fontweight='bold')
|
||||
draw_cell(ax, px1 - 1.5, y1 - 0.4, 3.0, 0.8, "Sendrecv\n(→P0, ←P0)",
|
||||
fill='white', fontsize=9, fontweight='bold')
|
||||
|
||||
# Bidirectional arrows — simultaneous exchange
|
||||
draw_curvy_arrow(ax, px0 + 1.5, y1 + 0.15, px1 - 1.5, y1 + 0.15,
|
||||
connectionstyle="arc3,rad=0.12", lw=2)
|
||||
draw_curvy_arrow(ax, px1 - 1.5, y1 - 0.15, px0 + 1.5, y1 - 0.15,
|
||||
connectionstyle="arc3,rad=0.12", lw=2)
|
||||
ax.text(5.5, y1 + 0.9, "x[3] →", ha='center', fontsize=8)
|
||||
ax.text(5.5, y1 - 0.85, "← x[4]", ha='center', fontsize=8)
|
||||
|
||||
# Step 2: Both complete
|
||||
y2 = 5.0
|
||||
ax.text(5.5, y2 + 0.3, "Wymiana zakończona ✓", ha='center', fontsize=10,
|
||||
fontweight='bold',
|
||||
bbox=dict(boxstyle='round,pad=0.3', facecolor=VERY_LIGHT,
|
||||
edgecolor='black', lw=1.5))
|
||||
|
||||
# Step 3: Compute
|
||||
y3 = 3.5
|
||||
draw_cell(ax, px0 - 1.5, y3 - 0.4, 3.0, 0.8, "Oblicz x'[0..3]",
|
||||
fill='white', fontsize=9)
|
||||
draw_cell(ax, px1 - 1.5, y3 - 0.4, 3.0, 0.8, "Oblicz x'[4..7]",
|
||||
fill='white', fontsize=9)
|
||||
|
||||
# Step 4: Next iteration
|
||||
y4 = 2.0
|
||||
ax.text(5.5, y4, "→ Następna iteracja", ha='center', fontsize=9,
|
||||
style='italic', color=DARK_GRAY)
|
||||
|
||||
fig.tight_layout(rect=[0, 0, 1, 0.93])
|
||||
path = os.path.join(OUTPUT_DIR, 'q26_deadlock_vs_solution.png')
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG_COLOR)
|
||||
plt.close(fig)
|
||||
print(f" ✓ {path}")
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# 5. FULL JACOBI ITERATION — sequential pseudocode showing the dependency
|
||||
# =========================================================================
|
||||
def generate_jacobi_full_picture():
|
||||
fig, ax = plt.subplots(figsize=(12, 8))
|
||||
ax.set_xlim(-1, 16)
|
||||
ax.set_ylim(-5, 8)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_title("Równoległy Jacobi — pełny obraz jednej iteracji",
|
||||
fontsize=TITLE_SIZE, fontweight='bold', pad=15)
|
||||
|
||||
cw, ch = 1.0, 0.7
|
||||
|
||||
# === ROW 1: Old values (iteration k) ===
|
||||
y1 = 6.0
|
||||
ax.text(-0.8, y1 + ch/2, "Iteracja k\n(stare):", ha='right', va='center',
|
||||
fontsize=9, fontweight='bold')
|
||||
n = 12
|
||||
p_colors_cells = [VERY_LIGHT]*4 + [LIGHT_GRAY]*4 + ['#E8E8E8']*4
|
||||
for i in range(n):
|
||||
draw_cell(ax, i * cw, y1, cw, ch, f"x[{i}]", fill=p_colors_cells[i],
|
||||
fontsize=7)
|
||||
|
||||
# Process boundaries
|
||||
for bx in [4, 8]:
|
||||
ax.plot([bx, bx], [y1 - 0.3, y1 + ch + 0.3], color='black',
|
||||
lw=2.5, linestyle='--')
|
||||
|
||||
ax.text(2, y1 + ch + 0.5, "Proces 0", ha='center', fontsize=9, fontweight='bold')
|
||||
ax.text(6, y1 + ch + 0.5, "Proces 1", ha='center', fontsize=9, fontweight='bold')
|
||||
ax.text(10, y1 + ch + 0.5, "Proces 2", ha='center', fontsize=9, fontweight='bold')
|
||||
|
||||
# === STEP labels on the left ===
|
||||
# Step 1: Compute interior
|
||||
y2 = 3.5
|
||||
ax.text(6, y2 + 1.5, "Krok 1: Oblicz punkty wewnętrzne (bez ghost cells)",
|
||||
ha='center', fontsize=10, fontweight='bold')
|
||||
|
||||
ax.text(-0.8, y2 + ch/2, "Iteracja k+1\n(nowe):", ha='right', va='center',
|
||||
fontsize=9, fontweight='bold')
|
||||
|
||||
# Show computation arrows only for interior points
|
||||
for i in range(n):
|
||||
is_boundary = (i in [0, 3, 4, 7, 8, 11])
|
||||
if is_boundary:
|
||||
draw_cell(ax, i * cw, y2, cw, ch, "?",
|
||||
fill=MED_GRAY, fontsize=9, fontweight='bold')
|
||||
else:
|
||||
fill = p_colors_cells[i]
|
||||
draw_cell(ax, i * cw, y2, cw, ch, f"x'[{i}]", fill=fill, fontsize=7)
|
||||
# Show dependency arrows from old row
|
||||
draw_arrow(ax, (i-1)*cw + cw/2, y1, i*cw + cw/2, y2 + ch,
|
||||
color=DARK_GRAY, lw=0.8)
|
||||
draw_arrow(ax, (i+1)*cw + cw/2, y1, i*cw + cw/2, y2 + ch,
|
||||
color=DARK_GRAY, lw=0.8)
|
||||
|
||||
for bx in [4, 8]:
|
||||
ax.plot([bx, bx], [y2 - 0.3, y2 + ch + 0.3], color='black',
|
||||
lw=2.5, linestyle='--')
|
||||
|
||||
# Label boundary cells
|
||||
ax.annotate("granica\n(potrzebuje\nghost cell)", xy=(3.5, y2), xytext=(3.5, y2 - 1.5),
|
||||
fontsize=7, ha='center', va='top',
|
||||
arrowprops=dict(arrowstyle='->', color='black', lw=1))
|
||||
ax.annotate("granica\n(potrzebuje\nghost cell)", xy=(4.5, y2), xytext=(5.5, y2 - 1.5),
|
||||
fontsize=7, ha='center', va='top',
|
||||
arrowprops=dict(arrowstyle='->', color='black', lw=1))
|
||||
|
||||
# === Step 2: Exchange ghost cells ===
|
||||
y3 = -0.5
|
||||
ax.text(6, y3 + 2.0, "Krok 2: Wymień ghost cells → Krok 3: Oblicz punkty graniczne",
|
||||
ha='center', fontsize=10, fontweight='bold')
|
||||
|
||||
for i in range(n):
|
||||
fill = p_colors_cells[i]
|
||||
draw_cell(ax, i * cw, y3, cw, ch, f"x'[{i}]", fill=fill, fontsize=7)
|
||||
|
||||
for bx in [4, 8]:
|
||||
ax.plot([bx, bx], [y3 - 0.3, y3 + ch + 0.3], color='black',
|
||||
lw=2.5, linestyle='--')
|
||||
|
||||
# Show exchange arrows at boundaries
|
||||
draw_curvy_arrow(ax, 3.5, y3 + ch + 0.05, 4.5, y3 + ch + 0.05,
|
||||
connectionstyle="arc3,rad=-0.5", lw=1.5)
|
||||
draw_curvy_arrow(ax, 4.5, y3 - 0.05, 3.5, y3 - 0.05,
|
||||
connectionstyle="arc3,rad=-0.5", lw=1.5)
|
||||
|
||||
draw_curvy_arrow(ax, 7.5, y3 + ch + 0.05, 8.5, y3 + ch + 0.05,
|
||||
connectionstyle="arc3,rad=-0.5", lw=1.5)
|
||||
draw_curvy_arrow(ax, 8.5, y3 - 0.05, 7.5, y3 - 0.05,
|
||||
connectionstyle="arc3,rad=-0.5", lw=1.5)
|
||||
|
||||
# Summary
|
||||
ax.text(6, y3 - 1.5,
|
||||
"Powtarzaj Krok 1→2→3 aż do zbieżności (|x' - x| < ε)",
|
||||
ha='center', fontsize=10, style='italic',
|
||||
bbox=dict(boxstyle='round,pad=0.4', facecolor=VERY_LIGHT,
|
||||
edgecolor='black', lw=1))
|
||||
|
||||
# Pseudocode box
|
||||
pseudo = (
|
||||
"for iter = 1 to max_iter:\n"
|
||||
" oblicz x'[wewnętrzne] // nie wymaga ghost cells\n"
|
||||
" wymień ghost cells z sąsiadami // Send + Recv\n"
|
||||
" oblicz x'[graniczne] // teraz ghost cells dostępne\n"
|
||||
" if |x' - x| < ε: break\n"
|
||||
" x ← x'"
|
||||
)
|
||||
ax.text(6, -3.5, pseudo, ha='center', va='center', fontsize=8,
|
||||
family='monospace',
|
||||
bbox=dict(boxstyle='round,pad=0.5', facecolor='white',
|
||||
edgecolor='black', lw=1.5))
|
||||
|
||||
fig.tight_layout()
|
||||
path = os.path.join(OUTPUT_DIR, 'q26_jacobi_full_iteration.png')
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG_COLOR)
|
||||
plt.close(fig)
|
||||
print(f" ✓ {path}")
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# MAIN
|
||||
# =========================================================================
|
||||
if __name__ == '__main__':
|
||||
print("Generating Q26 Jacobi diagrams...")
|
||||
generate_jacobi_stencil()
|
||||
generate_domain_decomposition()
|
||||
generate_ghost_cell_exchange()
|
||||
generate_deadlock_vs_solution()
|
||||
generate_jacobi_full_picture()
|
||||
print("Done!")
|
||||
377
pytania/generate_q9_budowa_diagrams.py
Normal file
@ -0,0 +1,377 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate supplementary diagrams for PYTANIE 9 'Budowa procesu' and 'Budowa wątku'.
|
||||
Replaces ASCII art with monochrome A4-printable PNGs (300 DPI).
|
||||
"""
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as mpatches
|
||||
from matplotlib.patches import FancyBboxPatch
|
||||
import os
|
||||
|
||||
DPI = 300
|
||||
BG = 'white'
|
||||
LN = 'black'
|
||||
FS = 8
|
||||
FS_TITLE = 11
|
||||
FS_SMALL = 6.5
|
||||
FS_LABEL = 9
|
||||
OUTPUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'img')
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
GRAY1 = '#E8E8E8'
|
||||
GRAY2 = '#D0D0D0'
|
||||
GRAY3 = '#B8B8B8'
|
||||
GRAY4 = '#F5F5F5'
|
||||
GRAY5 = '#C0C0C0'
|
||||
|
||||
|
||||
def draw_box(ax, x, y, w, h, text, fill='white', lw=1.2, fontsize=FS,
|
||||
fontweight='normal', ha='center', va='center', rounded=True,
|
||||
edgecolor=LN, linestyle='-'):
|
||||
if rounded:
|
||||
rect = FancyBboxPatch((x, y), w, h, boxstyle="round,pad=0.05",
|
||||
lw=lw, edgecolor=edgecolor, facecolor=fill,
|
||||
linestyle=linestyle)
|
||||
else:
|
||||
rect = mpatches.Rectangle((x, y), w, h, lw=lw, edgecolor=edgecolor,
|
||||
facecolor=fill, linestyle=linestyle)
|
||||
ax.add_patch(rect)
|
||||
ax.text(x + w/2, y + h/2, text, ha=ha, va=va, fontsize=fontsize,
|
||||
fontweight=fontweight, wrap=True)
|
||||
|
||||
|
||||
def draw_arrow(ax, x1, y1, x2, y2, lw=1.2, style='->', color=LN):
|
||||
ax.annotate("", xy=(x2, y2), xytext=(x1, y1),
|
||||
arrowprops=dict(arrowstyle=style, color=color, lw=lw))
|
||||
|
||||
|
||||
def save_fig(fig, name):
|
||||
path = os.path.join(OUTPUT_DIR, name)
|
||||
fig.savefig(path, dpi=DPI, bbox_inches='tight', facecolor=BG, pad_inches=0.15)
|
||||
plt.close(fig)
|
||||
print(f" Saved: {path}")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 1. Memory layout with C code annotations
|
||||
# ============================================================
|
||||
def gen_memory_c_annotated():
|
||||
fig, ax = plt.subplots(figsize=(9, 5.5))
|
||||
ax.set_xlim(0, 12)
|
||||
ax.set_ylim(0, 8)
|
||||
ax.set_aspect('auto')
|
||||
ax.axis('off')
|
||||
ax.set_title('Segmenty pamięci procesu — mapowanie kodu C',
|
||||
fontsize=FS_TITLE, fontweight='bold', pad=10)
|
||||
|
||||
# Left side: memory segments stack
|
||||
seg_x = 1.0
|
||||
seg_w = 2.8
|
||||
seg_h = 0.95
|
||||
gap = 0.08
|
||||
|
||||
segments = [
|
||||
('STACK ↓', GRAY1, 'rośnie w dół'),
|
||||
('...', 'white', 'wolna przestrzeń'),
|
||||
('HEAP ↑', GRAY4, 'rośnie w górę'),
|
||||
('BSS', GRAY2, 'zerowane'),
|
||||
('DATA', GRAY3, 'zainicjalizowane'),
|
||||
('TEXT', GRAY5, 'read-only'),
|
||||
]
|
||||
|
||||
seg_positions = {}
|
||||
top_y = 7.0
|
||||
for i, (name, color, note) in enumerate(segments):
|
||||
y = top_y - i * (seg_h + gap)
|
||||
draw_box(ax, seg_x, y, seg_w, seg_h, name, fill=color,
|
||||
fontsize=FS_LABEL, fontweight='bold', rounded=False)
|
||||
ax.text(seg_x + seg_w + 0.15, y + seg_h / 2, note,
|
||||
fontsize=FS_SMALL, va='center', style='italic', color='#555')
|
||||
seg_positions[name.split()[0].replace('↓', '').replace('↑', '').strip()] = y + seg_h / 2
|
||||
|
||||
# Address labels
|
||||
ax.text(seg_x - 0.15, top_y + seg_h / 2, 'wysoki\nadres',
|
||||
fontsize=FS_SMALL, va='center', ha='right', style='italic')
|
||||
ax.text(seg_x - 0.15, seg_positions['TEXT'], 'niski\nadres',
|
||||
fontsize=FS_SMALL, va='center', ha='right', style='italic')
|
||||
|
||||
# Right side: C code with arrows pointing to segments
|
||||
code_x = 6.5
|
||||
code_lines = [
|
||||
('int global_init = 42;', 'DATA', '→ DATA'),
|
||||
('int global_uninit;', 'BSS', '→ BSS'),
|
||||
('', None, ''),
|
||||
('int main() {', 'TEXT', '→ TEXT'),
|
||||
(' int local = 10;', 'STACK', '→ STACK'),
|
||||
(' int *p = malloc(100);', 'HEAP', ' p → STACK\n 100B → HEAP'),
|
||||
(' free(p);', None, ''),
|
||||
(' return 0;', None, ''),
|
||||
('}', None, ''),
|
||||
]
|
||||
|
||||
# Code box background
|
||||
code_top = 7.2
|
||||
code_line_h = 0.55
|
||||
total_code_h = len(code_lines) * code_line_h + 0.3
|
||||
rect = mpatches.FancyBboxPatch((code_x - 0.3, code_top - total_code_h),
|
||||
5.5, total_code_h,
|
||||
boxstyle="round,pad=0.1",
|
||||
lw=1.2, edgecolor=GRAY3, facecolor=GRAY4)
|
||||
ax.add_patch(rect)
|
||||
ax.text(code_x + 2.2, code_top + 0.15, 'Kod C — przykład',
|
||||
fontsize=FS, fontweight='bold', ha='center')
|
||||
|
||||
for i, (line, seg, annotation) in enumerate(code_lines):
|
||||
y = code_top - (i + 1) * code_line_h
|
||||
ax.text(code_x, y, line, fontsize=7, va='center', family='monospace')
|
||||
|
||||
if seg and seg in seg_positions:
|
||||
# Draw arrow from annotation to segment
|
||||
ann_x = code_x + 4.0
|
||||
seg_y = seg_positions[seg]
|
||||
ax.text(ann_x, y, annotation.split('\n')[0], fontsize=FS_SMALL,
|
||||
va='center', fontweight='bold', color='#333')
|
||||
# Connecting line (dashed)
|
||||
ax.plot([seg_x + seg_w, ann_x - 0.1], [seg_y, y],
|
||||
linestyle=':', color=GRAY3, lw=0.8)
|
||||
|
||||
save_fig(fig, 'q9_memory_c_annotated.png')
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 2. PCB detailed with concrete values
|
||||
# ============================================================
|
||||
def gen_pcb_detailed():
|
||||
fig, ax = plt.subplots(figsize=(7, 4.5))
|
||||
ax.set_xlim(0, 10)
|
||||
ax.set_ylim(0, 7)
|
||||
ax.set_aspect('auto')
|
||||
ax.axis('off')
|
||||
ax.set_title('PCB (Process Control Block) — dowód osobisty procesu',
|
||||
fontsize=FS_TITLE, fontweight='bold', pad=10)
|
||||
|
||||
# PCB outer box
|
||||
pcb_x, pcb_y, pcb_w, pcb_h = 1.0, 0.8, 8.0, 5.5
|
||||
rect = mpatches.FancyBboxPatch((pcb_x, pcb_y), pcb_w, pcb_h,
|
||||
boxstyle="round,pad=0.15",
|
||||
lw=2, edgecolor=LN, facecolor='white')
|
||||
ax.add_patch(rect)
|
||||
ax.text(pcb_x + pcb_w / 2, pcb_y + pcb_h + 0.15, 'PCB procesu PID=1234',
|
||||
fontsize=FS_LABEL, fontweight='bold', ha='center')
|
||||
|
||||
fields = [
|
||||
('PID', '1234', 'identyfikator procesu'),
|
||||
('Stan', 'RUNNING', 'aktualny stan wykonania'),
|
||||
('PC', '0x004015A0', 'następna instrukcja do wykonania'),
|
||||
('Rejestry CPU', 'EAX=5, EBX=0, ESP=...', 'stan procesora'),
|
||||
('Tablice stron', '[strona→ramka]', 'mapowanie pamięci wirtualnej'),
|
||||
('Otwarte pliki', 'fd0, fd1, fd2, ...', 'deskryptory plików'),
|
||||
('Priorytet', '20 (nice)', 'klasa schedulingu'),
|
||||
('Czas CPU', '1.34 s', 'accounting / statystyki'),
|
||||
]
|
||||
|
||||
row_h = 0.55
|
||||
top_y = pcb_y + pcb_h - 0.4
|
||||
field_w = 2.3
|
||||
val_w = 3.0
|
||||
desc_x = pcb_x + field_w + val_w + 0.6
|
||||
|
||||
for i, (field, value, desc) in enumerate(fields):
|
||||
y = top_y - i * (row_h + 0.05)
|
||||
# Field name box
|
||||
draw_box(ax, pcb_x + 0.3, y, field_w, row_h, field,
|
||||
fill=GRAY2, fontsize=FS, fontweight='bold', rounded=False)
|
||||
# Value box
|
||||
draw_box(ax, pcb_x + 0.3 + field_w, y, val_w, row_h, value,
|
||||
fill=GRAY4, fontsize=7.5, rounded=False)
|
||||
# Description
|
||||
ax.text(desc_x, y + row_h / 2, desc,
|
||||
fontsize=FS_SMALL, va='center', style='italic', color='#555')
|
||||
|
||||
# Bottom note
|
||||
ax.text(5.0, 0.35, 'Context switch = zapisz PCB starego procesu → wczytaj PCB nowego',
|
||||
fontsize=FS, ha='center', style='italic',
|
||||
bbox=dict(boxstyle='round,pad=0.25', facecolor=GRAY4, edgecolor=GRAY3))
|
||||
|
||||
save_fig(fig, 'q9_pcb_detailed.png')
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 3. Process states with ALL transition labels
|
||||
# ============================================================
|
||||
def gen_process_states_labeled():
|
||||
fig, ax = plt.subplots(figsize=(8, 4.5))
|
||||
ax.set_xlim(0, 13)
|
||||
ax.set_ylim(-0.5, 6)
|
||||
ax.set_aspect('auto')
|
||||
ax.axis('off')
|
||||
ax.set_title('Stany procesu — diagram przejść z opisami',
|
||||
fontsize=FS_TITLE, fontweight='bold', pad=10)
|
||||
|
||||
states = {
|
||||
'NEW': (0.8, 3.0),
|
||||
'READY': (3.8, 3.0),
|
||||
'RUNNING': (7.3, 3.0),
|
||||
'BLOCKED': (7.3, 0.5),
|
||||
'TERMINATED': (11.0, 3.0),
|
||||
}
|
||||
fills = {
|
||||
'NEW': GRAY4, 'READY': GRAY1, 'RUNNING': GRAY3,
|
||||
'BLOCKED': GRAY2, 'TERMINATED': GRAY5,
|
||||
}
|
||||
bw, bh = 2.0, 1.0
|
||||
|
||||
for name, (x, y) in states.items():
|
||||
draw_box(ax, x, y, bw, bh, name, fill=fills[name], fontsize=FS_LABEL,
|
||||
fontweight='bold')
|
||||
|
||||
# Transition: NEW → READY
|
||||
sx, sy = states['NEW']
|
||||
dx, dy = states['READY']
|
||||
draw_arrow(ax, sx + bw, sy + bh/2, dx, dy + bh/2, lw=1.5)
|
||||
ax.text((sx + bw + dx) / 2, sy + bh/2 + 0.2, 'admit\n(utworzony)',
|
||||
fontsize=FS_SMALL, ha='center', va='bottom')
|
||||
|
||||
# Transition: READY → RUNNING (dispatch)
|
||||
sx, sy = states['READY']
|
||||
dx, dy = states['RUNNING']
|
||||
draw_arrow(ax, sx + bw, sy + bh * 0.65, dx, dy + bh * 0.65, lw=1.5)
|
||||
ax.text((sx + bw + dx) / 2, sy + bh * 0.65 + 0.2, 'dispatch\n(scheduler → CPU)',
|
||||
fontsize=FS_SMALL, ha='center', va='bottom')
|
||||
|
||||
# Transition: RUNNING → READY (preemption)
|
||||
draw_arrow(ax, dx, dy + bh * 0.35, sx + bw, sy + bh * 0.35, lw=1.5)
|
||||
ax.text((sx + bw + dx) / 2, sy + bh * 0.35 - 0.15, 'preempt\n(kwant czasu)',
|
||||
fontsize=FS_SMALL, ha='center', va='top')
|
||||
|
||||
# Transition: RUNNING → TERMINATED
|
||||
sx, sy = states['RUNNING']
|
||||
dx, dy = states['TERMINATED']
|
||||
draw_arrow(ax, sx + bw, sy + bh/2, dx, dy + bh/2, lw=1.5)
|
||||
ax.text((sx + bw + dx) / 2, sy + bh/2 + 0.2, 'exit()',
|
||||
fontsize=FS_SMALL, ha='center', va='bottom')
|
||||
|
||||
# Transition: RUNNING → BLOCKED
|
||||
sx, sy = states['RUNNING']
|
||||
dx, dy = states['BLOCKED']
|
||||
draw_arrow(ax, sx + bw/2, sy, dx + bw/2, dy + bh, lw=1.5)
|
||||
ax.text(sx + bw + 0.2, (sy + dy + bh) / 2, 'I/O wait\n(np. read z dysku)',
|
||||
fontsize=FS_SMALL, ha='left', va='center')
|
||||
|
||||
# Transition: BLOCKED → READY
|
||||
bx, by = states['BLOCKED']
|
||||
rx, ry = states['READY']
|
||||
ax.annotate("", xy=(rx + bw/2, ry), xytext=(bx, by + bh/2),
|
||||
arrowprops=dict(arrowstyle='->', lw=1.5, color=LN,
|
||||
connectionstyle='arc3,rad=0.35'))
|
||||
ax.text(4.0, 1.0, 'I/O done\n(powrót do kolejki)',
|
||||
fontsize=FS_SMALL, ha='center')
|
||||
|
||||
# Legend at bottom
|
||||
legend_items = [
|
||||
'NEW → READY: proces utworzony, gotowy',
|
||||
'READY → RUNNING: scheduler przydziela CPU',
|
||||
'RUNNING → READY: upłynął kwant czasu (preemption)',
|
||||
'RUNNING → BLOCKED: czeka na I/O',
|
||||
'BLOCKED → READY: I/O zakończone',
|
||||
'RUNNING → TERMINATED: proces kończy się',
|
||||
]
|
||||
for i, item in enumerate(legend_items):
|
||||
col = i // 3
|
||||
row = i % 3
|
||||
ax.text(0.5 + col * 6.5, -0.1 - row * 0.35, f'• {item}',
|
||||
fontsize=FS_SMALL, va='center')
|
||||
|
||||
save_fig(fig, 'q9_process_states_labeled.png')
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 4. Thread shared vs private — annotated diagram
|
||||
# ============================================================
|
||||
def gen_thread_shared_private():
|
||||
fig, ax = plt.subplots(figsize=(9, 5.5))
|
||||
ax.set_xlim(0, 12)
|
||||
ax.set_ylim(0, 8)
|
||||
ax.set_aspect('auto')
|
||||
ax.axis('off')
|
||||
ax.set_title('Wątki wewnątrz procesu — współdzielone vs prywatne',
|
||||
fontsize=FS_TITLE, fontweight='bold', pad=10)
|
||||
|
||||
# Outer process box
|
||||
proc_rect = mpatches.FancyBboxPatch((0.5, 0.3), 11.0, 7.0,
|
||||
boxstyle="round,pad=0.15",
|
||||
lw=2.5, edgecolor=LN, facecolor='white')
|
||||
ax.add_patch(proc_rect)
|
||||
ax.text(6.0, 7.55, 'PROCES (PID = 1234)', fontsize=FS_LABEL,
|
||||
fontweight='bold', ha='center')
|
||||
|
||||
# Shared region (top)
|
||||
shared_rect = mpatches.Rectangle((1.0, 4.5), 10.0, 2.5,
|
||||
lw=1.5, edgecolor=LN, facecolor=GRAY1)
|
||||
ax.add_patch(shared_rect)
|
||||
ax.text(6.0, 6.75, 'WSPÓŁDZIELONE (wszystkie wątki widzą to samo)',
|
||||
fontsize=FS, fontweight='bold', ha='center')
|
||||
|
||||
shared_items = [
|
||||
('TEXT', 'kod programu'),
|
||||
('DATA', 'zm. globalne\nzainicjalizowane'),
|
||||
('BSS', 'zm. globalne\nniezainicjalizowane'),
|
||||
('HEAP', 'malloc/new\n(dynamiczna)'),
|
||||
('Pliki', 'deskryptory\nfd[0..n]'),
|
||||
('PID', 'identyfikator\nprocesu'),
|
||||
]
|
||||
for i, (name, desc) in enumerate(shared_items):
|
||||
x = 1.4 + i * 1.6
|
||||
draw_box(ax, x, 4.7, 1.3, 0.7, name, fill=GRAY3,
|
||||
fontsize=FS, fontweight='bold', rounded=False)
|
||||
ax.text(x + 0.65, 5.6, desc, fontsize=5.5, ha='center', va='center')
|
||||
|
||||
# Private region (bottom) — 3 threads
|
||||
private_rect = mpatches.Rectangle((1.0, 0.6), 10.0, 3.5,
|
||||
lw=1.5, edgecolor=LN, facecolor='white',
|
||||
linestyle='--')
|
||||
ax.add_patch(private_rect)
|
||||
ax.text(6.0, 3.85, 'PRYWATNE (każdy wątek ma WŁASNE)',
|
||||
fontsize=FS, fontweight='bold', ha='center')
|
||||
|
||||
thread_colors = [GRAY4, '#E0E0E0', GRAY4]
|
||||
for t in range(3):
|
||||
tx = 1.5 + t * 3.3
|
||||
tw = 2.8
|
||||
thread_rect = mpatches.FancyBboxPatch((tx, 0.8), tw, 2.7,
|
||||
boxstyle="round,pad=0.1",
|
||||
lw=1.5, edgecolor=LN,
|
||||
facecolor=thread_colors[t])
|
||||
ax.add_patch(thread_rect)
|
||||
tid = t + 1
|
||||
ax.text(tx + tw/2, 3.25, f'Wątek {tid} (TID={40+tid})',
|
||||
fontsize=FS, fontweight='bold', ha='center')
|
||||
|
||||
private_items = [
|
||||
(f'Stos_{tid}', 'zmienne lokalne'),
|
||||
(f'Rejestry_{tid}', 'EAX, EBX, ESP...'),
|
||||
(f'PC_{tid}', 'pozycja w kodzie'),
|
||||
]
|
||||
for j, (name, desc) in enumerate(private_items):
|
||||
y = 2.65 - j * 0.6
|
||||
draw_box(ax, tx + 0.15, y, tw - 0.3, 0.45, f'{name}',
|
||||
fill='white', fontsize=7, fontweight='bold', rounded=False)
|
||||
ax.text(tx + tw/2, y - 0.1, desc, fontsize=5.5, ha='center',
|
||||
va='top', color='#555')
|
||||
|
||||
save_fig(fig, 'q9_thread_shared_private.png')
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MAIN
|
||||
# ============================================================
|
||||
if __name__ == '__main__':
|
||||
print("Generating supplementary PYTANIE 9 'Budowa' diagrams...")
|
||||
gen_memory_c_annotated()
|
||||
gen_pcb_detailed()
|
||||
gen_process_states_labeled()
|
||||
gen_thread_shared_private()
|
||||
print("\nAll 4 supplementary diagrams generated!")
|
||||
696
pytania/generate_thesis_bridge_diagrams.py
Normal file
@ -0,0 +1,696 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate thesis-bridge diagrams for exam questions.
|
||||
Shows how exam concepts connect to the master's thesis
|
||||
(Unity vs Unreal game engine comparison).
|
||||
|
||||
All: A4-compatible, B&W, 300 DPI, laser-printer-friendly.
|
||||
"""
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as mpatches
|
||||
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
DPI = 300
|
||||
BG = 'white'
|
||||
LN = 'black'
|
||||
FS = 9
|
||||
FS_TITLE = 13
|
||||
FS_SMALL = 7.5
|
||||
FS_TINY = 6.5
|
||||
OUTPUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'img')
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
GRAY1 = '#E8E8E8'
|
||||
GRAY2 = '#D0D0D0'
|
||||
GRAY3 = '#B8B8B8'
|
||||
GRAY4 = '#F5F5F5'
|
||||
GRAY5 = '#C0C0C0'
|
||||
WHITE = 'white'
|
||||
|
||||
|
||||
def draw_box(ax, x, y, w, h, text, fill='white', lw=1.2, fontsize=FS,
|
||||
fontweight='normal', ha='center', va='center', rounded=True):
|
||||
if rounded:
|
||||
rect = FancyBboxPatch((x, y), w, h, boxstyle="round,pad=0.08",
|
||||
lw=lw, edgecolor=LN, facecolor=fill)
|
||||
else:
|
||||
rect = mpatches.FancyBboxPatch((x, y), w, h, boxstyle="square,pad=0",
|
||||
lw=lw, edgecolor=LN, facecolor=fill)
|
||||
ax.add_patch(rect)
|
||||
ax.text(x + w/2, y + h/2, text, ha=ha, va=va, fontsize=fontsize,
|
||||
fontweight=fontweight, wrap=True,
|
||||
bbox=dict(facecolor='none', edgecolor='none', pad=0))
|
||||
return rect
|
||||
|
||||
|
||||
def arrow(ax, x1, y1, x2, y2, style='->', lw=1.2, color=LN):
|
||||
ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
|
||||
arrowprops=dict(arrowstyle=style, lw=lw, color=color))
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 1: Game Engine Thread Architecture (for Q9)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_game_engine_threads():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(8, 5.5), dpi=DPI)
|
||||
ax.set_xlim(0, 10)
|
||||
ax.set_ylim(0, 7)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(5, 6.7, 'Wątki w silniku gier — Game Loop Architecture',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
# Main Game Loop box
|
||||
draw_box(ax, 0.3, 5.0, 9.4, 1.3, '', fill=GRAY4, lw=2)
|
||||
ax.text(5, 6.0, 'GAME LOOP (Main Thread)', ha='center',
|
||||
fontsize=FS, fontweight='bold')
|
||||
ax.text(5, 5.45, 'Input → Update → Physics → Render → Present (every frame)',
|
||||
ha='center', fontsize=FS_SMALL)
|
||||
|
||||
# Sub-threads
|
||||
threads = [
|
||||
(0.5, 3.2, 2.0, 1.4, 'Render\nThread', GRAY1,
|
||||
'GPU commands\nDraw calls\nShader dispatch'),
|
||||
(2.8, 3.2, 2.0, 1.4, 'Physics\nThread', GRAY2,
|
||||
'Collision detection\nRigidbody sim\nRaycast'),
|
||||
(5.1, 3.2, 2.0, 1.4, 'Audio\nThread', GRAY1,
|
||||
'Sound mixing\nDSP effects\n3D spatialization'),
|
||||
(7.4, 3.2, 2.0, 1.4, 'Worker Pool\n(Job System)', GRAY2,
|
||||
'AI pathfinding\nAnimation\nAsset loading'),
|
||||
]
|
||||
|
||||
for x, y, w, h, label, fill, detail in threads:
|
||||
draw_box(ax, x, y, w, h, '', fill=fill)
|
||||
ax.text(x + w/2, y + h - 0.3, label, ha='center', fontsize=FS,
|
||||
fontweight='bold')
|
||||
ax.text(x + w/2, y + 0.3, detail, ha='center', fontsize=FS_TINY,
|
||||
color='#333333')
|
||||
arrow(ax, x + w/2, 5.0, x + w/2, y + h, '->', lw=1.0)
|
||||
|
||||
# Engine comparison
|
||||
draw_box(ax, 0.3, 0.5, 4.3, 2.3, '', fill=WHITE, lw=1.5)
|
||||
ax.text(2.45, 2.5, 'UNITY', ha='center', fontsize=FS, fontweight='bold')
|
||||
ax.text(2.45, 2.0, 'C# + Job System (DOTS)', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(2.45, 1.6, 'Main thread: MonoBehaviour', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(2.45, 1.2, 'Workers: Burst Compiler', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(2.45, 0.8, 'GC pauses freeze main thread!', ha='center',
|
||||
fontsize=FS_SMALL, fontweight='bold', style='italic')
|
||||
|
||||
draw_box(ax, 5.4, 0.5, 4.3, 2.3, '', fill=WHITE, lw=1.5)
|
||||
ax.text(7.55, 2.5, 'UNREAL ENGINE', ha='center', fontsize=FS, fontweight='bold')
|
||||
ax.text(7.55, 2.0, 'C++ + TaskGraph', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(7.55, 1.6, 'GameThread + RenderThread', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(7.55, 1.2, 'Parallel rendering pipeline', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(7.55, 0.8, 'No GC — deterministic timing', ha='center',
|
||||
fontsize=FS_SMALL, fontweight='bold', style='italic')
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q9_game_engine_threads.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 2: Memory Management — Unity GC vs Unreal Manual (Q10)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_memory_gc_vs_manual():
|
||||
fig, axes = plt.subplots(1, 2, figsize=(10, 5), dpi=DPI)
|
||||
fig.patch.set_facecolor(BG)
|
||||
fig.suptitle('Zarządzanie pamięcią w silnikach gier — GC vs Manual',
|
||||
fontsize=FS_TITLE, fontweight='bold', y=0.98)
|
||||
|
||||
# Left: Unity GC
|
||||
ax = axes[0]
|
||||
ax.set_xlim(0, 10)
|
||||
ax.set_ylim(0, 10)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title('Unity (C# — Garbage Collector)', fontsize=FS, fontweight='bold', pad=10)
|
||||
|
||||
# Heap visualization
|
||||
colors = [GRAY1, GRAY3, GRAY1, WHITE, GRAY3, GRAY1, WHITE, GRAY3, GRAY1, WHITE]
|
||||
labels = ['Obj', 'Bullet', 'Obj', 'FREE', 'Enemy', 'Obj', 'FREE', 'Bullet', 'Obj', 'FREE']
|
||||
for i, (c, l) in enumerate(zip(colors, labels)):
|
||||
y = 8.5 - i * 0.7
|
||||
draw_box(ax, 1, y, 5, 0.6, l, fill=c, fontsize=FS_SMALL)
|
||||
|
||||
ax.text(0.5, 9.3, 'MANAGED HEAP', ha='left', fontsize=FS, fontweight='bold')
|
||||
ax.text(7, 9.0, 'Problem:', ha='left', fontsize=FS, fontweight='bold')
|
||||
ax.text(7, 8.4, '• GC pause (stop-the-world)', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 7.9, '• Fragmentacja heapa', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 7.4, '• Spike\'y w frame time', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 6.6, 'Rozwiązanie:', ha='left', fontsize=FS, fontweight='bold')
|
||||
ax.text(7, 6.0, '• Object Pooling!', ha='left', fontsize=FS_TINY,
|
||||
fontweight='bold')
|
||||
ax.text(7, 5.5, ' (BulletPool.cs)', ha='left', fontsize=FS_TINY,
|
||||
style='italic')
|
||||
ax.text(7, 5.0, '• Unikaj new w Update()', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 4.5, '• Incremental GC (2019+)', ha='left', fontsize=FS_TINY)
|
||||
|
||||
# GC arrow
|
||||
ax.annotate('GC\nPAUSE', xy=(3.5, 2.5), fontsize=FS,
|
||||
fontweight='bold', ha='center', color='black',
|
||||
bbox=dict(boxstyle='round,pad=0.3', facecolor=GRAY3))
|
||||
|
||||
# Right: Unreal Manual
|
||||
ax = axes[1]
|
||||
ax.set_xlim(0, 10)
|
||||
ax.set_ylim(0, 10)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title('Unreal Engine (C++ — Manual / Smart Pointers)', fontsize=FS, fontweight='bold', pad=10)
|
||||
|
||||
# Memory blocks - organized
|
||||
segments = [
|
||||
(8.5, 'TSharedPtr<T>', GRAY1, 'Reference-counted'),
|
||||
(7.5, 'TUniquePtr<T>', GRAY2, 'Exclusive ownership'),
|
||||
(6.5, 'TWeakPtr<T>', GRAY1, 'Non-owning observer'),
|
||||
(5.5, 'FMemory::Malloc', GRAY3, 'Raw allocation'),
|
||||
(4.5, 'UObject (GC)', GRAY2, 'Reflected objects'),
|
||||
]
|
||||
|
||||
ax.text(0.5, 9.3, 'MEMORY MODEL', ha='left', fontsize=FS, fontweight='bold')
|
||||
for y, label, fill, desc in segments:
|
||||
draw_box(ax, 1, y, 3.5, 0.7, label, fill=fill, fontsize=FS_SMALL,
|
||||
fontweight='bold')
|
||||
ax.text(5, y + 0.35, f'← {desc}', ha='left', fontsize=FS_TINY, va='center')
|
||||
|
||||
ax.text(7, 9.0, 'Zalety:', ha='left', fontsize=FS, fontweight='bold')
|
||||
ax.text(7, 8.4, '• Deterministic destruction', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 7.9, '• Brak GC pauses', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 7.4, '• Custom allocators', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 6.6, 'Cena:', ha='left', fontsize=FS, fontweight='bold')
|
||||
ax.text(7, 6.0, '• Manual lifecycle mgmt', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 5.5, '• Use-after-free risk', ha='left', fontsize=FS_TINY)
|
||||
ax.text(7, 5.0, '• Memory leaks possible', ha='left', fontsize=FS_TINY)
|
||||
|
||||
fig.tight_layout(rect=[0, 0, 1, 0.94])
|
||||
out = os.path.join(OUTPUT_DIR, 'q10_gc_vs_manual_memory.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 3: Object Pooling — BulletPool pattern (Q10)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_object_pooling():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(9, 4.5), dpi=DPI)
|
||||
ax.set_xlim(0, 12)
|
||||
ax.set_ylim(0, 6)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(6, 5.7, 'Object Pooling — eliminacja alokacji w runtime',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
# WITHOUT pool
|
||||
draw_box(ax, 0.2, 3.2, 5.4, 2.2, '', fill=GRAY4, lw=1.5)
|
||||
ax.text(2.9, 5.0, 'BEZ POOLINGU', ha='center', fontsize=FS, fontweight='bold')
|
||||
ax.text(2.9, 4.5, 'Spawn() → new Bullet() [ALLOC]', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(2.9, 4.1, 'Despawn() → Destroy() [FREE → GC]', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(2.9, 3.6, '1000 bullets × 60 fps = 60k alloc/s', ha='center',
|
||||
fontsize=FS_SMALL, fontweight='bold', color='#333333')
|
||||
|
||||
# WITH pool
|
||||
draw_box(ax, 6.4, 3.2, 5.4, 2.2, '', fill=WHITE, lw=1.5)
|
||||
ax.text(9.1, 5.0, 'Z OBJECT POOL', ha='center', fontsize=FS, fontweight='bold')
|
||||
ax.text(9.1, 4.5, 'Spawn() → pool.Get() [REUSE]', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(9.1, 4.1, 'Despawn() → pool.Return() [RECYCLE]', ha='center', fontsize=FS_SMALL)
|
||||
ax.text(9.1, 3.6, '0 alloc/s w steady state', ha='center',
|
||||
fontsize=FS_SMALL, fontweight='bold', color='#333333')
|
||||
|
||||
# Pool visualization
|
||||
draw_box(ax, 2.5, 0.5, 7, 2.2, '', fill=GRAY1, lw=1.5)
|
||||
ax.text(6, 2.3, 'BulletPool (pre-allocated)', ha='center', fontsize=FS, fontweight='bold')
|
||||
|
||||
pool_states = ['ACTIVE', 'ACTIVE', 'IDLE', 'IDLE', 'ACTIVE', 'IDLE', 'ACTIVE', 'IDLE']
|
||||
for i, state in enumerate(pool_states):
|
||||
x = 3.0 + i * 0.75
|
||||
fill = GRAY3 if state == 'ACTIVE' else WHITE
|
||||
draw_box(ax, x, 0.8, 0.6, 0.6, '', fill=fill, fontsize=FS_TINY)
|
||||
ax.text(x + 0.3, 1.6, state[0], ha='center', fontsize=FS_TINY,
|
||||
fontweight='bold')
|
||||
|
||||
ax.text(10.3, 1.1, 'A = Active\nI = Idle', ha='left', fontsize=FS_TINY)
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q10_object_pooling.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 4: OOP Composition in game engines (Q6)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_component_pattern():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(9, 6), dpi=DPI)
|
||||
ax.set_xlim(0, 12)
|
||||
ax.set_ylim(0, 8)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(6, 7.7, 'Composition over Inheritance — Component Pattern w silnikach gier',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
# LEFT: Inheritance (bad)
|
||||
draw_box(ax, 0.3, 5.0, 5.0, 2.3, '', fill=GRAY4, lw=1.5)
|
||||
ax.text(2.8, 6.9, '[X] Dziedziczenie — kruche', ha='center',
|
||||
fontsize=FS, fontweight='bold')
|
||||
hierarchy = [
|
||||
(1.5, 6.2, 'GameObject'),
|
||||
(0.5, 5.5, 'Enemy'),
|
||||
(2.5, 5.5, 'FlyingEnemy'),
|
||||
(3.8, 5.5, 'ShootingFlyingEnemy??'),
|
||||
]
|
||||
for x, y, label in hierarchy:
|
||||
draw_box(ax, x, y, 1.8 if '??' not in label else 2.5,
|
||||
0.5, label, fill=WHITE, fontsize=FS_TINY)
|
||||
|
||||
arrow(ax, 1.4, 5.75, 2.4, 6.2, '->', lw=0.8)
|
||||
arrow(ax, 3.4, 5.75, 2.9, 6.2, '->', lw=0.8)
|
||||
|
||||
# RIGHT: Composition (good)
|
||||
draw_box(ax, 6.5, 3.7, 5.2, 3.8, '', fill=WHITE, lw=1.5)
|
||||
ax.text(9.1, 7.1, '[OK] Kompozycja — Component Pattern', ha='center',
|
||||
fontsize=FS, fontweight='bold')
|
||||
|
||||
# Entity
|
||||
draw_box(ax, 7.5, 6.0, 3.2, 0.7, 'GameObject / AActor', fill=GRAY1,
|
||||
fontsize=FS_SMALL, fontweight='bold')
|
||||
|
||||
# Components
|
||||
comps = [
|
||||
(6.8, 5.0, 'Transform'),
|
||||
(8.4, 5.0, 'SpriteRenderer'),
|
||||
(6.8, 4.3, 'Health'),
|
||||
(8.4, 4.3, 'BulletSpawner'),
|
||||
(6.8, 3.6, 'EnemyAI'),
|
||||
(8.4, 3.6, 'Collider2D'),
|
||||
]
|
||||
for x, y, label in comps:
|
||||
draw_box(ax, x, y + 0.1, 1.5, 0.45, label, fill=GRAY2, fontsize=FS_TINY)
|
||||
arrow(ax, x + 0.75, y + 0.55, 9.1, 6.0, '->', lw=0.5, color='#666666')
|
||||
|
||||
# Comparison table
|
||||
draw_box(ax, 0.3, 0.3, 11.4, 3.0, '', fill=GRAY4, lw=1.0)
|
||||
ax.text(6, 3.0, 'Unity vs Unreal — mechanizmy reużywalności', ha='center',
|
||||
fontsize=FS, fontweight='bold')
|
||||
|
||||
table_data = [
|
||||
('Mechanizm', 'Unity (C#)', 'Unreal (C++)'),
|
||||
('Kompozycja', 'MonoBehaviour + GetComponent<T>()', 'UActorComponent'),
|
||||
('Generics', 'List<T>, Dictionary<K,V>', 'TArray<T>, TMap<K,V>'),
|
||||
('Interfejsy', 'interface IDamageable', 'UInterface'),
|
||||
('Wzorce', 'Singleton, Observer (events)', 'Singleton, Delegate'),
|
||||
('Pool', 'ObjectPool<T> / custom', 'FPooledObject / custom'),
|
||||
]
|
||||
|
||||
for i, (mech, unity_col, unreal_col) in enumerate(table_data):
|
||||
y_row = 2.55 - i * 0.4
|
||||
weight = 'bold' if i == 0 else 'normal'
|
||||
ax.text(1.8, y_row, mech, ha='center', fontsize=FS_TINY, fontweight=weight)
|
||||
ax.text(5.5, y_row, unity_col, ha='center', fontsize=FS_TINY, fontweight=weight)
|
||||
ax.text(9.5, y_row, unreal_col, ha='center', fontsize=FS_TINY, fontweight=weight)
|
||||
|
||||
# Column separator lines
|
||||
ax.plot([3.5, 3.5], [0.5, 2.8], color=LN, lw=0.5, ls='--')
|
||||
ax.plot([7.5, 7.5], [0.5, 2.8], color=LN, lw=0.5, ls='--')
|
||||
ax.plot([0.5, 11.5], [2.3, 2.3], color=LN, lw=0.5)
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q6_component_pattern_engines.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 5: STL vs Unreal Containers (Q5)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_stl_vs_unreal():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(9, 5), dpi=DPI)
|
||||
ax.set_xlim(0, 12)
|
||||
ax.set_ylim(0, 7)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(6, 6.7, 'STL vs Unreal Engine Containers — porównanie',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
# Table
|
||||
rows = [
|
||||
('Kategoria', 'C++ STL', 'Unreal Engine (C++)', 'Dlaczego UE zmienił?'),
|
||||
('Tablica dynamiczna', 'std::vector<T>', 'TArray<T>', 'Custom allocator, reflection'),
|
||||
('Hash map', 'std::unordered_map', 'TMap<K,V>', 'Gameplay serialization'),
|
||||
('Hash set', 'std::unordered_set', 'TSet<T>', 'UPROPERTY support'),
|
||||
('String', 'std::string', 'FString / FName / FText', 'FName: hashed, immutable (IDs)'),
|
||||
('Smart pointer', 'shared_ptr<T>', 'TSharedPtr<T>', 'Thread-safe by default'),
|
||||
('Optional', 'std::optional<T>', 'TOptional<T>', 'UE coding standard'),
|
||||
('Iteratory', 'begin()/end()', 'begin()/end() (compatible)', 'Range-based for works'),
|
||||
('Algorytmy', '<algorithm>', 'Algo:: namespace', 'Reduced header bloat'),
|
||||
]
|
||||
|
||||
y_start = 6.1
|
||||
row_h = 0.55
|
||||
col_x = [0.3, 2.5, 5.0, 7.5, 10.8]
|
||||
|
||||
for i, (cat, stl, ue, why) in enumerate(rows):
|
||||
y = y_start - i * row_h
|
||||
fill = GRAY2 if i == 0 else (GRAY4 if i % 2 == 0 else WHITE)
|
||||
draw_box(ax, 0.2, y - 0.05, 11.6, row_h - 0.05, '', fill=fill,
|
||||
lw=0.5, rounded=False)
|
||||
weight = 'bold' if i == 0 else 'normal'
|
||||
ax.text(col_x[0], y + row_h/2 - 0.05, cat, ha='left', fontsize=FS_TINY,
|
||||
fontweight=weight)
|
||||
ax.text(col_x[1], y + row_h/2 - 0.05, stl, ha='left', fontsize=FS_TINY,
|
||||
fontweight=weight, family='monospace' if i > 0 else 'sans-serif')
|
||||
ax.text(col_x[2], y + row_h/2 - 0.05, ue, ha='left', fontsize=FS_TINY,
|
||||
fontweight=weight, family='monospace' if i > 0 else 'sans-serif')
|
||||
ax.text(col_x[3], y + row_h/2 - 0.05, why, ha='left', fontsize=FS_TINY,
|
||||
fontweight=weight)
|
||||
|
||||
# Bottom note
|
||||
ax.text(6, 0.6, 'Kluczowy wniosek: Unreal NIE używa STL — ma własne kontenery z identycznym API\n'
|
||||
'ale dodatkowym wsparciem dla refleksji (UPROPERTY), serializacji i GC obiektów UObject.',
|
||||
ha='center', fontsize=FS_SMALL, style='italic',
|
||||
bbox=dict(boxstyle='round,pad=0.4', facecolor=GRAY4, edgecolor=LN, lw=0.8))
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q5_stl_vs_unreal.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 6: Amdahl in Game Engine Rendering Pipeline (Q25)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_amdahl_game_pipeline():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(10, 5.5), dpi=DPI)
|
||||
ax.set_xlim(0, 13)
|
||||
ax.set_ylim(0, 7.5)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(6.5, 7.2, 'Prawo Amdahla w silniku gier — co można zrównoleglić?',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
# Pipeline stages — frame budget
|
||||
stages = [
|
||||
('Input\n(seq)', 0.5, WHITE, True),
|
||||
('Game Logic\n(seq)', 2.0, GRAY1, True),
|
||||
('Physics\n(parallel)', 2.0, GRAY3, False),
|
||||
('Animation\n(parallel)', 1.5, GRAY3, False),
|
||||
('Culling\n(parallel)', 1.0, GRAY3, False),
|
||||
('Rendering\n(parallel)', 3.0, GRAY3, False),
|
||||
('Post-process\n(GPU)', 1.5, GRAY2, False),
|
||||
('Present\n(seq)', 0.5, WHITE, True),
|
||||
]
|
||||
|
||||
x = 0.3
|
||||
y = 5.0
|
||||
h = 1.2
|
||||
for label, width, fill, is_seq in stages:
|
||||
draw_box(ax, x, y, width, h, label, fill=fill, fontsize=FS_TINY,
|
||||
fontweight='bold' if is_seq else 'normal')
|
||||
if is_seq:
|
||||
ax.text(x + width/2, y - 0.25, 'SEQ', ha='center', fontsize=FS_TINY,
|
||||
fontweight='bold')
|
||||
else:
|
||||
ax.text(x + width/2, y - 0.25, 'PAR', ha='center', fontsize=FS_TINY,
|
||||
color='#444444')
|
||||
x += width + 0.15
|
||||
|
||||
ax.text(6.5, 6.5, '← 16.67 ms frame budget @ 60 FPS →',
|
||||
ha='center', fontsize=FS_SMALL, style='italic')
|
||||
|
||||
# Amdahl calculation
|
||||
draw_box(ax, 0.3, 1.5, 12.3, 2.8, '', fill=GRAY4, lw=1.5)
|
||||
ax.text(6.5, 4.0, 'Amdahl w praktyce — profiling z NVIDIA Nsight',
|
||||
ha='center', fontsize=FS, fontweight='bold')
|
||||
|
||||
calc_lines = [
|
||||
'Sekwencyjna część (p_seq): Input + Game Logic + Present ≈ 25% frame time',
|
||||
'Równoległa część (p_par): Physics + Anim + Culling + Render ≈ 75% frame time',
|
||||
'',
|
||||
'S(n) = 1 / ((1 - p) + p/n) → S(4 cores) = 1 / (0.25 + 0.75/4) = 1 / 0.4375 ≈ 2.29x',
|
||||
'S(8 cores) ≈ 2.91x S(16 cores) ≈ 3.37x S(∞) = 1/0.25 = 4x MAX',
|
||||
'',
|
||||
'Wniosek: nawet z ∞ rdzeniami, 25% sekwencyjnego kodu limituje do 4x speedup!',
|
||||
'Nsight pozwala zmierzyć DOKŁADNIE ile czasu jest seq vs par per frame.',
|
||||
]
|
||||
|
||||
for i, line in enumerate(calc_lines):
|
||||
weight = 'bold' if 'Wniosek' in line or 'Nsight' in line else 'normal'
|
||||
ax.text(0.6, 3.5 - i * 0.28, line, ha='left', fontsize=FS_TINY,
|
||||
fontweight=weight, family='monospace' if '=' in line or '→' in line else 'sans-serif')
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q25_amdahl_game_pipeline.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 7: Async/Sync in Game Engines — GPU/CPU (Q26)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_gpu_cpu_sync():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(10, 5.5), dpi=DPI)
|
||||
ax.set_xlim(0, 13)
|
||||
ax.set_ylim(0, 7.5)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(6.5, 7.2,
|
||||
'Synchroniczna vs Asynchroniczna komunikacja — CPU↔GPU w silnikach gier',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
# Timeline - Frame N
|
||||
ax.text(0.3, 6.5, 'Frame N', ha='left', fontsize=FS, fontweight='bold')
|
||||
|
||||
# CPU timeline
|
||||
ax.text(0.3, 5.8, 'CPU:', ha='left', fontsize=FS, fontweight='bold')
|
||||
cpu_blocks = [
|
||||
(1.5, 5.5, 2.5, 0.6, 'Game Logic\n(Update)', GRAY1),
|
||||
(4.2, 5.5, 2.0, 0.6, 'Prepare\nDraw Calls', GRAY2),
|
||||
(6.4, 5.5, 1.5, 0.6, 'Submit to\nGPU', GRAY3),
|
||||
(8.1, 5.5, 2.5, 0.6, 'IDLE (wait)\nor next frame', WHITE),
|
||||
]
|
||||
for x, y, w, h, label, fill in cpu_blocks:
|
||||
draw_box(ax, x, y, w, h, label, fill=fill, fontsize=FS_TINY)
|
||||
|
||||
# GPU timeline
|
||||
ax.text(0.3, 4.6, 'GPU:', ha='left', fontsize=FS, fontweight='bold')
|
||||
gpu_blocks = [
|
||||
(1.5, 4.3, 3.5, 0.6, 'Rendering Frame N-1', GRAY3),
|
||||
(5.2, 4.3, 1.0, 0.6, 'IDLE', WHITE),
|
||||
(6.4, 4.3, 4.2, 0.6, 'Rendering Frame N', GRAY2),
|
||||
]
|
||||
for x, y, w, h, label, fill in gpu_blocks:
|
||||
draw_box(ax, x, y, w, h, label, fill=fill, fontsize=FS_TINY)
|
||||
|
||||
# Sync point
|
||||
ax.plot([6.4, 6.4], [4.3, 6.1], color=LN, lw=1.5, ls='--')
|
||||
ax.text(6.4, 6.2, 'SYNC\nPOINT', ha='center', fontsize=FS_TINY,
|
||||
fontweight='bold')
|
||||
|
||||
# Comparison table
|
||||
draw_box(ax, 0.3, 0.5, 12.3, 3.3, '', fill=GRAY4, lw=1.0)
|
||||
ax.text(6.5, 3.5, 'Asynchroniczne mechanizmy w grach — analogia do MPI',
|
||||
ha='center', fontsize=FS, fontweight='bold')
|
||||
|
||||
table = [
|
||||
('Mechanizm', 'Sync/Async', 'Blokujący?', 'Analogia MPI', 'Silnik'),
|
||||
('glFinish()', 'SYNC', 'TAK', 'MPI_Ssend', 'OpenGL'),
|
||||
('Unity Coroutine', 'ASYNC', 'NIE', 'MPI_Isend+Wait', 'Unity'),
|
||||
('C# async/await', 'ASYNC', 'NIE', 'MPI_Irecv+Wait', 'Unity'),
|
||||
('GPU Fence', 'SYNC', 'TAK (check)', 'MPI_Barrier', 'Oba'),
|
||||
('Command Buffer', 'ASYNC', 'NIE (queue)', 'MPI_Bsend', 'Oba'),
|
||||
('UE TaskGraph', 'ASYNC', 'NIE (deps)', 'DAG scheduling', 'Unreal'),
|
||||
]
|
||||
|
||||
col_xs = [0.6, 3.8, 5.8, 7.8, 10.0]
|
||||
for i, row in enumerate(table):
|
||||
y = 3.0 - i * 0.33
|
||||
weight = 'bold' if i == 0 else 'normal'
|
||||
for j, val in enumerate(row):
|
||||
ax.text(col_xs[j], y, val, ha='left', fontsize=FS_TINY,
|
||||
fontweight=weight)
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q26_gpu_cpu_sync_async.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 8: Game Engine Architecture — C4 model (Q13/27)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_engine_c4():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(10, 6.5), dpi=DPI)
|
||||
ax.set_xlim(0, 13)
|
||||
ax.set_ylim(0, 8.5)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(6.5, 8.2,
|
||||
'Modelowanie architektury silnika gier — podejście C4',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
# Level 1: Context
|
||||
draw_box(ax, 0.3, 6.3, 12.3, 1.6, '', fill=GRAY4, lw=1.5)
|
||||
ax.text(6.5, 7.6, 'C1: Context — System w otoczeniu', ha='center',
|
||||
fontsize=FS, fontweight='bold')
|
||||
ctx_items = [
|
||||
(1.5, 6.5, 'Gracz\n(Input)'),
|
||||
(4.0, 6.5, 'Game Engine\n(Unity/Unreal)'),
|
||||
(7.0, 6.5, 'GPU / OS\n(Platform)'),
|
||||
(10.0, 6.5, 'Asset Pipeline\n(Blender, PS)'),
|
||||
]
|
||||
for x, y, label in ctx_items:
|
||||
draw_box(ax, x, y, 2.0, 0.9, label, fill=WHITE, fontsize=FS_TINY)
|
||||
|
||||
arrow(ax, 3.5, 6.95, 4.0, 6.95, '->')
|
||||
arrow(ax, 6.0, 6.95, 7.0, 6.95, '->')
|
||||
arrow(ax, 9.0, 6.95, 10.0, 6.95, '<-')
|
||||
|
||||
# Level 2: Containers
|
||||
draw_box(ax, 0.3, 3.8, 12.3, 2.2, '', fill=WHITE, lw=1.5)
|
||||
ax.text(6.5, 5.7, 'C2: Containers — Główne podsystemy silnika',
|
||||
ha='center', fontsize=FS, fontweight='bold')
|
||||
containers = [
|
||||
(0.5, 4.0, 'Rendering\nEngine', GRAY3),
|
||||
(2.5, 4.0, 'Physics\nEngine', GRAY2),
|
||||
(4.5, 4.0, 'Scripting\nRuntime', GRAY1),
|
||||
(6.5, 4.0, 'Audio\nEngine', GRAY2),
|
||||
(8.5, 4.0, 'Scene\nGraph', GRAY1),
|
||||
(10.5, 4.0, 'Resource\nManager', GRAY3),
|
||||
]
|
||||
for x, y, label, fill in containers:
|
||||
draw_box(ax, x, y, 1.8, 1.2, label, fill=fill, fontsize=FS_TINY,
|
||||
fontweight='bold')
|
||||
|
||||
# Level 3: Components (zoomed into Scripting Runtime)
|
||||
draw_box(ax, 0.3, 1.2, 12.3, 2.3, '', fill=GRAY4, lw=1.5)
|
||||
ax.text(6.5, 3.2, 'C3: Components — Porównanie Scripting Runtime',
|
||||
ha='center', fontsize=FS, fontweight='bold')
|
||||
|
||||
# Unity side
|
||||
unity_comps = [
|
||||
(0.8, 1.4, 'Mono/.NET\nRuntime'),
|
||||
(2.8, 1.4, 'C# Scripts\n(MonoBehaviour)'),
|
||||
(4.8, 1.4, 'IL2CPP\n(AOT compile)'),
|
||||
]
|
||||
ax.text(3.3, 2.7, 'UNITY', ha='center', fontsize=FS_SMALL, fontweight='bold')
|
||||
for x, y, label in unity_comps:
|
||||
draw_box(ax, x, y, 1.8, 0.9, label, fill=GRAY1, fontsize=FS_TINY)
|
||||
|
||||
# Unreal side
|
||||
unreal_comps = [
|
||||
(7.3, 1.4, 'Native C++\nRuntime'),
|
||||
(9.3, 1.4, 'Blueprint\nVM'),
|
||||
(11.1, 1.4, 'UObject\nReflection'),
|
||||
]
|
||||
ax.text(9.8, 2.7, 'UNREAL', ha='center', fontsize=FS_SMALL, fontweight='bold')
|
||||
for x, y, label in unreal_comps:
|
||||
draw_box(ax, x, y, 1.8, 0.9, label, fill=GRAY2, fontsize=FS_TINY)
|
||||
|
||||
# Divider
|
||||
ax.plot([6.5, 6.5], [1.3, 3.0], color=LN, lw=1.0, ls='--')
|
||||
|
||||
# ADR note
|
||||
ax.text(6.5, 0.6,
|
||||
'Kluczowe ADR-y: „C# z GC vs C++ manual" | „Component vs Actor model" | '
|
||||
'„Managed heap vs custom allocators"',
|
||||
ha='center', fontsize=FS_TINY, style='italic',
|
||||
bbox=dict(boxstyle='round,pad=0.3', facecolor=WHITE, edgecolor=LN, lw=0.8))
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q13_engine_c4_architecture.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# DIAGRAM 9: Architectural Patterns in Game Engines (Q14/28)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
def draw_engine_patterns():
|
||||
fig, ax = plt.subplots(1, 1, figsize=(10, 6), dpi=DPI)
|
||||
ax.set_xlim(0, 13)
|
||||
ax.set_ylim(0, 8)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
fig.patch.set_facecolor(BG)
|
||||
|
||||
ax.text(6.5, 7.7,
|
||||
'Wzorce architektoniczne w silnikach gier — mapa wzorców',
|
||||
ha='center', fontsize=FS_TITLE, fontweight='bold')
|
||||
|
||||
patterns = [
|
||||
('Component\nPattern', 1.0, 5.5, GRAY1,
|
||||
'Unity: MonoBehaviour\nUnreal: UActorComponent\n→ Composition over Inheritance'),
|
||||
('Object Pool', 4.5, 5.5, GRAY2,
|
||||
'Unity: BulletPool.cs\nUnreal: FPooledObject\n→ Eliminacja GC spikes'),
|
||||
('Observer /\nEvent-Driven', 8.0, 5.5, GRAY3,
|
||||
'Unity: C# event/delegate\nUnreal: FMulticastDelegate\n→ Loose coupling'),
|
||||
('Singleton', 1.0, 3.0, GRAY2,
|
||||
'Unity: GameDirector.Instance\nUnreal: UGameInstance\n→ Global state access'),
|
||||
('Game Loop', 4.5, 3.0, GRAY1,
|
||||
'Update() → FixedUpdate()\nTick() → TickComponent()\n→ Frame-based execution'),
|
||||
('Entity-\nComponent-\nSystem (ECS)', 8.0, 3.0, GRAY3,
|
||||
'Unity DOTS / Burst\nUnreal Mass Entity\n→ Data-oriented, cache-friendly'),
|
||||
]
|
||||
|
||||
for label, x, y, fill, desc in patterns:
|
||||
draw_box(ax, x, y, 2.8, 1.8, '', fill=fill, lw=1.5)
|
||||
ax.text(x + 1.4, y + 1.45, label, ha='center', fontsize=FS_SMALL,
|
||||
fontweight='bold')
|
||||
lines = desc.split('\n')
|
||||
for i, line in enumerate(lines):
|
||||
ax.text(x + 1.4, y + 0.9 - i * 0.28, line, ha='center',
|
||||
fontsize=FS_TINY)
|
||||
|
||||
# Bottom: catalog mapping
|
||||
draw_box(ax, 0.3, 0.3, 12.3, 2.2, '', fill=GRAY4, lw=1.0)
|
||||
ax.text(6.5, 2.2, 'Katalogi wzorców — gdzie je znaleźć?', ha='center',
|
||||
fontsize=FS, fontweight='bold')
|
||||
catalog_info = [
|
||||
'Game Loop, Component, Object Pool → Game Programming Patterns (Robert Nystrom, 2014)',
|
||||
'Observer, Singleton, Strategy → GoF (Gang of Four, 1994)',
|
||||
'ECS, Data-Oriented Design → Unity DOTS docs / Mike Acton GDC 2014',
|
||||
'Event-Driven, Pub-Sub → EIP (Hohpe & Woolf, 2003)',
|
||||
]
|
||||
for i, line in enumerate(catalog_info):
|
||||
ax.text(0.6, 1.8 - i * 0.35, line, ha='left', fontsize=FS_TINY)
|
||||
|
||||
out = os.path.join(OUTPUT_DIR, 'q14_engine_patterns_map.png')
|
||||
fig.savefig(out, dpi=DPI, bbox_inches='tight', facecolor=BG)
|
||||
plt.close(fig)
|
||||
print(f' ✓ {out}')
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
if __name__ == '__main__':
|
||||
print('Generating thesis-bridge diagrams...')
|
||||
draw_game_engine_threads()
|
||||
draw_memory_gc_vs_manual()
|
||||
draw_object_pooling()
|
||||
draw_component_pattern()
|
||||
draw_stl_vs_unreal()
|
||||
draw_amdahl_game_pipeline()
|
||||
draw_gpu_cpu_sync()
|
||||
draw_engine_c4()
|
||||
draw_engine_patterns()
|
||||
print('Done! All diagrams in pytania/img/')
|
||||
BIN
pytania/img/q10_gc_vs_manual_memory.png
Normal file
|
After Width: | Height: | Size: 235 KiB |
BIN
pytania/img/q10_object_pooling.png
Normal file
|
After Width: | Height: | Size: 123 KiB |
BIN
pytania/img/q13_engine_c4_architecture.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
pytania/img/q14_engine_patterns_map.png
Normal file
|
After Width: | Height: | Size: 260 KiB |
BIN
pytania/img/q18_eoq_cost_curves.png
Normal file
|
After Width: | Height: | Size: 190 KiB |
BIN
pytania/img/q18_eoq_sawtooth.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
pytania/img/q25_amdahl_game_pipeline.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
pytania/img/q26_deadlock_vs_solution.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
pytania/img/q26_domain_decomposition.png
Normal file
|
After Width: | Height: | Size: 297 KiB |
BIN
pytania/img/q26_ghost_cell_exchange.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
pytania/img/q26_gpu_cpu_sync_async.png
Normal file
|
After Width: | Height: | Size: 193 KiB |
BIN
pytania/img/q26_jacobi_full_iteration.png
Normal file
|
After Width: | Height: | Size: 320 KiB |
BIN
pytania/img/q26_jacobi_stencil.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
pytania/img/q5_stl_vs_unreal.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
pytania/img/q6_component_pattern_engines.png
Normal file
|
After Width: | Height: | Size: 227 KiB |
BIN
pytania/img/q9_game_engine_threads.png
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
pytania/img/q9_memory_c_annotated.png
Normal file
|
After Width: | Height: | Size: 183 KiB |
BIN
pytania/img/q9_pcb_detailed.png
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
pytania/img/q9_process_states_labeled.png
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
pytania/img/q9_thread_shared_private.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
@ -1,338 +0,0 @@
|
||||
# Pytanie 1: Porównanie automatów i rozpoznawanych klas języków
|
||||
|
||||
## Pytanie
|
||||
**"Porównać 'siłę wyrazu' automatu skończonego, automatu ze stosem oraz maszyny Turinga. Jakie klasy języków rozpoznaje każdy z nich?"**
|
||||
|
||||
Przedmiot: AISDI (Algorytmy i Struktury Danych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Hierarchia Chomsky'ego - fundament teoretyczny
|
||||
|
||||
Noam Chomsky w 1956 roku zaproponował hierarchię czterech klas języków formalnych, gdzie każda kolejna klasa zawiera poprzednią:
|
||||
|
||||
```
|
||||
Typ 0: Języki rekurencyjnie przeliczalne (Recursively Enumerable)
|
||||
⊃
|
||||
Typ 1: Języki kontekstowe (Context-Sensitive)
|
||||
⊃
|
||||
Typ 2: Języki bezkontekstowe (Context-Free)
|
||||
⊃
|
||||
Typ 3: Języki regularne (Regular)
|
||||
```
|
||||
|
||||
### 1. Automat Skończony (Finite Automaton - FA)
|
||||
|
||||
#### Definicja formalna
|
||||
Automat skończony to piątka: **M = (Q, Σ, δ, q₀, F)**
|
||||
- **Q** - skończony zbiór stanów
|
||||
- **Σ** - alfabet wejściowy (skończony zbiór symboli)
|
||||
- **δ** - funkcja przejścia: Q × Σ → Q (DFA) lub Q × Σ → P(Q) (NFA)
|
||||
- **q₀** - stan początkowy (q₀ ∈ Q)
|
||||
- **F** - zbiór stanów akceptujących (F ⊆ Q)
|
||||
|
||||
#### Rozpoznawana klasa języków
|
||||
**Języki regularne (Typ 3)** - najsłabsza klasa w hierarchii Chomsky'ego
|
||||
|
||||
#### Charakterystyka
|
||||
- **Pamięć**: Brak pamięci pomocniczej - tylko aktualny stan
|
||||
- **Moc obliczeniowa**: Nie potrafi "liczyć" (porównywać ilości)
|
||||
- **Równoważne formalizmy**:
|
||||
- Wyrażenia regularne (regex)
|
||||
- Gramatyki regularne (prawo- lub lewostronnie liniowe)
|
||||
- DFA ≡ NFA ≡ ε-NFA (równoważne pod względem mocy)
|
||||
|
||||
#### Przykłady języków rozpoznawalnych
|
||||
- L = {w ∈ {a,b}* : w zawiera podciąg "ab"}
|
||||
- L = {w ∈ {0,1}* : w jest podzielne przez 3 (interpretowane binarnie)}
|
||||
- Identyfikatory w językach programowania: `[a-zA-Z_][a-zA-Z0-9_]*`
|
||||
|
||||
#### Przykłady języków NIEROZPOZNAWALNYCH
|
||||
- L = {aⁿbⁿ : n ≥ 0} - wymaga liczenia
|
||||
- L = {ww : w ∈ {a,b}*} - wymaga zapamiętania w
|
||||
- Poprawnie zagnieżdżone nawiasy
|
||||
|
||||
#### Lemat o pompowaniu (Pumping Lemma) dla języków regularnych
|
||||
Dla każdego języka regularnego L istnieje stała p (długość pompowania), taka że:
|
||||
każde słowo w ∈ L, gdzie |w| ≥ p, można podzielić na w = xyz, gdzie:
|
||||
1. |y| > 0
|
||||
2. |xy| ≤ p
|
||||
3. ∀i ≥ 0: xyⁱz ∈ L
|
||||
|
||||
---
|
||||
|
||||
### 2. Automat ze Stosem (Pushdown Automaton - PDA)
|
||||
|
||||
#### Definicja formalna
|
||||
Automat ze stosem to siódemka: **M = (Q, Σ, Γ, δ, q₀, Z₀, F)**
|
||||
- **Q** - skończony zbiór stanów
|
||||
- **Σ** - alfabet wejściowy
|
||||
- **Γ** - alfabet stosowy
|
||||
- **δ** - funkcja przejścia: Q × (Σ ∪ {ε}) × Γ → P(Q × Γ*)
|
||||
- **q₀** - stan początkowy
|
||||
- **Z₀** - początkowy symbol na stosie
|
||||
- **F** - zbiór stanów akceptujących
|
||||
|
||||
#### Rozpoznawana klasa języków
|
||||
**Języki bezkontekstowe (Typ 2)** - Context-Free Languages (CFL)
|
||||
|
||||
#### Charakterystyka
|
||||
- **Pamięć**: Stos (LIFO) - pamięć potencjalnie nieskończona, ale z ograniczonym dostępem
|
||||
- **Moc obliczeniowa**: Potrafi "liczyć" (porównywać pary ilości)
|
||||
- **DPDA ⊂ NPDA**: Deterministyczne PDA są SŁABSZE niż niedeterministyczne!
|
||||
- **Równoważne formalizmy**: Gramatyki bezkontekstowe (CFG)
|
||||
|
||||
#### Dwa tryby akceptacji
|
||||
1. **Przez stan końcowy**: automat jest w stanie z F po przeczytaniu całego słowa
|
||||
2. **Przez pusty stos**: stos jest pusty po przeczytaniu całego słowa
|
||||
|
||||
Oba tryby są równoważne pod względem mocy.
|
||||
|
||||
#### Przykłady języków rozpoznawalnych
|
||||
- L = {aⁿbⁿ : n ≥ 0} - klasyczny przykład
|
||||
- L = {w ∈ {a,b}* : #a(w) = #b(w)} - równa liczba a i b
|
||||
- Poprawnie zagnieżdżone nawiasy: (), (()), (()()), ...
|
||||
- Palindromy: L = {wwᴿ : w ∈ {a,b}*}
|
||||
|
||||
#### Przykłady języków NIEROZPOZNAWALNYCH
|
||||
- L = {aⁿbⁿcⁿ : n ≥ 0} - wymaga liczenia trzech rzeczy
|
||||
- L = {ww : w ∈ {a,b}*} - kopiowanie (nie odwracanie!)
|
||||
- L = {aⁱbʲcᵏ : i = j lub j = k} - to jest CFL! (suma dwóch CFL)
|
||||
|
||||
#### DPDA vs NPDA
|
||||
**Deterministyczne PDA** rozpoznają **właściwy podzbiór** języków bezkontekstowych:
|
||||
- DPDA: L = {aⁿbⁿ : n ≥ 0} ✓
|
||||
- NPDA only: L = {wwᴿ : w ∈ {a,b}*} - palindromy parzyste
|
||||
|
||||
---
|
||||
|
||||
### 3. Maszyna Turinga (Turing Machine - TM)
|
||||
|
||||
#### Definicja formalna
|
||||
Maszyna Turinga to siódemka: **M = (Q, Σ, Γ, δ, q₀, qaccept, qreject)**
|
||||
- **Q** - skończony zbiór stanów
|
||||
- **Σ** - alfabet wejściowy (nie zawiera symbolu pustego ␣)
|
||||
- **Γ** - alfabet taśmowy (Σ ⊂ Γ, ␣ ∈ Γ)
|
||||
- **δ** - funkcja przejścia: Q × Γ → Q × Γ × {L, R}
|
||||
- **q₀** - stan początkowy
|
||||
- **qaccept** - stan akceptujący
|
||||
- **qreject** - stan odrzucający
|
||||
|
||||
#### Rozpoznawana klasa języków
|
||||
**Języki rekurencyjnie przeliczalne (Typ 0)** - Recursively Enumerable (RE)
|
||||
|
||||
Podklasa: **Języki rekurencyjne (rozstrzygalne)** - TM zawsze się zatrzymuje
|
||||
|
||||
#### Charakterystyka
|
||||
- **Pamięć**: Taśma nieskończona z dostępem swobodnym (R/W)
|
||||
- **Moc obliczeniowa**: Maksymalna możliwa (teza Churcha-Turinga)
|
||||
- **DTM ≡ NTM**: Deterministyczne i niedeterministyczne TM są RÓWNOWAŻNE pod względem mocy (ale różnią się złożonością czasową)
|
||||
|
||||
#### Warianty równoważne
|
||||
- Wielotaśmowa TM
|
||||
- Niedeterministyczna TM
|
||||
- RAM (Random Access Machine)
|
||||
- Języki programowania (Turing-complete)
|
||||
|
||||
#### Przykłady języków rozpoznawalnych
|
||||
- L = {aⁿbⁿcⁿ : n ≥ 0}
|
||||
- L = {ww : w ∈ {a,b}*}
|
||||
- Wszystkie języki bezkontekstowe
|
||||
- Wszystkie języki kontekstowe
|
||||
- Problem stopu (HP) - ale TM może się nie zatrzymać!
|
||||
|
||||
#### Przykłady języków NIEROZPOZNAWALNYCH
|
||||
- Komplement problemu stopu: L = {⟨M,w⟩ : M nie zatrzymuje się na w}
|
||||
- Problem odpowiedniości Posta (PCP)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tabela porównawcza
|
||||
|
||||
| Cecha | FA | PDA | TM |
|
||||
|-------|-----|-----|-----|
|
||||
| **Pamięć** | Brak (tylko stan) | Stos (LIFO) | Taśma (R/W swobodny) |
|
||||
| **Klasa języków** | Regularne (Typ 3) | Bezkontekstowe (Typ 2) | Rek. przeliczalne (Typ 0) |
|
||||
| **Gramatyka** | Regularna | Bezkontekstowa (CFG) | Nieograniczona |
|
||||
| **DET = NIEDET?** | TAK | NIE | TAK (moc), NIE (złożoność) |
|
||||
| **Domknięcie ∪** | TAK | TAK | TAK |
|
||||
| **Domknięcie ∩** | TAK | NIE | TAK |
|
||||
| **Domknięcie ¬** | TAK | NIE | NIE (RE), TAK (rekurencyjne) |
|
||||
| **Rozstrzygalność pustości** | TAK | TAK | NIE |
|
||||
| **Zastosowanie** | Leksery, regex | Parsery, kompilatory | Obliczenia ogólne |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Relacje między klasami
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Typ 0: Rekurencyjnie przeliczalne (TM) │
|
||||
│ ┌───────────────────────────────────────────────────────┐ │
|
||||
│ │ Rekurencyjne (TM zatrzymująca się) │ │
|
||||
│ │ ┌─────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ Typ 1: Kontekstowe (LBA) │ │ │
|
||||
│ │ │ ┌───────────────────────────────────────────┐ │ │ │
|
||||
│ │ │ │ Typ 2: Bezkontekstowe (PDA) │ │ │ │
|
||||
│ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │
|
||||
│ │ │ │ │ Deterministyczne CFL (DPDA) │ │ │ │ │
|
||||
│ │ │ │ │ ┌───────────────────────────────┐ │ │ │ │ │
|
||||
│ │ │ │ │ │ Typ 3: Regularne (FA) │ │ │ │ │ │
|
||||
│ │ │ │ │ └───────────────────────────────┘ │ │ │ │ │
|
||||
│ │ │ │ └─────────────────────────────────────┘ │ │ │ │
|
||||
│ │ │ └───────────────────────────────────────────┘ │ │ │
|
||||
│ │ └─────────────────────────────────────────────────┘ │ │
|
||||
│ └───────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "STOS LIFO"
|
||||
- **S**kończony automat - **S**tan tylko (bez pamięci)
|
||||
- **T**ylko regex - języki regularne
|
||||
- **O**graniczony PDA - **O**dnosi się do stosu
|
||||
- **S**tos = bezkontekstowe
|
||||
|
||||
### "TuRing = Total Random access"
|
||||
- **T**aśma nieskończona
|
||||
- **R**andom access (czytanie i pisanie)
|
||||
- **Total** - wszystko może obliczyć (co jest obliczalne)
|
||||
|
||||
### "3-2-1 START"
|
||||
- **3** = Typ 3 = FA = regex (najsłabszy)
|
||||
- **2** = Typ 2 = PDA = CFG (parser)
|
||||
- **1** = Typ 1 = kontekstowe (LBA)
|
||||
- **0** = Typ 0 = TM = wszystko (START od zera = najpotężniejszy)
|
||||
|
||||
### "FA NIC nie pamięta, PDA pamięta ALE odwraca, TM pamięta WSZYSTKO"
|
||||
- FA: nie liczy
|
||||
- PDA: liczy ale LIFO (stąd aⁿbⁿ tak, aⁿbⁿcⁿ nie)
|
||||
- TM: liczy wszystko
|
||||
|
||||
### Akronim "CHOMSKY" dla hierarchii:
|
||||
- **C**omputable all (Typ 0 - TM)
|
||||
- **H**ard context-sensitive (Typ 1)
|
||||
- **O**K with stack (Typ 2 - PDA)
|
||||
- **M**inimal - regex only (Typ 3 - FA)
|
||||
- **S**trict inclusion (każda klasa zawiera niższą)
|
||||
- **K**ey for compilers (zastosowania)
|
||||
- **Y**ears of theory (od 1956)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Udowodnij, że język L = {aⁿbⁿ} nie jest regularny"
|
||||
|
||||
**Odpowiedź:**
|
||||
Stosujemy lemat o pompowaniu. Załóżmy, że L jest regularny z długością pompowania p.
|
||||
|
||||
Weźmy w = aᵖbᵖ ∈ L, |w| = 2p ≥ p
|
||||
|
||||
Według lematu: w = xyz, gdzie |xy| ≤ p, |y| > 0
|
||||
|
||||
Ponieważ |xy| ≤ p, to xy składa się tylko z 'a' (pierwsze p znaków to same 'a').
|
||||
Zatem y = aᵏ dla pewnego k > 0.
|
||||
|
||||
Pompujemy: xy²z = aᵖ⁺ᵏbᵖ
|
||||
|
||||
Ale p + k ≠ p, więc xy²z ∉ L. **Sprzeczność!** ∎
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Dlaczego DPDA ⊂ NPDA, ale DFA = NFA?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**DFA = NFA:**
|
||||
- Można przekształcić NFA w DFA przez konstrukcję potęgową (subset construction)
|
||||
- Każdy stan DFA odpowiada podzbiorowi stanów NFA
|
||||
- Wykładniczy wzrost stanów, ale ta sama moc
|
||||
|
||||
**DPDA ⊂ NPDA:**
|
||||
- PDA ma stos - niedeterminizm pozwala "zgadywać" środek palindromu
|
||||
- DPDA nie może rozpoznać {wwᴿ} bo nie wie, kiedy kończy się w
|
||||
- DPDA rozpoznaje języki z własnością prefiksową
|
||||
- Niedeterminizm w PDA NIE daje się wyeliminować (brak konstrukcji analogicznej do potęgowej dla stosów)
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Co to jest LBA i gdzie się mieści w hierarchii?"
|
||||
|
||||
**Odpowiedź:**
|
||||
**Linear Bounded Automaton (LBA)** - maszyna Turinga z ograniczoną taśmą:
|
||||
- Taśma ograniczona do długości liniowej względem wejścia: O(n)
|
||||
- Rozpoznaje języki kontekstowe (Typ 1)
|
||||
- NLBA > DLBA? - otwarty problem!
|
||||
- Przykład: L = {aⁿbⁿcⁿ} - kontekstowy, ale nie bezkontekstowy
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Jakie są praktyczne zastosowania każdego typu automatu?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Automat | Zastosowania praktyczne |
|
||||
|---------|------------------------|
|
||||
| **FA/DFA** | Leksery (tokenizacja), walidacja regex, kontrolery stanów w grach, protokoły sieciowe, automaty w VHDL/Verilog |
|
||||
| **PDA** | Parsery (analiza składniowa), kompilatory (CFG), walidacja XML/JSON, sprawdzanie nawiasów |
|
||||
| **TM** | Model teoretyczny obliczeń, dowody nierozstrzygalności, złożoność obliczeniowa (P vs NP) |
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co to jest teza Churcha-Turinga?"
|
||||
|
||||
**Odpowiedź:**
|
||||
**Teza Churcha-Turinga** (nieformalnie):
|
||||
> "Każda funkcja, która może być obliczona przez jakikolwiek algorytm, może być obliczona przez maszynę Turinga."
|
||||
|
||||
**Równoważne formalizmy:**
|
||||
- Maszyna Turinga
|
||||
- Rachunek lambda (Church)
|
||||
- Funkcje rekurencyjne (Gödel)
|
||||
- Maszyna RAM
|
||||
- Języki Turing-complete (C, Python, Java...)
|
||||
|
||||
**To jest TEZA, nie twierdzenie** - nie można jej udowodnić, bo "algorytm" nie ma formalnej definicji.
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Czy istnieje język, który nie jest rekurencyjnie przeliczalny?"
|
||||
|
||||
**Odpowiedź:**
|
||||
TAK! Argument przekątniowy (diagonalizacja):
|
||||
|
||||
**L_d** = {⟨M⟩ : M nie akceptuje ⟨M⟩}
|
||||
|
||||
Ten język nie jest RE (rekurencyjnie przeliczalny).
|
||||
|
||||
**Dowód:**
|
||||
Załóżmy, że TM M_d rozpoznaje L_d.
|
||||
- Czy M_d akceptuje ⟨M_d⟩?
|
||||
- Jeśli TAK → ⟨M_d⟩ ∉ L_d → M_d nie powinno akceptować (sprzeczność)
|
||||
- Jeśli NIE → ⟨M_d⟩ ∈ L_d → M_d powinno akceptować (sprzeczność)
|
||||
|
||||
Zatem M_d nie istnieje, więc L_d ∉ RE. ∎
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **Hierarchia jest ścisła**: Reg ⊂ CFL ⊂ CSL ⊂ RE
|
||||
2. **Pamięć = moc**: brak < stos < taśma
|
||||
3. **FA: DET = NIEDET**, PDA: DET < NIEDET, TM: DET = NIEDET (moc)
|
||||
4. **Domknięcie na dopełnienie**: FA tak, CFL nie, RE nie
|
||||
5. **Praktyka**: FA = regex/lexer, PDA = parser, TM = teoria
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Hopcroft, Motwani, Ullman - "Introduction to Automata Theory, Languages, and Computation"
|
||||
2. Sipser - "Introduction to the Theory of Computation"
|
||||
3. Kozen - "Automata and Computability"
|
||||
@ -1,487 +0,0 @@
|
||||
# Pytanie 2: Algorytmy najkrótszej ścieżki
|
||||
|
||||
## Pytanie
|
||||
**"Omówić i porównać algorytmy najkrótszej ścieżki wskazując ich kluczowe właściwości i logikę budowy: Dijkstry, Belmana-Forda, A*."**
|
||||
|
||||
Przedmiot: AISDI (Algorytmy i Struktury Danych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie - problem najkrótszej ścieżki
|
||||
|
||||
**Problem:** Dany jest graf G = (V, E) z funkcją wag w: E → ℝ. Znajdź ścieżkę z wierzchołka źródłowego s do wierzchołka docelowego t o minimalnej sumie wag krawędzi.
|
||||
|
||||
**Warianty problemu:**
|
||||
1. **Single-Source Shortest Path (SSSP)** - z jednego źródła do wszystkich wierzchołków
|
||||
2. **Single-Pair Shortest Path** - z s do konkretnego t
|
||||
3. **All-Pairs Shortest Path (APSP)** - między wszystkimi parami (Floyd-Warshall)
|
||||
|
||||
---
|
||||
|
||||
## 1. Algorytm Dijkstry
|
||||
|
||||
### Charakterystyka
|
||||
- **Autor:** Edsger Dijkstra (1956, opublikowany 1959)
|
||||
- **Typ:** Zachłanny (greedy)
|
||||
- **Problem:** SSSP - najkrótsze ścieżki z jednego źródła do wszystkich wierzchołków
|
||||
- **Ograniczenie:** ⚠️ **Tylko nieujemne wagi krawędzi** (w(e) ≥ 0)
|
||||
|
||||
### Idea algorytmu (logika budowy)
|
||||
1. **Relaksacja:** Stopniowe ulepszanie oszacowań odległości
|
||||
2. **Zachłanność:** W każdym kroku wybieramy wierzchołek o najmniejszej znanej odległości
|
||||
3. **Optymalna podstruktura:** Najkrótsza ścieżka składa się z najkrótszych podścieżek
|
||||
|
||||
### Pseudokod
|
||||
|
||||
```
|
||||
DIJKSTRA(G, w, s):
|
||||
// Inicjalizacja
|
||||
for each v ∈ V:
|
||||
d[v] ← ∞
|
||||
π[v] ← NIL
|
||||
d[s] ← 0
|
||||
|
||||
Q ← priority_queue(V) // min-heap według d[v]
|
||||
S ← ∅ // zbiór przetworzonych
|
||||
|
||||
while Q ≠ ∅:
|
||||
u ← EXTRACT-MIN(Q)
|
||||
S ← S ∪ {u}
|
||||
|
||||
for each v ∈ Adj[u]: // relaksacja
|
||||
if d[u] + w(u,v) < d[v]:
|
||||
d[v] ← d[u] + w(u,v)
|
||||
π[v] ← u
|
||||
DECREASE-KEY(Q, v, d[v])
|
||||
|
||||
return d, π
|
||||
```
|
||||
|
||||
### Złożoność czasowa
|
||||
|
||||
| Implementacja kolejki | EXTRACT-MIN | DECREASE-KEY | Całkowita |
|
||||
|----------------------|-------------|--------------|-----------|
|
||||
| Lista/tablica | O(V) | O(1) | **O(V²)** |
|
||||
| Kopiec binarny | O(log V) | O(log V) | **O((V + E) log V)** |
|
||||
| Kopiec Fibonacciego | O(log V)* | O(1)* | **O(V log V + E)** |
|
||||
|
||||
*amortyzowane
|
||||
|
||||
### Dlaczego nie działa dla ujemnych wag?
|
||||
|
||||
```
|
||||
A ---(-5)--- B
|
||||
| |
|
||||
(1) (1)
|
||||
| |
|
||||
S -----------C
|
||||
(2)
|
||||
```
|
||||
|
||||
Dijkstra przetwarza wierzchołki w kolejności rosnącej odległości i oznacza je jako "zakończone". Jeśli waga może być ujemna, późniejszy wierzchołek może "poprawić" już zakończony.
|
||||
|
||||
**Przykład:** S→C = 2 (Dijkstra ustala jako finalne), ale S→A→B→C = 1 + (-5) + 1 = -3 < 2
|
||||
|
||||
---
|
||||
|
||||
## 2. Algorytm Bellmana-Forda
|
||||
|
||||
### Charakterystyka
|
||||
- **Autorzy:** Richard Bellman, Lester Ford Jr. (1958)
|
||||
- **Typ:** Programowanie dynamiczne
|
||||
- **Problem:** SSSP z wykrywaniem cykli ujemnych
|
||||
- **Zaleta:** ✅ **Działa dla ujemnych wag**
|
||||
- **Ograniczenie:** ⚠️ Graf nie może mieć cyklu o ujemnej sumie wag (ale algorytm go wykrywa!)
|
||||
|
||||
### Idea algorytmu (logika budowy)
|
||||
1. **Indukcja po liczbie krawędzi:** d^(k)[v] = najkrótsza ścieżka do v używająca ≤ k krawędzi
|
||||
2. **|V|-1 iteracji:** Najkrótsza ścieżka bez cykli ma co najwyżej |V|-1 krawędzi
|
||||
3. **Relaksacja wszystkich krawędzi:** W każdej iteracji relaksujemy każdą krawędź
|
||||
|
||||
### Pseudokod
|
||||
|
||||
```
|
||||
BELLMAN-FORD(G, w, s):
|
||||
// Inicjalizacja
|
||||
for each v ∈ V:
|
||||
d[v] ← ∞
|
||||
π[v] ← NIL
|
||||
d[s] ← 0
|
||||
|
||||
// Główna pętla: |V|-1 iteracji
|
||||
for i ← 1 to |V| - 1:
|
||||
for each edge (u, v) ∈ E:
|
||||
if d[u] + w(u,v) < d[v]: // relaksacja
|
||||
d[v] ← d[u] + w(u,v)
|
||||
π[v] ← u
|
||||
|
||||
// Wykrywanie cyklu ujemnego
|
||||
for each edge (u, v) ∈ E:
|
||||
if d[u] + w(u,v) < d[v]:
|
||||
return "CYKL UJEMNY"
|
||||
|
||||
return d, π
|
||||
```
|
||||
|
||||
### Złożoność czasowa
|
||||
**O(V · E)** - zawsze, niezależnie od implementacji
|
||||
|
||||
Dla grafów gęstych (E ≈ V²): O(V³) - wolniejszy niż Dijkstra O(V²)
|
||||
|
||||
### Wykrywanie cyklu ujemnego
|
||||
Po |V|-1 iteracjach, wszystkie najkrótsze ścieżki (bez cykli) są znalezione.
|
||||
Jeśli w iteracji |V| nadal można zrelaksować krawędź → istnieje cykl ujemny.
|
||||
|
||||
### Optymalizacja: wczesne zakończenie
|
||||
```
|
||||
for i ← 1 to |V| - 1:
|
||||
changed ← false
|
||||
for each edge (u, v) ∈ E:
|
||||
if d[u] + w(u,v) < d[v]:
|
||||
d[v] ← d[u] + w(u,v)
|
||||
π[v] ← u
|
||||
changed ← true
|
||||
if not changed:
|
||||
break // Brak zmian = gotowe wcześniej
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Algorytm A* (A-star)
|
||||
|
||||
### Charakterystyka
|
||||
- **Autorzy:** Peter Hart, Nils Nilsson, Bertram Raphael (1968)
|
||||
- **Typ:** Heurystyczny (informed search)
|
||||
- **Problem:** Single-Pair - najkrótsza ścieżka z s do konkretnego t
|
||||
- **Zaleta:** ✅ **Znacznie szybszy niż Dijkstra** dla problemu s→t
|
||||
- **Wymóg:** Heurystyka dopuszczalna (admissible)
|
||||
|
||||
### Idea algorytmu (logika budowy)
|
||||
1. **Rozszerzenie Dijkstry:** Dodajemy funkcję heurystyczną
|
||||
2. **f(n) = g(n) + h(n):**
|
||||
- g(n) = koszt dotarcia do n (znany)
|
||||
- h(n) = heurystyczne oszacowanie kosztu n → cel (szacowany)
|
||||
- f(n) = całkowite oszacowanie kosztu ścieżki przez n
|
||||
3. **Wybieramy wierzchołek o minimalnym f(n)** zamiast minimalnym g(n)
|
||||
|
||||
### Pseudokod
|
||||
|
||||
```
|
||||
A-STAR(G, w, s, t, h):
|
||||
// Inicjalizacja
|
||||
for each v ∈ V:
|
||||
g[v] ← ∞
|
||||
f[v] ← ∞
|
||||
π[v] ← NIL
|
||||
g[s] ← 0
|
||||
f[s] ← h(s)
|
||||
|
||||
OPEN ← priority_queue({s}) // min-heap według f[v]
|
||||
CLOSED ← ∅
|
||||
|
||||
while OPEN ≠ ∅:
|
||||
u ← EXTRACT-MIN(OPEN)
|
||||
|
||||
if u = t:
|
||||
return RECONSTRUCT-PATH(π, t)
|
||||
|
||||
CLOSED ← CLOSED ∪ {u}
|
||||
|
||||
for each v ∈ Adj[u]:
|
||||
if v ∈ CLOSED:
|
||||
continue
|
||||
|
||||
tentative_g ← g[u] + w(u, v)
|
||||
|
||||
if v ∉ OPEN:
|
||||
OPEN ← OPEN ∪ {v}
|
||||
else if tentative_g ≥ g[v]:
|
||||
continue
|
||||
|
||||
π[v] ← u
|
||||
g[v] ← tentative_g
|
||||
f[v] ← g[v] + h(v)
|
||||
|
||||
return "BRAK ŚCIEŻKI"
|
||||
```
|
||||
|
||||
### Heurystyka - kluczowy element
|
||||
|
||||
#### Wymagane właściwości:
|
||||
|
||||
1. **Dopuszczalność (Admissibility):**
|
||||
h(n) ≤ h*(n) dla każdego n
|
||||
|
||||
gdzie h*(n) = rzeczywisty koszt n → cel
|
||||
|
||||
→ Gwarantuje optymalność rozwiązania
|
||||
|
||||
2. **Spójność/Monotoniczność (Consistency):**
|
||||
h(n) ≤ w(n, m) + h(m) dla każdej krawędzi (n, m)
|
||||
|
||||
→ Gwarantuje, że węzeł nie musi być ponownie otwarty
|
||||
→ Spójność implikuje dopuszczalność
|
||||
|
||||
#### Popularne heurystyki (dla siatek 2D):
|
||||
|
||||
| Heurystyka | Wzór | Ruch |
|
||||
|------------|------|------|
|
||||
| **Manhattan** | \|x₁-x₂\| + \|y₁-y₂\| | 4 kierunki |
|
||||
| **Euklidesowa** | √((x₁-x₂)² + (y₁-y₂)²) | dowolny kąt |
|
||||
| **Czebyszewa** | max(\|x₁-x₂\|, \|y₁-y₂\|) | 8 kierunków |
|
||||
| **Oktylowa** | max(Δx, Δy) + (√2-1)·min(Δx, Δy) | 8 kier. + przekątne |
|
||||
|
||||
### Złożoność czasowa
|
||||
- **Najgorszy przypadek:** O((V + E) log V) - jak Dijkstra
|
||||
- **Praktycznie:** Znacznie lepiej dzięki heurystyce - przeszukuje mniej wierzchołków
|
||||
- **Zależy od jakości h:** Im lepsza heurystyka, tym mniej eksploracji
|
||||
|
||||
### Przypadki specjalne:
|
||||
- **h(n) = 0:** A* = Dijkstra
|
||||
- **h(n) = h*(n):** A* idzie prosto do celu (idealna heurystyka)
|
||||
- **h(n) > h*(n):** Może nie znaleźć optymalnej ścieżki!
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tabela porównawcza
|
||||
|
||||
| Cecha | Dijkstra | Bellman-Ford | A* |
|
||||
|-------|----------|--------------|-----|
|
||||
| **Typ** | Zachłanny | Prog. dynamiczne | Heurystyczny |
|
||||
| **Problem** | SSSP | SSSP | Single-pair (s→t) |
|
||||
| **Ujemne wagi** | ❌ NIE | ✅ TAK | ❌ NIE |
|
||||
| **Cykle ujemne** | Błędny wynik | Wykrywa | Błędny wynik |
|
||||
| **Złożoność** | O(V log V + E) | O(V·E) | O((V+E) log V)* |
|
||||
| **Pamięć** | O(V) | O(V) | O(V) |
|
||||
| **Optymalizacja** | Kolejka priorytetowa | Wczesne zakończenie | Heurystyka |
|
||||
| **Zastosowanie** | Grafy nieujemne | Grafy z ujemnymi | Pathfinding w grach |
|
||||
|
||||
*praktycznie często znacznie mniej
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Zastosowania praktyczne
|
||||
|
||||
### Dijkstra
|
||||
- **Nawigacja GPS** (drogi nie mają ujemnych odległości)
|
||||
- **Routing w sieciach** (OSPF protocol)
|
||||
- **Mapy Google/Apple** (dla małych obszarów)
|
||||
|
||||
### Bellman-Ford
|
||||
- **Routing w sieciach** (RIP protocol - prostszy)
|
||||
- **Arbitraż walutowy** (szukanie cykli ujemnych = zysk!)
|
||||
- **Systemy z "karami"** (ujemne wagi = bonusy)
|
||||
|
||||
### A*
|
||||
- **Gry komputerowe** - pathfinding NPC, RTS
|
||||
- **Robotyka** - planowanie ruchu
|
||||
- **Puzzle** - 8-puzzle, 15-puzzle
|
||||
- **Nawigacja** - gdy znamy pozycję celu
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Relaksacja - wspólny element
|
||||
|
||||
Wszystkie trzy algorytmy używają **relaksacji krawędzi**:
|
||||
|
||||
```
|
||||
RELAX(u, v, w):
|
||||
if d[u] + w(u,v) < d[v]:
|
||||
d[v] ← d[u] + w(u,v)
|
||||
π[v] ← u
|
||||
```
|
||||
|
||||
**Różnica w kolejności relaksacji:**
|
||||
- **Dijkstra:** Relaksuje krawędzie wychodzące z wierzchołka o minimalnym d[v]
|
||||
- **Bellman-Ford:** Relaksuje wszystkie krawędzie w każdej z |V|-1 iteracji
|
||||
- **A*:** Relaksuje krawędzie wychodzące z wierzchołka o minimalnym f[v] = g[v] + h[v]
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "DBF - Dijkstra Bellman Ford"
|
||||
- **D**ijkstra = **D**odatnie wagi tylko
|
||||
- **B**ellman-Ford = **B**ez ograniczeń (ujemne OK)
|
||||
- **F**ind cycles = wykrywa cykle ujemne
|
||||
|
||||
### "A* = A sterowana"
|
||||
- **A**lgorytm **A**sterowany heurystyką
|
||||
- **A**le heurystyka musi być **A**dmissible
|
||||
|
||||
### "GREP" dla Dijkstry:
|
||||
- **G**reedy (zachłanny)
|
||||
- **R**elaksacja krawędzi
|
||||
- **E**xtract-min z kolejki
|
||||
- **P**riority queue kluczowa
|
||||
|
||||
### "VE" dla Bellman-Ford:
|
||||
- **V**-1 iteracji
|
||||
- **E** krawędzi relaksowanych w każdej
|
||||
|
||||
### "HIG" dla A*:
|
||||
- **H**eurystyka kieruje
|
||||
- **I**nformed search
|
||||
- **G**oal-oriented (zorientowany na cel)
|
||||
|
||||
### Złożoność - "Dijkstra lubi VlogV, Bellman lubi VE":
|
||||
- Dijkstra: O(V log V + E) z kopcem Fibonacciego
|
||||
- Bellman-Ford: O(V · E)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Pokaż działanie algorytmu Dijkstry na przykładzie"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
```
|
||||
Graf:
|
||||
A ---(1)--- B
|
||||
| |
|
||||
(4) (2)
|
||||
| |
|
||||
S ---(2)--- C ---(1)--- D
|
||||
```
|
||||
|
||||
| Krok | Przetwarzany | d[S] | d[A] | d[B] | d[C] | d[D] |
|
||||
|------|--------------|------|------|------|------|------|
|
||||
| Init | - | 0 | ∞ | ∞ | ∞ | ∞ |
|
||||
| 1 | S | 0 | 4 | ∞ | 2 | ∞ |
|
||||
| 2 | C | 0 | 4 | 4 | 2 | 3 |
|
||||
| 3 | D | 0 | 4 | 4 | 2 | 3 |
|
||||
| 4 | A | 0 | 4 | 4 | 2 | 3 |
|
||||
| 5 | B | 0 | 4 | 4 | 2 | 3 |
|
||||
|
||||
Najkrótsza ścieżka S→D: S → C → D (koszt 3)
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Jak wykryć ujemny cykl algorytmem Bellman-Forda?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
Po |V|-1 iteracjach, wykonujemy jeszcze jedną iterację po wszystkich krawędziach:
|
||||
|
||||
```python
|
||||
# Po głównej pętli
|
||||
for (u, v) in edges:
|
||||
if d[u] + w[u][v] < d[v]:
|
||||
return "UJEMNY CYKL ISTNIEJE"
|
||||
```
|
||||
|
||||
**Dlaczego to działa?**
|
||||
- Najkrótsza ścieżka prosta (bez cykli) ma co najwyżej |V|-1 krawędzi
|
||||
- Po |V|-1 iteracjach wszystkie takie ścieżki są znalezione
|
||||
- Jeśli |V|-ta iteracja poprawia cokolwiek → ścieżka przez cykl jest krótsza → cykl ujemny
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Dlaczego heurystyka musi być dopuszczalna w A*?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Dopuszczalność:** h(n) ≤ h*(n) - nigdy nie przeszacowujemy kosztu
|
||||
|
||||
**Dowód optymalności:**
|
||||
1. Załóżmy, że A* zwraca ścieżkę P o koszcie g(P)
|
||||
2. Niech P* będzie optymalną ścieżką o koszcie g(P*)
|
||||
3. Jeśli g(P) > g(P*), to w momencie zwrócenia P:
|
||||
- Jakiś węzeł n na P* był w OPEN
|
||||
- f(n) = g(n) + h(n) ≤ g(n) + h*(n) = g(P*) < g(P) = f(goal)
|
||||
- Ale A* wybrał goal zamiast n → sprzeczność!
|
||||
|
||||
**Przykład niedopuszczalnej heurystyki:**
|
||||
```
|
||||
S ---(1)--- A ---(1)--- T
|
||||
\ /
|
||||
\---(10)--------/
|
||||
```
|
||||
Jeśli h(A) = 5 (a h*(A) = 1), A* może wybrać ścieżkę S→T (koszt 10) zamiast S→A→T (koszt 2).
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Porównaj A* z Dijkstrą - kiedy użyć którego?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Sytuacja | Lepszy algorytm |
|
||||
|----------|-----------------|
|
||||
| Szukam ścieżki do WSZYSTKICH wierzchołków | **Dijkstra** |
|
||||
| Szukam ścieżki do JEDNEGO celu | **A*** |
|
||||
| Nie mam dobrej heurystyki | **Dijkstra** |
|
||||
| Graf ma strukturę geometryczną (mapa 2D) | **A*** |
|
||||
| Graf abstrakcyjny (np. stanów) | Zależy od heurystyki |
|
||||
| Potrzebuję gwarancji optymalności | Oba (A* z dopuszczalną h) |
|
||||
|
||||
**Praktycznie:**
|
||||
- A* z h(n)=0 to Dijkstra
|
||||
- Dobra heurystyka może zredukować eksplorację o rzędy wielkości
|
||||
- W grach A* jest standardem (Unity NavMesh używa wariantu A*)
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co to jest algorytm Floyd-Warshalla i jak się ma do omawianych?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Floyd-Warshall** rozwiązuje **All-Pairs Shortest Path (APSP)**:
|
||||
- Znajduje najkrótsze ścieżki między WSZYSTKIMI parami wierzchołków
|
||||
- Złożoność: O(V³)
|
||||
- Działa z ujemnymi wagami (wykrywa cykle ujemne)
|
||||
- Programowanie dynamiczne
|
||||
|
||||
```
|
||||
for k ← 1 to V:
|
||||
for i ← 1 to V:
|
||||
for j ← 1 to V:
|
||||
d[i][j] ← min(d[i][j], d[i][k] + d[k][j])
|
||||
```
|
||||
|
||||
**Porównanie:**
|
||||
- SSSP z dodatnimi wagami: Dijkstra O(V log V + E)
|
||||
- SSSP z ujemnymi wagami: Bellman-Ford O(VE)
|
||||
- APSP: Floyd-Warshall O(V³) lub V × Dijkstra O(V² log V + VE)
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Jakie są warianty algorytmu Dijkstry?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
1. **Bidirectional Dijkstra:**
|
||||
- Równoczesne przeszukiwanie z s i z t
|
||||
- Spotykają się w środku
|
||||
- ~2× szybszy w praktyce
|
||||
|
||||
2. **Dial's Algorithm:**
|
||||
- Dla małych, całkowitych wag [0, C]
|
||||
- O(V + E + C) zamiast O((V+E) log V)
|
||||
- Używa "bucket queue"
|
||||
|
||||
3. **Johnson's Algorithm:**
|
||||
- APSP dla grafów rzadkich
|
||||
- Używa Bellman-Ford + V × Dijkstra
|
||||
- O(VE + V² log V) - lepszy niż Floyd-Warshall dla rzadkich grafów
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **Dijkstra** = zachłanny, tylko nieujemne wagi, najszybszy dla SSSP
|
||||
2. **Bellman-Ford** = prog. dynamiczne, ujemne wagi OK, wykrywa cykle ujemne
|
||||
3. **A*** = Dijkstra + heurystyka, szybki dla single-pair, wymaga h admissible
|
||||
4. **Relaksacja** = wspólna operacja, różnica w kolejności
|
||||
5. **Złożoność:** Dijkstra O(V log V + E), BF O(VE), A* zależy od h
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Cormen, Leiserson, Rivest, Stein - "Introduction to Algorithms" (CLRS)
|
||||
2. Sedgewick, Wayne - "Algorithms"
|
||||
3. Hart, Nilsson, Raphael - "A Formal Basis for the Heuristic Determination of Minimum Cost Paths" (1968)
|
||||
4. Red Blob Games - "Introduction to A*" (online, interaktywny)
|
||||
@ -1,515 +0,0 @@
|
||||
# Pytanie 3: Redundancja i normalizacja w relacyjnej bazie danych
|
||||
|
||||
## Pytanie
|
||||
**"Omówić zagadnienia redundancji i normalizacji w relacyjnej bazie danych oraz wynikające z tego wymagania."**
|
||||
|
||||
Przedmiot: BD2 (Bazy Danych 2)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
**Redundancja** (nadmiarowość) i **normalizacja** to dwa fundamentalne, przeciwstawne pojęcia w projektowaniu relacyjnych baz danych:
|
||||
|
||||
- **Redundancja** = niepożądane powtarzanie danych
|
||||
- **Normalizacja** = proces eliminacji redundancji poprzez dekompozycję relacji
|
||||
|
||||
---
|
||||
|
||||
## 1. Redundancja danych
|
||||
|
||||
### Definicja
|
||||
**Redundancja** występuje, gdy ta sama informacja jest przechowywana w wielu miejscach bazy danych, co prowadzi do:
|
||||
- Marnowania pamięci
|
||||
- Niespójności danych (anomalii)
|
||||
- Trudności w utrzymaniu
|
||||
|
||||
### Anomalie wynikające z redundancji
|
||||
|
||||
#### Przykład - tabela z redundancją:
|
||||
|
||||
| StudentID | Imię | Nazwisko | KursID | NazwaKursu | Prowadzący |
|
||||
|-----------|------|----------|--------|------------|------------|
|
||||
| 1 | Jan | Kowalski | BD1 | Bazy Danych | Dr Nowak |
|
||||
| 1 | Jan | Kowalski | AISDI | Algorytmy | Prof. Wiśniewski |
|
||||
| 2 | Anna | Nowak | BD1 | Bazy Danych | Dr Nowak |
|
||||
| 2 | Anna | Nowak | BD1 | Bazy Danych | Dr Nowak |
|
||||
|
||||
**Problemy:**
|
||||
- "Bazy Danych" i "Dr Nowak" powtórzono 3 razy
|
||||
- "Jan Kowalski" powtórzono 2 razy
|
||||
|
||||
### Trzy typy anomalii
|
||||
|
||||
#### 1. Anomalia wstawiania (Insertion Anomaly)
|
||||
**Problem:** Nie można dodać danych bez dodania innych, niepotrzebnych danych.
|
||||
|
||||
**Przykład:** Nie możemy dodać nowego kursu "Sieci komputerowe" bez przypisania do niego studenta.
|
||||
|
||||
#### 2. Anomalia usuwania (Deletion Anomaly)
|
||||
**Problem:** Usunięcie danych powoduje niezamierzoną utratę innych informacji.
|
||||
|
||||
**Przykład:** Jeśli Anna Nowak zrezygnuje ze studiów, tracimy informację, że kurs BD1 prowadzi Dr Nowak (jeśli była jedynym studentem tego kursu).
|
||||
|
||||
#### 3. Anomalia modyfikacji (Update Anomaly)
|
||||
**Problem:** Zmiana jednej informacji wymaga modyfikacji wielu wierszy.
|
||||
|
||||
**Przykład:** Jeśli Dr Nowak zmieni nazwisko, musimy zaktualizować wszystkie wiersze z kursem BD1.
|
||||
|
||||
---
|
||||
|
||||
## 2. Normalizacja
|
||||
|
||||
### Definicja
|
||||
**Normalizacja** to proces organizowania danych w bazie w celu:
|
||||
- Eliminacji redundancji
|
||||
- Zapewnienia integralności danych
|
||||
- Ułatwienia utrzymania i modyfikacji
|
||||
|
||||
### Podstawowe pojęcia
|
||||
|
||||
#### Zależność funkcyjna (Functional Dependency - FD)
|
||||
**X → Y** oznacza: wartość X jednoznacznie określa wartość Y
|
||||
|
||||
**Przykład:** StudentID → (Imię, Nazwisko)
|
||||
- Znając StudentID, możemy jednoznacznie określić imię i nazwisko
|
||||
|
||||
#### Klucz główny (Primary Key)
|
||||
Minimalny zbiór atrybutów, który jednoznacznie identyfikuje krotkę (wiersz).
|
||||
|
||||
#### Klucz kandydujący (Candidate Key)
|
||||
Każdy minimalny zbiór atrybutów, który mógłby być kluczem głównym.
|
||||
|
||||
#### Atrybut pierwszy (Prime Attribute)
|
||||
Atrybut należący do jakiegokolwiek klucza kandydującego.
|
||||
|
||||
#### Atrybut wtórny (Non-prime Attribute)
|
||||
Atrybut nienależący do żadnego klucza kandydującego.
|
||||
|
||||
---
|
||||
|
||||
## 3. Postacie normalne
|
||||
|
||||
### Hierarchia postaci normalnych
|
||||
|
||||
```
|
||||
5NF ⊂ 4NF ⊂ BCNF ⊂ 3NF ⊂ 2NF ⊂ 1NF
|
||||
```
|
||||
|
||||
Każda wyższa postać implikuje niższą.
|
||||
|
||||
---
|
||||
|
||||
### 1NF - Pierwsza Postać Normalna
|
||||
|
||||
#### Wymagania:
|
||||
1. **Atomowość wartości** - każda komórka zawiera jedną, niepodzielną wartość
|
||||
2. **Brak powtarzających się grup** - brak tablic/list w komórkach
|
||||
3. **Istnieje klucz główny**
|
||||
|
||||
#### ❌ Naruszenie 1NF:
|
||||
|
||||
| StudentID | Imię | Telefony |
|
||||
|-----------|------|----------|
|
||||
| 1 | Jan | 123456, 789012 |
|
||||
|
||||
#### ✅ Po normalizacji do 1NF:
|
||||
|
||||
**Studenci:**
|
||||
| StudentID | Imię |
|
||||
|-----------|------|
|
||||
| 1 | Jan |
|
||||
|
||||
**Telefony:**
|
||||
| StudentID | Telefon |
|
||||
|-----------|---------|
|
||||
| 1 | 123456 |
|
||||
| 1 | 789012 |
|
||||
|
||||
---
|
||||
|
||||
### 2NF - Druga Postać Normalna
|
||||
|
||||
#### Wymagania:
|
||||
1. Spełnia 1NF
|
||||
2. **Każdy atrybut wtórny jest w pełni funkcyjnie zależny od całego klucza głównego** (nie od jego części)
|
||||
|
||||
Dotyczy tylko tabel z **kluczem złożonym** (wielokolumnowym).
|
||||
|
||||
#### ❌ Naruszenie 2NF:
|
||||
|
||||
| StudentID | KursID | NazwaKursu | Ocena |
|
||||
|-----------|--------|------------|-------|
|
||||
| 1 | BD1 | Bazy Danych | 5 |
|
||||
| 2 | BD1 | Bazy Danych | 4 |
|
||||
|
||||
Klucz: (StudentID, KursID)
|
||||
- NazwaKursu zależy tylko od KursID, nie od całego klucza!
|
||||
- KursID → NazwaKursu (częściowa zależność)
|
||||
|
||||
#### ✅ Po normalizacji do 2NF:
|
||||
|
||||
**Oceny:**
|
||||
| StudentID | KursID | Ocena |
|
||||
|-----------|--------|-------|
|
||||
| 1 | BD1 | 5 |
|
||||
| 2 | BD1 | 4 |
|
||||
|
||||
**Kursy:**
|
||||
| KursID | NazwaKursu |
|
||||
|--------|------------|
|
||||
| BD1 | Bazy Danych |
|
||||
|
||||
---
|
||||
|
||||
### 3NF - Trzecia Postać Normalna
|
||||
|
||||
#### Wymagania:
|
||||
1. Spełnia 2NF
|
||||
2. **Brak przechodnich zależności funkcyjnych** - atrybuty wtórne nie zależą od innych atrybutów wtórnych
|
||||
|
||||
**Formalnie:** Dla każdej nietrywialnej FD X → A:
|
||||
- X jest nadkluczem, LUB
|
||||
- A jest atrybutem pierwszym (należy do klucza)
|
||||
|
||||
#### ❌ Naruszenie 3NF:
|
||||
|
||||
| StudentID | Imię | WydziałID | NazwaWydziału |
|
||||
|-----------|------|-----------|---------------|
|
||||
| 1 | Jan | W4 | Elektroniki |
|
||||
|
||||
Klucz: StudentID
|
||||
- StudentID → WydziałID → NazwaWydziału (przechodnia zależność!)
|
||||
|
||||
#### ✅ Po normalizacji do 3NF:
|
||||
|
||||
**Studenci:**
|
||||
| StudentID | Imię | WydziałID |
|
||||
|-----------|------|-----------|
|
||||
| 1 | Jan | W4 |
|
||||
|
||||
**Wydziały:**
|
||||
| WydziałID | NazwaWydziału |
|
||||
|-----------|---------------|
|
||||
| W4 | Elektroniki |
|
||||
|
||||
---
|
||||
|
||||
### BCNF - Postać Normalna Boyce'a-Codda
|
||||
|
||||
#### Wymagania:
|
||||
1. Spełnia 3NF
|
||||
2. **Dla każdej nietrywialnej FD X → Y, X jest nadkluczem**
|
||||
|
||||
BCNF jest silniejsza niż 3NF - eliminuje przypadki, gdy atrybut pierwszy zależy od atrybutu niebędącego nadkluczem.
|
||||
|
||||
#### ❌ Naruszenie BCNF (ale spełnia 3NF):
|
||||
|
||||
| Student | Przedmiot | Prowadzący |
|
||||
|---------|-----------|------------|
|
||||
| Jan | Bazy Danych | Dr Nowak |
|
||||
| Jan | Algorytmy | Dr Nowak |
|
||||
| Anna | Bazy Danych | Dr Kowalski |
|
||||
|
||||
Klucze kandydujące: {Student, Przedmiot}, {Student, Prowadzący}
|
||||
- Prowadzący → Przedmiot (jeden prowadzący = jeden przedmiot)
|
||||
- Ale Prowadzący nie jest nadkluczem!
|
||||
|
||||
#### ✅ Po normalizacji do BCNF:
|
||||
|
||||
**Zapisy:**
|
||||
| Student | Prowadzący |
|
||||
|---------|------------|
|
||||
| Jan | Dr Nowak |
|
||||
| Anna | Dr Kowalski |
|
||||
|
||||
**Prowadzący:**
|
||||
| Prowadzący | Przedmiot |
|
||||
|------------|-----------|
|
||||
| Dr Nowak | Bazy Danych |
|
||||
| Dr Kowalski | Bazy Danych |
|
||||
|
||||
---
|
||||
|
||||
### 4NF - Czwarta Postać Normalna
|
||||
|
||||
#### Wymagania:
|
||||
1. Spełnia BCNF
|
||||
2. **Brak nietrywialnych zależności wielowartościowych** (MVD - Multivalued Dependencies)
|
||||
|
||||
**Zależność wielowartościowa X ↠ Y:** Dla danego X istnieje zbiór wartości Y niezależny od innych atrybutów.
|
||||
|
||||
#### ❌ Naruszenie 4NF:
|
||||
|
||||
| Pracownik | Umiejętność | Język |
|
||||
|-----------|-------------|-------|
|
||||
| Jan | Java | Angielski |
|
||||
| Jan | Java | Niemiecki |
|
||||
| Jan | Python | Angielski |
|
||||
| Jan | Python | Niemiecki |
|
||||
|
||||
Pracownik ↠ Umiejętność i Pracownik ↠ Język (niezależne!)
|
||||
|
||||
#### ✅ Po normalizacji do 4NF:
|
||||
|
||||
**PracownikUmiejętności:**
|
||||
| Pracownik | Umiejętność |
|
||||
|-----------|-------------|
|
||||
| Jan | Java |
|
||||
| Jan | Python |
|
||||
|
||||
**PracownikJęzyki:**
|
||||
| Pracownik | Język |
|
||||
|-----------|-------|
|
||||
| Jan | Angielski |
|
||||
| Jan | Niemiecki |
|
||||
|
||||
---
|
||||
|
||||
### 5NF - Piąta Postać Normalna (PJNF)
|
||||
|
||||
#### Wymagania:
|
||||
1. Spełnia 4NF
|
||||
2. **Brak zależności połączeniowych** (Join Dependencies)
|
||||
3. Dekompozycja bez strat tylko na podstawie kluczy kandydujących
|
||||
|
||||
5NF eliminuje redundancję wynikającą z niemożliwości odtworzenia oryginalnej relacji przez złączenie jej projekcji.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tabela porównawcza postaci normalnych
|
||||
|
||||
| Postać | Eliminuje | Wymaga |
|
||||
|--------|-----------|--------|
|
||||
| **1NF** | Wielowartościowe atrybuty | Atomowość, klucz główny |
|
||||
| **2NF** | Częściowe zależności | Pełna zależność od klucza |
|
||||
| **3NF** | Przechodnie zależności | Brak X → A gdzie X nie jest nadkluczem i A nie jest pierwszym |
|
||||
| **BCNF** | Zależności od nie-nadkluczy | Każdy determinant jest nadkluczem |
|
||||
| **4NF** | Wielowartościowe zależności | Brak nietrywialnych MVD |
|
||||
| **5NF** | Zależności połączeniowe | Dekompozycja tylko przez klucze |
|
||||
|
||||
---
|
||||
|
||||
## 4. Proces normalizacji
|
||||
|
||||
### Algorytm dekompozycji do 3NF
|
||||
|
||||
1. **Znajdź pokrycie kanoniczne** zbioru zależności funkcyjnych
|
||||
2. **Dla każdej FD X → A** utwórz relację R(X, A)
|
||||
3. **Jeśli żadna relacja nie zawiera klucza kandydującego**, dodaj relację z atrybutami klucza
|
||||
4. **Usuń relacje zawarte w innych relacjach**
|
||||
|
||||
### Własności dobrej dekompozycji
|
||||
|
||||
#### 1. Bezstratność (Lossless Join)
|
||||
Po dekompozycji można odtworzyć oryginalną relację przez złączenie naturalne.
|
||||
|
||||
**Twierdzenie:** Dekompozycja R na R₁ i R₂ jest bezstratna wtw gdy:
|
||||
- R₁ ∩ R₂ → R₁, lub
|
||||
- R₁ ∩ R₂ → R₂
|
||||
|
||||
#### 2. Zachowanie zależności (Dependency Preservation)
|
||||
Wszystkie oryginalne FD można zweryfikować w pojedynczych tabelach wynikowych (bez złączeń).
|
||||
|
||||
---
|
||||
|
||||
## 5. Denormalizacja
|
||||
|
||||
### Kiedy stosować?
|
||||
- **Optymalizacja wydajności** - złączenia są kosztowne
|
||||
- **Systemy OLAP/hurtownie danych** - dane głównie odczytywane
|
||||
- **Raportowanie** - predefiniowane zapytania
|
||||
|
||||
### Techniki denormalizacji:
|
||||
1. **Dodanie redundantnych kolumn** - unikanie złączeń
|
||||
2. **Tabele podsumowujące** - agregaty
|
||||
3. **Tabele historyczne** - snapshoty
|
||||
4. **Materializowane widoki** - cache wyników
|
||||
|
||||
### Kompromis:
|
||||
```
|
||||
NORMALIZACJA ←————————————→ DENORMALIZACJA
|
||||
Integralność Wydajność odczytu
|
||||
Mniej redundancji Więcej redundancji
|
||||
Wolniejsze odczyty Szybsze odczyty
|
||||
Szybsze zapisy Wolniejsze zapisy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "1-2-3-BC" dla postaci normalnych:
|
||||
- **1**NF = **1** wartość w komórce (atomowość)
|
||||
- **2**NF = **2** słowa: "pełna zależność" (od całego klucza)
|
||||
- **3**NF = **3** słowa: "brak przechodniości" (A→B→C eliminowane)
|
||||
- **BC**NF = **B**ardzo **C**isty (każdy determinant = nadklucz)
|
||||
|
||||
### "AIU" dla anomalii:
|
||||
- **A**nomalia wstawiania (**A**dding) - nie można dodać
|
||||
- **I**nsercja usuwania (**I**nterrupts) - traci dane przy DELETE
|
||||
- **U**pdate modyfikacji - trzeba zmieniać wiele wierszy
|
||||
|
||||
### "KAP" dla kluczy:
|
||||
- **K**lucz główny - wybrany unikalny identyfikator
|
||||
- **A**lternatywny (kandydujący) - mógłby być głównym
|
||||
- **P**ierwszy atrybut - należy do jakiegoś klucza
|
||||
|
||||
### Wzór na 3NF:
|
||||
> "Każdy atrybut zależy od **klucza**, **całego klucza** i **tylko od klucza**."
|
||||
> (The key, the whole key, and nothing but the key - so help me Codd!)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Podaj przykład dekompozycji do 3NF z zachowaniem bezstratności"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Relacja:** R(A, B, C, D)
|
||||
**FD:** A → B, B → C, C → D
|
||||
|
||||
**Klucz:** A
|
||||
|
||||
**Dekompozycja:**
|
||||
1. R₁(A, B) - z FD A → B
|
||||
2. R₂(B, C) - z FD B → C
|
||||
3. R₃(C, D) - z FD C → D
|
||||
|
||||
**Sprawdzenie bezstratności:**
|
||||
- R₁ ∩ R₂ = {B}, B → C (B jest kluczem R₂) ✓
|
||||
- R₂ ∩ R₃ = {C}, C → D (C jest kluczem R₃) ✓
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Czym się różni 3NF od BCNF?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Cecha | 3NF | BCNF |
|
||||
|-------|-----|------|
|
||||
| **Warunek** | X nadklucz LUB A pierwszy | X zawsze nadklucz |
|
||||
| **Siła** | Słabsza | Silniejsza |
|
||||
| **Dekompozycja** | Zachowuje zależności | Może nie zachować |
|
||||
| **Redundancja** | Możliwa minimalna | Brak |
|
||||
|
||||
**Przykład różnicy:**
|
||||
|
||||
R(Student, Przedmiot, Prowadzący)
|
||||
- Klucze: {Student, Przedmiot}, {Student, Prowadzący}
|
||||
- FD: Prowadzący → Przedmiot
|
||||
|
||||
**3NF:** ✅ spełniona (Przedmiot jest atrybutem pierwszym)
|
||||
**BCNF:** ❌ naruszona (Prowadzący nie jest nadkluczem)
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Jak sprawdzić, czy relacja jest w 3NF?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Algorytm:**
|
||||
1. Znajdź wszystkie nietrywialne FD
|
||||
2. Dla każdej FD X → A sprawdź:
|
||||
- Czy X jest nadkluczem? → OK
|
||||
- Czy A jest atrybutem pierwszym? → OK
|
||||
- Jeśli żadne → NIE jest w 3NF
|
||||
|
||||
**Przykład:**
|
||||
R(A, B, C), FD: {A → B, B → C}
|
||||
|
||||
Klucz: A
|
||||
- A → B: A jest nadkluczem ✓
|
||||
- B → C: B nie jest nadkluczem, C nie jest pierwszy ✗
|
||||
|
||||
**Wniosek:** R NIE jest w 3NF
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Kiedy normalizacja może zaszkodzić?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
1. **Systemy OLAP/raportowe:**
|
||||
- Złączenia wielu tabel są kosztowne
|
||||
- Dane głównie odczytywane, rzadko modyfikowane
|
||||
- Lepiej: denormalizacja, schematy gwiazdy/płatka śniegu
|
||||
|
||||
2. **Aplikacje o wysokiej wydajności:**
|
||||
- Każde złączenie to koszt
|
||||
- Cache'owanie i replikacja danych może być szybsze
|
||||
|
||||
3. **Systemy czasu rzeczywistego:**
|
||||
- Determinizm ważniejszy niż oszczędność miejsca
|
||||
- Redundancja może przyspieszyć dostęp
|
||||
|
||||
**Zasada:** Normalizuj dla OLTP, denormalizuj dla OLAP
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co to jest zależność wielowartościowa (MVD)?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Zależność wielowartościowa X ↠ Y:**
|
||||
Dla każdej wartości X istnieje zbiór wartości Y, który jest niezależny od innych atrybutów relacji.
|
||||
|
||||
**Formalnie:** X ↠ Y w R(X, Y, Z) gdy:
|
||||
Dla każdych dwóch krotek t₁, t₂ takich że t₁[X] = t₂[X]:
|
||||
istnieje krotka t₃ gdzie:
|
||||
- t₃[X] = t₁[X] = t₂[X]
|
||||
- t₃[Y] = t₁[Y]
|
||||
- t₃[Z] = t₂[Z]
|
||||
|
||||
**Intuicja:** Y i Z są "niezależne" przy danym X.
|
||||
|
||||
**Przykład:**
|
||||
Pracownik ↠ Umiejętność (niezależne od języka)
|
||||
Pracownik ↠ Język (niezależne od umiejętności)
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Wyjaśnij pojęcie pokrycia kanonicznego"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Pokrycie kanoniczne** to minimalny zbiór FD równoważny oryginalnemu.
|
||||
|
||||
**Właściwości:**
|
||||
1. Prawa strona każdej FD ma jeden atrybut
|
||||
2. Lewa strona jest minimalna (brak nadmiarowych atrybutów)
|
||||
3. Brak redundantnych FD
|
||||
|
||||
**Algorytm:**
|
||||
1. Rozłóż prawe strony: A → BC na A → B, A → C
|
||||
2. Usuń nadmiarowe atrybuty z lewych stron
|
||||
3. Usuń redundantne FD (te wynikające z innych)
|
||||
|
||||
**Przykład:**
|
||||
F = {A → BC, B → C, A → B, AB → C}
|
||||
|
||||
Pokrycie kanoniczne:
|
||||
Fc = {A → B, B → C}
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **Redundancja** = powtarzanie danych → anomalie AIU
|
||||
2. **Normalizacja** = dekompozycja eliminująca redundancję
|
||||
3. **3NF** = standard praktyczny (zachowuje zależności)
|
||||
4. **BCNF** = silniejsza, ale może gubić zależności
|
||||
5. **Wzór 3NF:** "klucz, cały klucz, tylko klucz"
|
||||
6. **Kompromis:** normalizacja vs wydajność
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Date, C.J. - "An Introduction to Database Systems"
|
||||
2. Elmasri, Navathe - "Fundamentals of Database Systems"
|
||||
3. Codd, E.F. - "A Relational Model of Data for Large Shared Data Banks" (1970)
|
||||
4. Garcia-Molina, Ullman, Widom - "Database Systems: The Complete Book"
|
||||
@ -1,434 +0,0 @@
|
||||
# Pytanie 4: Baza danych jako fundament systemów informatycznych
|
||||
|
||||
## Pytanie
|
||||
**"Dlaczego baza danych stanowi dobry fundament do budowy wielu systemów informatycznych?"**
|
||||
|
||||
Przedmiot: BD2 (Bazy Danych 2)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
Baza danych to **centralny komponent** większości systemów informatycznych, ponieważ zapewnia:
|
||||
- Trwałe przechowywanie danych
|
||||
- Współbieżny dostęp
|
||||
- Integralność i spójność
|
||||
- Niezależność danych od aplikacji
|
||||
|
||||
---
|
||||
|
||||
## 1. Kluczowe właściwości baz danych (ACID)
|
||||
|
||||
### Transakcyjność - gwarancje ACID
|
||||
|
||||
| Właściwość | Opis | Znaczenie |
|
||||
|------------|------|-----------|
|
||||
| **A**tomicity (Atomowość) | Transakcja wykonuje się w całości lub wcale | Brak częściowych zmian |
|
||||
| **C**onsistency (Spójność) | Dane przechodzą z jednego spójnego stanu w drugi | Reguły biznesowe zawsze spełnione |
|
||||
| **I**solation (Izolacja) | Równoległe transakcje nie widzą swoich zmian | Brak efektów ubocznych |
|
||||
| **D**urability (Trwałość) | Zatwierdzone zmiany przetrwają awarie | Bezpieczeństwo danych |
|
||||
|
||||
### Przykład znaczenia ACID
|
||||
|
||||
**Przelew bankowy:**
|
||||
```sql
|
||||
BEGIN TRANSACTION;
|
||||
UPDATE Konta SET saldo = saldo - 1000 WHERE id = 1; -- Odejmij
|
||||
UPDATE Konta SET saldo = saldo + 1000 WHERE id = 2; -- Dodaj
|
||||
COMMIT;
|
||||
```
|
||||
|
||||
Bez ACID:
|
||||
- Awaria po pierwszym UPDATE = utrata pieniędzy (brak atomowości)
|
||||
- Saldo < 0 mimo ograniczenia (brak spójności)
|
||||
- Inna transakcja widzi stan pośredni (brak izolacji)
|
||||
- Po zatwierdzeniu dane giną (brak trwałości)
|
||||
|
||||
---
|
||||
|
||||
## 2. Niezależność danych
|
||||
|
||||
### Trójpoziomowa architektura ANSI/SPARC
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Poziom zewnętrzny (widoki) │ ← Aplikacje widzą różne "okna"
|
||||
├─────────────────────────────────────────┤
|
||||
│ Poziom konceptualny (logiczny) │ ← Struktura logiczna danych
|
||||
├─────────────────────────────────────────┤
|
||||
│ Poziom wewnętrzny (fizyczny) │ ← Sposób przechowywania
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Rodzaje niezależności
|
||||
|
||||
#### 1. Niezależność fizyczna
|
||||
Zmiana sposobu przechowywania (indeksy, partycjonowanie, kompresja) **nie wpływa** na aplikacje.
|
||||
|
||||
**Przykład:** Dodanie indeksu przyspiesza zapytania bez zmiany kodu aplikacji.
|
||||
|
||||
#### 2. Niezależność logiczna
|
||||
Zmiana struktury logicznej (dodanie kolumn, widoków) **minimalizuje** wpływ na aplikacje.
|
||||
|
||||
**Przykład:** Podział tabeli na dwie + widok łączący = stare aplikacje działają bez zmian.
|
||||
|
||||
---
|
||||
|
||||
## 3. Współbieżność i wielodostęp
|
||||
|
||||
### Problem współbieżności
|
||||
|
||||
Wiele aplikacji/użytkowników **jednocześnie** korzysta z tych samych danych.
|
||||
|
||||
### Mechanizmy kontroli współbieżności
|
||||
|
||||
| Mechanizm | Opis | Zastosowanie |
|
||||
|-----------|------|--------------|
|
||||
| **Blokady (Locks)** | Pesymistyczne - blokuj przed dostępem | Wysokie konflikty |
|
||||
| **MVCC** | Optymistyczne - wersjonowanie | Dużo odczytów |
|
||||
| **Timestamp Ordering** | Szeregowanie po czasie | Systemy rozproszone |
|
||||
| **Snapshot Isolation** | Izolacja migawkowa | Analityka |
|
||||
|
||||
### Poziomy izolacji (SQL Standard)
|
||||
|
||||
| Poziom | Dirty Read | Non-repeatable Read | Phantom Read |
|
||||
|--------|------------|---------------------|--------------|
|
||||
| READ UNCOMMITTED | Możliwy | Możliwy | Możliwy |
|
||||
| READ COMMITTED | Niemożliwy | Możliwy | Możliwy |
|
||||
| REPEATABLE READ | Niemożliwy | Niemożliwy | Możliwy |
|
||||
| SERIALIZABLE | Niemożliwy | Niemożliwy | Niemożliwy |
|
||||
|
||||
---
|
||||
|
||||
## 4. Integralność danych
|
||||
|
||||
### Mechanizmy wymuszania integralności
|
||||
|
||||
#### 1. Ograniczenia deklaratywne
|
||||
```sql
|
||||
CREATE TABLE Zamowienia (
|
||||
id INT PRIMARY KEY, -- Klucz główny
|
||||
klient_id INT NOT NULL, -- NOT NULL
|
||||
data DATE DEFAULT CURRENT_DATE, -- Wartość domyślna
|
||||
kwota DECIMAL(10,2) CHECK (kwota > 0), -- Warunek CHECK
|
||||
FOREIGN KEY (klient_id) REFERENCES Klienci(id) -- Klucz obcy
|
||||
);
|
||||
```
|
||||
|
||||
#### 2. Wyzwalacze (Triggers)
|
||||
```sql
|
||||
CREATE TRIGGER sprawdz_saldo
|
||||
BEFORE UPDATE ON Konta
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
IF NEW.saldo < 0 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Brak środków';
|
||||
END IF;
|
||||
END;
|
||||
```
|
||||
|
||||
#### 3. Procedury składowane
|
||||
Logika biznesowa w bazie = jednolite reguły dla wszystkich aplikacji.
|
||||
|
||||
---
|
||||
|
||||
## 5. Wydajność i optymalizacja
|
||||
|
||||
### Optymalizator zapytań
|
||||
|
||||
SZBD automatycznie:
|
||||
1. **Analizuje zapytanie** (parsing)
|
||||
2. **Generuje plany wykonania** (alternatywy)
|
||||
3. **Szacuje koszty** (statystyki)
|
||||
4. **Wybiera najlepszy plan** (optymalizacja)
|
||||
|
||||
### Mechanizmy wydajności
|
||||
|
||||
| Mechanizm | Funkcja |
|
||||
|-----------|---------|
|
||||
| **Indeksy** | Szybkie wyszukiwanie (B-tree, Hash, GiST) |
|
||||
| **Buforowanie** | Cache często używanych danych |
|
||||
| **Partycjonowanie** | Podział dużych tabel |
|
||||
| **Materializowane widoki** | Prekompilowane złączenia |
|
||||
| **Query cache** | Cache wyników zapytań |
|
||||
|
||||
---
|
||||
|
||||
## 6. Bezpieczeństwo
|
||||
|
||||
### Wielopoziomowe zabezpieczenia
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Autoryzacja (GRANT/REVOKE) │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Autentykacja (użytkownicy, role) │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Szyfrowanie (TDE, SSL/TLS) │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Audyt (logi, śledzenie zmian) │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Kontrola dostępu
|
||||
```sql
|
||||
-- Tworzenie roli
|
||||
CREATE ROLE analityk;
|
||||
GRANT SELECT ON Sprzedaz TO analityk;
|
||||
|
||||
-- Przypisanie użytkownika
|
||||
GRANT analityk TO jan_kowalski;
|
||||
|
||||
-- Widok ograniczający dane
|
||||
CREATE VIEW MojeZamowienia AS
|
||||
SELECT * FROM Zamowienia WHERE sprzedawca = CURRENT_USER;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Skalowalność i dostępność
|
||||
|
||||
### Skalowanie pionowe (Scale-up)
|
||||
- Więcej RAM, szybsze CPU, dyski SSD
|
||||
- Proste, ale ograniczone
|
||||
|
||||
### Skalowanie poziome (Scale-out)
|
||||
- **Replikacja** - kopie do odczytu
|
||||
- **Sharding** - podział danych między serwery
|
||||
- **Klastry** - wysoka dostępność
|
||||
|
||||
### Wysoka dostępność (HA)
|
||||
|
||||
| Rozwiązanie | Opis |
|
||||
|-------------|------|
|
||||
| **Replikacja Master-Slave** | Odczyty z replik |
|
||||
| **Replikacja Master-Master** | Zapisy na wielu węzłach |
|
||||
| **Failover automatyczny** | Przełączanie przy awarii |
|
||||
| **Backup/Recovery** | Odtwarzanie po katastrofie |
|
||||
|
||||
---
|
||||
|
||||
## 8. Standaryzacja i ekosystem
|
||||
|
||||
### SQL jako lingua franca
|
||||
- **Standardowy język** - SQL:2016, SQL:2023
|
||||
- **Przenośność** - kod działa na różnych SZBD
|
||||
- **Narzędzia** - uniwersalne IDE, ORM, ETL
|
||||
|
||||
### Bogaty ekosystem
|
||||
- **ORM** (Hibernate, Entity Framework, SQLAlchemy)
|
||||
- **Narzędzia migracji** (Flyway, Liquibase)
|
||||
- **Monitorowanie** (Grafana, Datadog)
|
||||
- **Backup** (pg_dump, mysqldump, RMAN)
|
||||
|
||||
---
|
||||
|
||||
## 9. Różnorodność modeli danych
|
||||
|
||||
### Jeden fundament, wiele modeli
|
||||
|
||||
| Model | SZBD | Zastosowanie |
|
||||
|-------|------|--------------|
|
||||
| **Relacyjny** | PostgreSQL, MySQL, Oracle | OLTP, dane strukturalne |
|
||||
| **Dokumentowy** | MongoDB, CouchDB | JSON, elastyczne schematy |
|
||||
| **Klucz-wartość** | Redis, DynamoDB | Cache, sesje |
|
||||
| **Grafowy** | Neo4j, Amazon Neptune | Relacje, sieci społeczne |
|
||||
| **Kolumnowy** | Cassandra, ClickHouse | Analityka, time-series |
|
||||
| **Czasowy** | TimescaleDB, InfluxDB | IoT, metryki |
|
||||
|
||||
### Polyglot Persistence
|
||||
Nowoczesne systemy często używają **wielu baz** - każda do swojego celu.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Porównanie: z bazą vs bez bazy
|
||||
|
||||
| Aspekt | Bez bazy (pliki) | Z bazą danych |
|
||||
|--------|------------------|---------------|
|
||||
| **Współbieżność** | Ręczne blokady | Automatyczna |
|
||||
| **Integralność** | W kodzie aplikacji | Deklaratywna |
|
||||
| **Zapytania** | Parsowanie plików | SQL/indeksy |
|
||||
| **Backup** | Kopiowanie plików | Spójne snapshoty |
|
||||
| **Skalowanie** | Trudne | Replikacja/sharding |
|
||||
| **Bezpieczeństwo** | OS-level | Granularne uprawnienia |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "ACID" - już sam w sobie mnemonik:
|
||||
- **A**tomowość - **A**ll or nothing
|
||||
- **C**onsistency - **C**orrect always
|
||||
- **I**solation - **I**ndependent transactions
|
||||
- **D**urability - **D**ata survives
|
||||
|
||||
### "BDSM" dla korzyści bazy danych:
|
||||
- **B**ezpieczeństwo (autoryzacja, audyt)
|
||||
- **D**ane niezależne (od aplikacji)
|
||||
- **S**kalowalność (replikacja, sharding)
|
||||
- **M**echanizmy integralności (FK, CHECK)
|
||||
|
||||
### "CIA" dla bezpieczeństwa:
|
||||
- **C**onfidentiality - kto może czytać
|
||||
- **I**ntegrity - kto może zmieniać
|
||||
- **A**vailability - dostępność usługi
|
||||
|
||||
### "CRUD = baza umie wszystko":
|
||||
- **C**reate - INSERT
|
||||
- **R**ead - SELECT
|
||||
- **U**pdate - UPDATE
|
||||
- **D**elete - DELETE
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Wyjaśnij różnicę między blokadami pesymistycznymi a optymistycznymi"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Cecha | Pesymistyczne | Optymistyczne |
|
||||
|-------|---------------|---------------|
|
||||
| **Założenie** | Konflikty są częste | Konflikty są rzadkie |
|
||||
| **Działanie** | Blokuj przed dostępem | Sprawdź przy zatwierdzeniu |
|
||||
| **Implementacja** | Locki (S, X, IS, IX) | Wersjonowanie (MVCC) |
|
||||
| **Zaleta** | Gwarancja sukcesu | Brak blokowania |
|
||||
| **Wada** | Deadlocki możliwe | Rollback przy konflikcie |
|
||||
| **Zastosowanie** | Dużo zapisów | Dużo odczytów |
|
||||
|
||||
**MVCC (Multi-Version Concurrency Control):**
|
||||
- Każdy zapis tworzy nową wersję wiersza
|
||||
- Odczyt widzi "migawkę" z początku transakcji
|
||||
- Brak blokowania między odczytem a zapisem
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Co to jest CAP theorem i jak wpływa na projektowanie?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Twierdzenie CAP** (Brewer, 2000):
|
||||
W systemie rozproszonym można mieć **co najwyżej 2 z 3** właściwości:
|
||||
|
||||
- **C**onsistency - wszystkie węzły widzą te same dane
|
||||
- **A**vailability - każde żądanie otrzymuje odpowiedź
|
||||
- **P**artition tolerance - system działa mimo podziału sieci
|
||||
|
||||
**Konsekwencje:**
|
||||
|
||||
| Wybór | Poświęca | Przykład |
|
||||
|-------|----------|----------|
|
||||
| **CA** | Partition tolerance | Tradycyjne RDBMS (single node) |
|
||||
| **CP** | Availability | MongoDB, HBase |
|
||||
| **AP** | Consistency | Cassandra, DynamoDB |
|
||||
|
||||
**Praktyka:** Systemy rozproszone MUSZĄ być P (partycje się zdarzają), więc wybór to C vs A.
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Kiedy baza relacyjna, a kiedy NoSQL?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Kryteria | Relacyjna (SQL) | NoSQL |
|
||||
|----------|-----------------|-------|
|
||||
| **Struktura danych** | Stała, dobrze zdefiniowana | Zmienna, elastyczna |
|
||||
| **Transakcje** | ACID wymagane | BASE akceptowalne |
|
||||
| **Relacje** | Złożone złączenia | Proste lub brak |
|
||||
| **Skala** | Pionowa (scale-up) | Pozioma (scale-out) |
|
||||
| **Przykłady** | Finanse, ERP, CRM | Social media, IoT, gaming |
|
||||
|
||||
**BASE** (dla NoSQL):
|
||||
- **B**asically **A**vailable - zazwyczaj dostępny
|
||||
- **S**oft state - stan może być nieaktualny
|
||||
- **E**ventually consistent - ostatecznie spójny
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Jak baza danych wspiera architekturę mikroserwisów?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Wzorzec: Database per Service**
|
||||
- Każdy mikroserwis ma **własną bazę**
|
||||
- Brak bezpośredniego dostępu do cudzych danych
|
||||
- Komunikacja przez API/eventy
|
||||
|
||||
**Wyzwania:**
|
||||
1. **Rozproszone transakcje** → Saga pattern
|
||||
2. **Spójność danych** → Event sourcing, CQRS
|
||||
3. **Złączenia** → Denormalizacja, API composition
|
||||
|
||||
**Rozwiązania:**
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ Zamówienia │ │ Klienci │ │ Produkty │
|
||||
│ (MongoDB) │ │ (PostgreSQL)│ │ (Redis) │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
↓ ↓ ↓
|
||||
└──────── Message Broker (Kafka) ─────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co to jest indeks i jakie są rodzaje?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Indeks** = struktura danych przyspieszająca wyszukiwanie.
|
||||
|
||||
| Typ | Struktura | Zastosowanie |
|
||||
|-----|-----------|--------------|
|
||||
| **B-tree** | Zbalansowane drzewo | Ogólne, zakresy, sortowanie |
|
||||
| **Hash** | Tablica mieszająca | Równość (=), bardzo szybki |
|
||||
| **GiST** | Drzewo uogólnione | Geodane, full-text |
|
||||
| **GIN** | Inverted index | Tablice, JSONB, full-text |
|
||||
| **BRIN** | Block Range Index | Duże tabele, dane posortowane |
|
||||
|
||||
**Kompromis:**
|
||||
- Indeks **przyspiesza** SELECT
|
||||
- Indeks **spowalnia** INSERT/UPDATE/DELETE
|
||||
- Indeks **zajmuje** miejsce na dysku
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Wyjaśnij pojęcie normalizacji vs denormalizacji w kontekście wydajności"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Aspekt | Normalizacja | Denormalizacja |
|
||||
|--------|--------------|----------------|
|
||||
| **Redundancja** | Minimalna | Celowa |
|
||||
| **Złączenia** | Wymagane | Minimalne |
|
||||
| **Zapisy** | Szybkie | Wolniejsze |
|
||||
| **Odczyty** | Wolniejsze | Szybsze |
|
||||
| **Spójność** | Łatwa | Trudniejsza |
|
||||
| **Zastosowanie** | OLTP | OLAP, cache |
|
||||
|
||||
**Praktyka:**
|
||||
- **OLTP** (transakcje) → 3NF/BCNF
|
||||
- **OLAP** (analityka) → Star/Snowflake schema
|
||||
- **Cache** → Pełna denormalizacja (Redis)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **ACID** = gwarancje transakcyjne fundamentem niezawodności
|
||||
2. **Niezależność danych** = zmiany struktury nie psują aplikacji
|
||||
3. **Współbieżność** = tysiące użytkowników jednocześnie
|
||||
4. **Integralność** = reguły biznesowe wymuszone w bazie
|
||||
5. **Optymalizator** = automatyczne przyspieszanie zapytań
|
||||
6. **Bezpieczeństwo** = wielopoziomowa kontrola dostępu
|
||||
7. **Skalowalność** = od jednego serwera do klastra globalnego
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Date, C.J. - "An Introduction to Database Systems"
|
||||
2. Kleppmann, M. - "Designing Data-Intensive Applications"
|
||||
3. Garcia-Molina, Ullman, Widom - "Database Systems: The Complete Book"
|
||||
4. Hellerstein, Stonebraker - "Readings in Database Systems" (Red Book)
|
||||
@ -1,685 +0,0 @@
|
||||
# Pytanie 5: Główne kategorie elementów biblioteki STL
|
||||
|
||||
## Pytanie
|
||||
**"Omówić główne kategorie elementów biblioteki STL. Jaka jest ich rola i wzajemne powiązania? Odpowiedź uzasadnić na przykładach."**
|
||||
|
||||
Przedmiot: PROI (Programowanie Obiektowe)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
**STL (Standard Template Library)** to część standardowej biblioteki C++ zawierająca generyczne struktury danych i algorytmy. Została zaprojektowana przez Alexandra Stepanova i weszła do standardu C++98.
|
||||
|
||||
### Filozofia STL
|
||||
- **Generyczność** - szablony (templates) umożliwiają pracę z dowolnymi typami
|
||||
- **Wydajność** - zero-overhead abstraction
|
||||
- **Modularność** - komponenty są niezależne i wymienne
|
||||
- **Ortogonalność** - kontenery i algorytmy są rozdzielone (przez iteratory)
|
||||
|
||||
---
|
||||
|
||||
## Cztery główne kategorie STL
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ STL │
|
||||
├─────────────┬─────────────┬─────────────┬─────────────────────┤
|
||||
│ KONTENERY │ ITERATORY │ ALGORYTMY │ FUNKTORY │
|
||||
│ (co?) │ (jak?) │ (operacje) │ (parametryzacja) │
|
||||
├─────────────┼─────────────┼─────────────┼─────────────────────┤
|
||||
│ vector │ input │ sort │ less<T> │
|
||||
│ list │ output │ find │ greater<T> │
|
||||
│ map │ forward │ transform │ plus<T> │
|
||||
│ set │ bidirect. │ copy │ lambdy │
|
||||
│ ... │ random │ ... │ ... │
|
||||
└─────────────┴─────────────┴─────────────┴─────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Kontenery (Containers)
|
||||
|
||||
### Definicja
|
||||
**Kontenery** to struktury danych przechowujące kolekcje obiektów. Zarządzają pamięcią automatycznie.
|
||||
|
||||
### Kategorie kontenerów
|
||||
|
||||
#### 1.1 Kontenery sekwencyjne (Sequence Containers)
|
||||
|
||||
Przechowują elementy w określonej kolejności.
|
||||
|
||||
| Kontener | Struktura | Dostęp | Wstawianie | Usuwanie |
|
||||
|----------|-----------|--------|------------|----------|
|
||||
| `vector` | Tablica dynamiczna | O(1) random | O(1) koniec, O(n) środek | O(1) koniec, O(n) środek |
|
||||
| `deque` | Tablica tablic | O(1) random | O(1) początek/koniec | O(1) początek/koniec |
|
||||
| `list` | Lista dwukierunkowa | O(n) | O(1) wszędzie* | O(1) wszędzie* |
|
||||
| `forward_list` | Lista jednokierunkowa | O(n) | O(1) po elemencie | O(1) po elemencie |
|
||||
| `array` | Tablica statyczna | O(1) random | N/A | N/A |
|
||||
|
||||
*po znalezieniu pozycji
|
||||
|
||||
```cpp
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
// vector - najczęściej używany
|
||||
std::vector<int> vec = {1, 2, 3, 4, 5};
|
||||
vec.push_back(6); // O(1) amortyzowane
|
||||
vec[2] = 10; // O(1) dostęp
|
||||
vec.insert(vec.begin(), 0); // O(n) - przesunięcie
|
||||
|
||||
// list - szybkie wstawianie/usuwanie
|
||||
std::list<int> lst = {1, 2, 3};
|
||||
auto it = lst.begin();
|
||||
std::advance(it, 1);
|
||||
lst.insert(it, 99); // O(1) po znalezieniu miejsca
|
||||
|
||||
// deque - szybki dostęp do obu końców
|
||||
std::deque<int> deq;
|
||||
deq.push_front(1); // O(1)
|
||||
deq.push_back(2); // O(1)
|
||||
```
|
||||
|
||||
#### 1.2 Kontenery asocjacyjne (Associative Containers)
|
||||
|
||||
Przechowują pary klucz-wartość, posortowane według klucza (drzewo czerwono-czarne).
|
||||
|
||||
| Kontener | Klucze | Wartości | Złożoność |
|
||||
|----------|--------|----------|-----------|
|
||||
| `set` | Unikalne | Brak | O(log n) |
|
||||
| `multiset` | Duplikaty OK | Brak | O(log n) |
|
||||
| `map` | Unikalne | Tak | O(log n) |
|
||||
| `multimap` | Duplikaty OK | Tak | O(log n) |
|
||||
|
||||
```cpp
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
// set - zbiór unikalnych, posortowanych elementów
|
||||
std::set<int> s = {3, 1, 4, 1, 5}; // {1, 3, 4, 5} - bez duplikatów
|
||||
s.insert(2); // O(log n)
|
||||
bool exists = s.count(3) > 0; // O(log n)
|
||||
|
||||
// map - słownik klucz->wartość
|
||||
std::map<std::string, int> ages;
|
||||
ages["Jan"] = 25; // O(log n)
|
||||
ages["Anna"] = 30;
|
||||
for (const auto& [name, age] : ages) {
|
||||
std::cout << name << ": " << age << "\n"; // Posortowane alfabetycznie
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 Kontenery asocjacyjne nieuporządkowane (Unordered Associative)
|
||||
|
||||
Implementacja: tablica haszująca (hash table).
|
||||
|
||||
| Kontener | Klucze | Wartości | Złożoność średnia |
|
||||
|----------|--------|----------|-------------------|
|
||||
| `unordered_set` | Unikalne | Brak | O(1) |
|
||||
| `unordered_multiset` | Duplikaty OK | Brak | O(1) |
|
||||
| `unordered_map` | Unikalne | Tak | O(1) |
|
||||
| `unordered_multimap` | Duplikaty OK | Tak | O(1) |
|
||||
|
||||
```cpp
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
// unordered_map - szybsza od map dla dużych zbiorów
|
||||
std::unordered_map<std::string, int> umap;
|
||||
umap["klucz"] = 42; // O(1) średnio
|
||||
auto it = umap.find("klucz"); // O(1) średnio
|
||||
|
||||
// unordered_set
|
||||
std::unordered_set<int> uset = {1, 2, 3};
|
||||
uset.insert(4); // O(1) średnio
|
||||
```
|
||||
|
||||
#### 1.4 Adaptery kontenerów (Container Adapters)
|
||||
|
||||
Interfejsy ograniczające funkcjonalność bazowego kontenera.
|
||||
|
||||
| Adapter | Domyślny kontener | Operacje |
|
||||
|---------|-------------------|----------|
|
||||
| `stack` | deque | push, pop, top (LIFO) |
|
||||
| `queue` | deque | push, pop, front (FIFO) |
|
||||
| `priority_queue` | vector | push, pop, top (max-heap) |
|
||||
|
||||
```cpp
|
||||
#include <stack>
|
||||
#include <queue>
|
||||
|
||||
// stack - LIFO
|
||||
std::stack<int> stk;
|
||||
stk.push(1);
|
||||
stk.push(2);
|
||||
stk.top(); // 2
|
||||
stk.pop(); // usuwa 2
|
||||
|
||||
// queue - FIFO
|
||||
std::queue<int> q;
|
||||
q.push(1);
|
||||
q.push(2);
|
||||
q.front(); // 1
|
||||
q.pop(); // usuwa 1
|
||||
|
||||
// priority_queue - max-heap domyślnie
|
||||
std::priority_queue<int> pq;
|
||||
pq.push(3);
|
||||
pq.push(1);
|
||||
pq.push(4);
|
||||
pq.top(); // 4 (największy)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Iteratory (Iterators)
|
||||
|
||||
### Definicja
|
||||
**Iteratory** to uogólnione wskaźniki - abstrakcja umożliwiająca jednolity dostęp do elementów kontenerów.
|
||||
|
||||
### Hierarchia iteratorów
|
||||
|
||||
```
|
||||
Input Iterator Output Iterator
|
||||
↓ ↓
|
||||
Forward Iterator ←────────┘
|
||||
↓
|
||||
Bidirectional Iterator
|
||||
↓
|
||||
Random Access Iterator
|
||||
↓
|
||||
Contiguous Iterator (C++17)
|
||||
```
|
||||
|
||||
### Kategorie iteratorów
|
||||
|
||||
| Kategoria | Operacje | Przykłady kontenerów |
|
||||
|-----------|----------|---------------------|
|
||||
| **Input** | `++`, `*`, `==`, `!=` | istream_iterator |
|
||||
| **Output** | `++`, `*` (zapis) | ostream_iterator |
|
||||
| **Forward** | Input + wielokrotne przejście | forward_list, unordered_* |
|
||||
| **Bidirectional** | Forward + `--` | list, set, map |
|
||||
| **Random Access** | Bidirectional + `+`, `-`, `[]`, `<` | vector, deque, array |
|
||||
| **Contiguous** | Random + ciągła pamięć | vector, array, string |
|
||||
|
||||
```cpp
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
|
||||
std::vector<int> vec = {1, 2, 3, 4, 5};
|
||||
|
||||
// Random access iterator
|
||||
auto it = vec.begin();
|
||||
it += 3; // OK - random access
|
||||
std::cout << *it; // 4
|
||||
std::cout << it[1]; // 5
|
||||
|
||||
std::list<int> lst = {1, 2, 3, 4, 5};
|
||||
|
||||
// Bidirectional iterator
|
||||
auto lit = lst.begin();
|
||||
++lit; // OK
|
||||
--lit; // OK - bidirectional
|
||||
// lit += 3; // BŁĄD! - brak random access
|
||||
|
||||
// Pomocnicze funkcje
|
||||
std::advance(lit, 3); // Działa dla każdego iteratora
|
||||
auto dist = std::distance(lst.begin(), lst.end()); // 5
|
||||
```
|
||||
|
||||
### Iteratory specjalne
|
||||
|
||||
```cpp
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
std::vector<int> vec = {1, 2, 3};
|
||||
|
||||
// Iteratory wstawiające
|
||||
std::vector<int> dest;
|
||||
std::copy(vec.begin(), vec.end(), std::back_inserter(dest)); // push_back
|
||||
|
||||
// Iteratory strumieni
|
||||
std::copy(vec.begin(), vec.end(),
|
||||
std::ostream_iterator<int>(std::cout, " ")); // wypisuje: 1 2 3
|
||||
|
||||
// Iteratory odwrotne
|
||||
for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
|
||||
std::cout << *rit << " "; // 3 2 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Algorytmy (Algorithms)
|
||||
|
||||
### Definicja
|
||||
**Algorytmy** to funkcje szablonowe operujące na zakresach (parach iteratorów). Są **oddzielone od kontenerów** - działają przez iteratory.
|
||||
|
||||
### Kategorie algorytmów
|
||||
|
||||
#### 3.1 Algorytmy niemodyfikujące
|
||||
|
||||
```cpp
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
std::vector<int> vec = {1, 2, 3, 4, 5, 3};
|
||||
|
||||
// Wyszukiwanie
|
||||
auto it = std::find(vec.begin(), vec.end(), 3); // pierwszy 3
|
||||
int cnt = std::count(vec.begin(), vec.end(), 3); // 2
|
||||
bool any = std::any_of(vec.begin(), vec.end(),
|
||||
[](int x) { return x > 4; }); // true
|
||||
|
||||
// Porównywanie
|
||||
std::vector<int> vec2 = {1, 2, 3, 4, 5, 3};
|
||||
bool eq = std::equal(vec.begin(), vec.end(), vec2.begin()); // true
|
||||
|
||||
// Zliczanie
|
||||
auto [min_it, max_it] = std::minmax_element(vec.begin(), vec.end());
|
||||
```
|
||||
|
||||
#### 3.2 Algorytmy modyfikujące
|
||||
|
||||
```cpp
|
||||
std::vector<int> vec = {3, 1, 4, 1, 5, 9};
|
||||
|
||||
// Sortowanie
|
||||
std::sort(vec.begin(), vec.end()); // {1, 1, 3, 4, 5, 9}
|
||||
std::sort(vec.begin(), vec.end(), std::greater<>()); // malejąco
|
||||
|
||||
// Przekształcanie
|
||||
std::transform(vec.begin(), vec.end(), vec.begin(),
|
||||
[](int x) { return x * 2; }); // podwojenie
|
||||
|
||||
// Usuwanie (erase-remove idiom)
|
||||
vec.erase(std::remove(vec.begin(), vec.end(), 1), vec.end());
|
||||
|
||||
// Wypełnianie
|
||||
std::fill(vec.begin(), vec.end(), 0);
|
||||
std::iota(vec.begin(), vec.end(), 1); // {1, 2, 3, ...}
|
||||
|
||||
// Kopiowanie
|
||||
std::vector<int> dest(vec.size());
|
||||
std::copy(vec.begin(), vec.end(), dest.begin());
|
||||
```
|
||||
|
||||
#### 3.3 Algorytmy partycjonujące i sortujące
|
||||
|
||||
```cpp
|
||||
std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6};
|
||||
|
||||
// Partycjonowanie
|
||||
auto pivot = std::partition(vec.begin(), vec.end(),
|
||||
[](int x) { return x < 5; });
|
||||
// Teraz: elementy < 5 | pivot | elementy >= 5
|
||||
|
||||
// Częściowe sortowanie
|
||||
std::partial_sort(vec.begin(), vec.begin() + 3, vec.end());
|
||||
// Pierwsze 3 elementy posortowane, reszta nieokreślona
|
||||
|
||||
// N-ty element
|
||||
std::nth_element(vec.begin(), vec.begin() + 4, vec.end());
|
||||
// Element na pozycji 4 jest taki jak po pełnym sortowaniu
|
||||
|
||||
// Sortowanie stabilne
|
||||
std::stable_sort(vec.begin(), vec.end()); // zachowuje kolejność równych
|
||||
```
|
||||
|
||||
#### 3.4 Algorytmy na zbiorach (posortowanych!)
|
||||
|
||||
```cpp
|
||||
std::vector<int> a = {1, 2, 3, 4, 5};
|
||||
std::vector<int> b = {3, 4, 5, 6, 7};
|
||||
std::vector<int> result;
|
||||
|
||||
// Suma zbiorów
|
||||
std::set_union(a.begin(), a.end(), b.begin(), b.end(),
|
||||
std::back_inserter(result)); // {1,2,3,4,5,6,7}
|
||||
|
||||
// Przecięcie
|
||||
result.clear();
|
||||
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
|
||||
std::back_inserter(result)); // {3,4,5}
|
||||
|
||||
// Różnica
|
||||
result.clear();
|
||||
std::set_difference(a.begin(), a.end(), b.begin(), b.end(),
|
||||
std::back_inserter(result)); // {1,2}
|
||||
```
|
||||
|
||||
#### 3.5 Algorytmy numeryczne (`<numeric>`)
|
||||
|
||||
```cpp
|
||||
#include <numeric>
|
||||
|
||||
std::vector<int> vec = {1, 2, 3, 4, 5};
|
||||
|
||||
int sum = std::accumulate(vec.begin(), vec.end(), 0); // 15
|
||||
int product = std::accumulate(vec.begin(), vec.end(), 1,
|
||||
std::multiplies<>()); // 120
|
||||
|
||||
// Iloczyn skalarny
|
||||
std::vector<int> a = {1, 2, 3};
|
||||
std::vector<int> b = {4, 5, 6};
|
||||
int dot = std::inner_product(a.begin(), a.end(), b.begin(), 0); // 32
|
||||
|
||||
// Sumy częściowe
|
||||
std::vector<int> prefix(vec.size());
|
||||
std::partial_sum(vec.begin(), vec.end(), prefix.begin()); // {1,3,6,10,15}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Funktory (Function Objects / Functors)
|
||||
|
||||
### Definicja
|
||||
**Funktory** to obiekty, które można wywołać jak funkcje (mają operator `()`). Służą do parametryzacji algorytmów.
|
||||
|
||||
### Rodzaje funktorów
|
||||
|
||||
#### 4.1 Predefiniowane funktory (`<functional>`)
|
||||
|
||||
```cpp
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
std::vector<int> vec = {3, 1, 4, 1, 5};
|
||||
|
||||
// Funktory arytmetyczne
|
||||
std::plus<int> add;
|
||||
int result = add(2, 3); // 5
|
||||
|
||||
// Funktory porównania
|
||||
std::sort(vec.begin(), vec.end(), std::greater<int>()); // malejąco
|
||||
std::sort(vec.begin(), vec.end(), std::less<int>()); // rosnąco
|
||||
|
||||
// Funktory logiczne
|
||||
std::logical_and<bool> land;
|
||||
bool b = land(true, false); // false
|
||||
```
|
||||
|
||||
#### 4.2 Wyrażenia lambda (C++11)
|
||||
|
||||
```cpp
|
||||
std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6};
|
||||
|
||||
// Lambda jako predykat
|
||||
auto it = std::find_if(vec.begin(), vec.end(),
|
||||
[](int x) { return x > 5; });
|
||||
|
||||
// Lambda z przechwytywaniem
|
||||
int threshold = 4;
|
||||
int count = std::count_if(vec.begin(), vec.end(),
|
||||
[threshold](int x) { return x > threshold; });
|
||||
|
||||
// Lambda modyfikująca (mutable)
|
||||
int counter = 0;
|
||||
std::for_each(vec.begin(), vec.end(),
|
||||
[&counter](int x) { counter += x; });
|
||||
|
||||
// Generic lambda (C++14)
|
||||
auto generic = [](auto x, auto y) { return x + y; };
|
||||
```
|
||||
|
||||
#### 4.3 std::function i std::bind
|
||||
|
||||
```cpp
|
||||
#include <functional>
|
||||
|
||||
// std::function - uniwersalny wrapper na callable
|
||||
std::function<int(int, int)> func = [](int a, int b) { return a + b; };
|
||||
func = std::plus<int>();
|
||||
func = &free_function;
|
||||
|
||||
// std::bind - częściowa aplikacja funkcji
|
||||
auto add5 = std::bind(std::plus<int>(), std::placeholders::_1, 5);
|
||||
int result = add5(10); // 15
|
||||
|
||||
// std::bind z referencją
|
||||
void modify(int& x) { x *= 2; }
|
||||
int n = 5;
|
||||
auto bound = std::bind(modify, std::ref(n));
|
||||
bound(); // n == 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Wzajemne powiązania
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ KONTENERY ←──── ITERATORY ────→ ALGORYTMY ←──── FUNKTORY │
|
||||
│ │ │ │ │ │
|
||||
│ przechowują abstrakcja operują na parametryzują │
|
||||
│ dane dostępu zakresach algorytmy │
|
||||
│ │ │ │ │ │
|
||||
│ vector<T> begin()/end() sort() less<T> │
|
||||
│ map<K,V> ++, *, == find() lambdy │
|
||||
│ set<T> random/bidir transform() std::function │
|
||||
│ │
|
||||
└───────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Kluczowa zasada: Ortogonalność
|
||||
|
||||
**M kontenerów × N algorytmów = M + N implementacji** (nie M × N!)
|
||||
|
||||
Dzięki iteratorom:
|
||||
- Algorytm `sort` działa z `vector`, `deque`, `array`
|
||||
- Każdy nowy kontener automatycznie współpracuje z istniejącymi algorytmami
|
||||
- Każdy nowy algorytm automatycznie współpracuje z istniejącymi kontenerami
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "KIAF" dla kategorii STL:
|
||||
- **K**ontenery - CO przechowujemy
|
||||
- **I**teratory - JAK się poruszamy
|
||||
- **A**lgorytmy - CO robimy z danymi
|
||||
- **F**unktory - JAK parametryzujemy operacje
|
||||
|
||||
### "VLDA" dla kontenerów sekwencyjnych:
|
||||
- **V**ector - domyślny wybór, tablica dynamiczna
|
||||
- **L**ist - szybkie wstawianie w środku
|
||||
- **D**eque - szybki dostęp do obu końców
|
||||
- **A**rray - stały rozmiar, na stosie
|
||||
|
||||
### "SM-UM" dla asocjacyjnych:
|
||||
- **S**et/**M**ap - posortowane (drzewo), O(log n)
|
||||
- **U**nordered_**M**ap/set - hash, O(1)
|
||||
|
||||
### "SQP" dla adapterów:
|
||||
- **S**tack - LIFO (stos talerzy)
|
||||
- **Q**ueue - FIFO (kolejka do kasy)
|
||||
- **P**riority_queue - VIP (najważniejsi pierwsi)
|
||||
|
||||
### "IOFBRC" dla iteratorów (od najsłabszego):
|
||||
- **I**nput - tylko czytanie, jedno przejście
|
||||
- **O**utput - tylko pisanie, jedno przejście
|
||||
- **F**orward - wielokrotne przejście do przodu
|
||||
- **B**idirectional - do przodu i do tyłu
|
||||
- **R**andom - skok do dowolnego miejsca
|
||||
- **C**ontiguous - ciągła pamięć
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Kiedy użyć vector, a kiedy list?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Kryterium | vector | list |
|
||||
|-----------|--------|------|
|
||||
| Dostęp losowy | O(1) ✓ | O(n) ✗ |
|
||||
| Wstawianie na końcu | O(1) ✓ | O(1) ✓ |
|
||||
| Wstawianie w środku | O(n) ✗ | O(1) ✓* |
|
||||
| Cache-friendly | TAK ✓ | NIE ✗ |
|
||||
| Pamięć | Mniej | Więcej (wskaźniki) |
|
||||
|
||||
*po znalezieniu pozycji
|
||||
|
||||
**Praktyczna zasada:** Używaj `vector` domyślnie. `list` tylko gdy:
|
||||
- Bardzo częste wstawianie/usuwanie w środku
|
||||
- Iteratory muszą pozostać ważne po modyfikacji
|
||||
- Nigdy nie potrzebujesz dostępu losowego
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Czym się różni map od unordered_map?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Cecha | map | unordered_map |
|
||||
|-------|-----|---------------|
|
||||
| Struktura | Drzewo RB | Hash table |
|
||||
| Złożoność | O(log n) | O(1) średnio |
|
||||
| Najgorszy przypadek | O(log n) | O(n) |
|
||||
| Wymagania dla klucza | `operator<` | `hash`, `operator==` |
|
||||
| Kolejność iteracji | Posortowana | Nieokreślona |
|
||||
| Stabilność | Iteratory stabilne | Rehashing może unieważnić |
|
||||
|
||||
**Kiedy co:**
|
||||
- `map`: Potrzebujesz kolejności, mały zbiór, klucze trudne do hashowania
|
||||
- `unordered_map`: Duży zbiór, najważniejsza szybkość, kolejność nieistotna
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Co to jest iterator invalidation?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Iterator invalidation** = iterator przestaje wskazywać na ważny element po modyfikacji kontenera.
|
||||
|
||||
| Kontener | push_back | insert | erase |
|
||||
|----------|-----------|--------|-------|
|
||||
| vector | Może (realloc) | Tak | Tak (od miejsca) |
|
||||
| deque | Tak | Tak | Tak |
|
||||
| list | Nie | Nie | Tylko usunięty |
|
||||
| map/set | Nie | Nie | Tylko usunięty |
|
||||
| unordered_* | Może (rehash) | Może (rehash) | Tylko usunięty |
|
||||
|
||||
```cpp
|
||||
std::vector<int> vec = {1, 2, 3, 4, 5};
|
||||
auto it = vec.begin() + 2;
|
||||
|
||||
vec.push_back(6); // it może być INVALID!
|
||||
vec.insert(vec.begin(), 0); // it jest INVALID!
|
||||
|
||||
// Bezpieczny sposób usuwania
|
||||
for (auto it = vec.begin(); it != vec.end(); ) {
|
||||
if (*it % 2 == 0)
|
||||
it = vec.erase(it); // erase zwraca następny ważny iterator
|
||||
else
|
||||
++it;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Jak działa erase-remove idiom?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
`std::remove` **nie usuwa** elementów - tylko przesuwa "dobre" na początek i zwraca iterator do "końca" dobrych.
|
||||
|
||||
```cpp
|
||||
std::vector<int> vec = {1, 2, 3, 2, 4, 2, 5};
|
||||
|
||||
// BEZ idiomu
|
||||
// std::remove zwraca iterator do nowego "końca"
|
||||
auto new_end = std::remove(vec.begin(), vec.end(), 2);
|
||||
// vec = {1, 3, 4, 5, ?, ?, ?} - stary rozmiar!
|
||||
// ^new_end
|
||||
|
||||
// Z idiomem
|
||||
vec.erase(new_end, vec.end()); // usuń "śmieci"
|
||||
// vec = {1, 3, 4, 5}
|
||||
|
||||
// Jednolinijkowo
|
||||
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
|
||||
|
||||
// C++20: std::erase (wreszcie!)
|
||||
std::erase(vec, 2);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co to są zakresy (ranges) w C++20?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Ranges** to ewolucja STL - algorytmy przyjmują kontener zamiast pary iteratorów.
|
||||
|
||||
```cpp
|
||||
#include <ranges>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
std::vector<int> vec = {5, 3, 1, 4, 2};
|
||||
|
||||
// C++17 (klasyczne)
|
||||
std::sort(vec.begin(), vec.end());
|
||||
|
||||
// C++20 (ranges)
|
||||
std::ranges::sort(vec);
|
||||
|
||||
// Widoki (views) - leniwe, kompozowalne
|
||||
auto result = vec
|
||||
| std::views::filter([](int x) { return x % 2 == 0; })
|
||||
| std::views::transform([](int x) { return x * 2; })
|
||||
| std::views::take(3);
|
||||
|
||||
// Pipeline - nie kopiuje, leniwe obliczenia
|
||||
for (int x : result) {
|
||||
std::cout << x << " ";
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Jaka jest złożoność pamięciowa kontenerów?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Kontener | Pamięć na element | Narzut całkowity |
|
||||
|----------|-------------------|------------------|
|
||||
| `array<T,N>` | sizeof(T) | 0 |
|
||||
| `vector<T>` | sizeof(T) | 3 wskaźniki + capacity |
|
||||
| `list<T>` | sizeof(T) + 2 wskaźniki | 1 wskaźnik (head) |
|
||||
| `forward_list<T>` | sizeof(T) + 1 wskaźnik | 1 wskaźnik |
|
||||
| `deque<T>` | sizeof(T) | Mapa bloków |
|
||||
| `set<T>` | sizeof(T) + 3 wsk. + kolor | Root + size |
|
||||
| `unordered_set<T>` | sizeof(T) + wskaźnik | Bucket array |
|
||||
|
||||
**Praktyka:** `vector` jest najbardziej cache-friendly (ciągła pamięć).
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **4 kategorie:** Kontenery, Iteratory, Algorytmy, Funktory
|
||||
2. **Ortogonalność:** M kontenerów + N algorytmów = M + N implementacji
|
||||
3. **vector domyślnie:** Najlepszy cache, wystarczający dla 90% przypadków
|
||||
4. **Iteratory łączą:** Abstrakcja między kontenerami a algorytmami
|
||||
5. **Lambda > funktory:** Czytelniejsze, nowocześniejsze
|
||||
6. **Ranges (C++20):** Przyszłość STL - leniwe, kompozowalne
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Josuttis - "The C++ Standard Library"
|
||||
2. Meyers - "Effective STL"
|
||||
3. cppreference.com - dokumentacja STL
|
||||
4. Stepanov - "Elements of Programming"
|
||||
@ -1,777 +0,0 @@
|
||||
# Pytanie 6: Metody reużywalności kodu w językach obiektowych
|
||||
|
||||
## Pytanie
|
||||
**"Omówić metody reużywalności kodu i struktur danych w obiektowych językach programowania."**
|
||||
|
||||
Przedmiot: PROI (Programowanie Obiektowe)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
**Reużywalność kodu (code reuse)** to fundamentalna zasada inżynierii oprogramowania - "nie wynajduj koła na nowo". W programowaniu obiektowym mamy kilka mechanizmów umożliwiających wielokrotne wykorzystanie kodu.
|
||||
|
||||
### Główne metody reużywalności
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ METODY REUŻYWALNOŚCI │
|
||||
├─────────────────┬─────────────────┬─────────────────────────────┤
|
||||
│ DZIEDZICZENIE │ KOMPOZYCJA │ PROGRAMOWANIE │
|
||||
│ (Inheritance) │ (Composition) │ GENERYCZNE │
|
||||
├─────────────────┼─────────────────┼─────────────────────────────┤
|
||||
│ INTERFEJSY │ DELEGACJA │ BIBLIOTEKI │
|
||||
│ (Interfaces) │ (Delegation) │ (Libraries) │
|
||||
├─────────────────┼─────────────────┼─────────────────────────────┤
|
||||
│ MIXINY │ TRAITY │ WZORCE PROJEKTOWE │
|
||||
│ (Mixins) │ (Traits) │ (Design Patterns) │
|
||||
└─────────────────┴─────────────────┴─────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Dziedziczenie (Inheritance)
|
||||
|
||||
### Definicja
|
||||
**Dziedziczenie** to mechanizm, w którym klasa pochodna (child) przejmuje atrybuty i metody klasy bazowej (parent).
|
||||
|
||||
### Typy dziedziczenia
|
||||
|
||||
| Typ | Opis | Języki |
|
||||
|-----|------|--------|
|
||||
| **Pojedyncze** | Jedna klasa bazowa | Java, C# |
|
||||
| **Wielokrotne** | Wiele klas bazowych | C++, Python |
|
||||
| **Wielopoziomowe** | A → B → C | Wszystkie |
|
||||
| **Hierarchiczne** | A → B, A → C | Wszystkie |
|
||||
|
||||
### Przykład (C++)
|
||||
|
||||
```cpp
|
||||
// Klasa bazowa
|
||||
class Pojazd {
|
||||
protected:
|
||||
std::string marka;
|
||||
int predkosc;
|
||||
|
||||
public:
|
||||
Pojazd(const std::string& m) : marka(m), predkosc(0) {}
|
||||
|
||||
virtual void jedz() {
|
||||
std::cout << marka << " jedzie " << predkosc << " km/h\n";
|
||||
}
|
||||
|
||||
virtual ~Pojazd() = default;
|
||||
};
|
||||
|
||||
// Klasa pochodna - dziedziczy i rozszerza
|
||||
class Samochod : public Pojazd {
|
||||
private:
|
||||
int liczbaDrzwi;
|
||||
|
||||
public:
|
||||
Samochod(const std::string& m, int drzwi)
|
||||
: Pojazd(m), liczbaDrzwi(drzwi) {}
|
||||
|
||||
void jedz() override {
|
||||
predkosc = 120;
|
||||
Pojazd::jedz(); // wywołanie metody bazowej
|
||||
std::cout << "Drzwi: " << liczbaDrzwi << "\n";
|
||||
}
|
||||
|
||||
void parkuj() { /* nowa metoda */ }
|
||||
};
|
||||
|
||||
// Użycie
|
||||
Samochod auto1("BMW", 4);
|
||||
auto1.jedz(); // Polimorfizm - wywołuje Samochod::jedz()
|
||||
```
|
||||
|
||||
### Zalety i wady dziedziczenia
|
||||
|
||||
| Zalety | Wady |
|
||||
|--------|------|
|
||||
| Naturalne modelowanie hierarchii | Silne wiązanie (tight coupling) |
|
||||
| Polimorfizm | Problem kruchej klasy bazowej |
|
||||
| Łatwe rozszerzanie | Problemy z wielodziedziczeniem (diamond) |
|
||||
| Współdzielenie implementacji | Narusza enkapsulację |
|
||||
|
||||
### Problem diamentu (Diamond Problem)
|
||||
|
||||
```
|
||||
A
|
||||
/ \
|
||||
B C
|
||||
\ /
|
||||
D
|
||||
```
|
||||
|
||||
```cpp
|
||||
class A { public: void metoda() {} };
|
||||
class B : public A {};
|
||||
class C : public A {};
|
||||
class D : public B, public C {}; // Która A::metoda()?
|
||||
|
||||
D d;
|
||||
// d.metoda(); // BŁĄD: niejednoznaczne!
|
||||
d.B::metoda(); // OK - jawne wskazanie
|
||||
```
|
||||
|
||||
**Rozwiązanie w C++:** Dziedziczenie wirtualne
|
||||
```cpp
|
||||
class B : virtual public A {};
|
||||
class C : virtual public A {};
|
||||
class D : public B, public C {}; // Jedna kopia A
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Kompozycja (Composition)
|
||||
|
||||
### Definicja
|
||||
**Kompozycja** to budowanie złożonych obiektów z prostszych komponentów. Relacja "zawiera" (has-a) zamiast "jest" (is-a).
|
||||
|
||||
### Zasada: "Favor composition over inheritance"
|
||||
|
||||
```cpp
|
||||
// ZŁE - dziedziczenie
|
||||
class Stack : public std::vector<int> {
|
||||
// Stack NIE JEST wektorem!
|
||||
// Użytkownik może wywołać insert(), erase()...
|
||||
};
|
||||
|
||||
// DOBRE - kompozycja
|
||||
class Stack {
|
||||
private:
|
||||
std::vector<int> elements; // Stack ZAWIERA wektor
|
||||
|
||||
public:
|
||||
void push(int x) { elements.push_back(x); }
|
||||
int pop() {
|
||||
int top = elements.back();
|
||||
elements.pop_back();
|
||||
return top;
|
||||
}
|
||||
bool empty() const { return elements.empty(); }
|
||||
// Tylko te metody, które mają sens dla stosu
|
||||
};
|
||||
```
|
||||
|
||||
### Typy relacji obiektowych
|
||||
|
||||
| Relacja | Siła | Cykl życia | Przykład |
|
||||
|---------|------|------------|----------|
|
||||
| **Kompozycja** | Silna | Zależny (owns) | Samochód → Silnik |
|
||||
| **Agregacja** | Słaba | Niezależny (uses) | Uniwersytet → Student |
|
||||
| **Asocjacja** | Luźna | Niezależny | Klient ↔ Zamówienie |
|
||||
|
||||
```cpp
|
||||
// Kompozycja - silnik "umiera" z samochodem
|
||||
class Samochod {
|
||||
private:
|
||||
Silnik silnik; // Obiekt wewnętrzny
|
||||
public:
|
||||
Samochod() : silnik() {} // Tworzy silnik
|
||||
// ~Samochod() niszczy silnik automatycznie
|
||||
};
|
||||
|
||||
// Agregacja - student istnieje niezależnie od uniwersytetu
|
||||
class Uniwersytet {
|
||||
private:
|
||||
std::vector<Student*> studenci; // Wskaźniki/referencje
|
||||
public:
|
||||
void dodajStudenta(Student* s) { studenci.push_back(s); }
|
||||
// ~Uniwersytet() NIE niszczy studentów
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Programowanie generyczne (Generic Programming)
|
||||
|
||||
### Definicja
|
||||
**Programowanie generyczne** to pisanie kodu niezależnego od konkretnych typów danych, używając szablonów (templates) lub generyków.
|
||||
|
||||
### Szablony w C++
|
||||
|
||||
```cpp
|
||||
// Szablon funkcji
|
||||
template<typename T>
|
||||
T maximum(T a, T b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
// Użycie - kompilator generuje wersje dla każdego typu
|
||||
int m1 = maximum(3, 5); // int
|
||||
double m2 = maximum(3.14, 2.71); // double
|
||||
std::string m3 = maximum("abc", "xyz"); // string
|
||||
|
||||
// Szablon klasy
|
||||
template<typename T, size_t N>
|
||||
class Array {
|
||||
private:
|
||||
T data[N];
|
||||
public:
|
||||
T& operator[](size_t i) { return data[i]; }
|
||||
constexpr size_t size() const { return N; }
|
||||
};
|
||||
|
||||
Array<int, 10> arr; // Tablica 10 intów
|
||||
Array<double, 5> darr; // Tablica 5 double'i
|
||||
```
|
||||
|
||||
### Generyki w Java/C#
|
||||
|
||||
```java
|
||||
// Java
|
||||
public class Box<T> {
|
||||
private T value;
|
||||
|
||||
public void set(T value) { this.value = value; }
|
||||
public T get() { return value; }
|
||||
}
|
||||
|
||||
// Ograniczenia typów (bounded type parameters)
|
||||
public <T extends Comparable<T>> T max(T a, T b) {
|
||||
return a.compareTo(b) > 0 ? a : b;
|
||||
}
|
||||
```
|
||||
|
||||
```csharp
|
||||
// C#
|
||||
public class Repository<T> where T : class, IEntity, new() {
|
||||
public T Create() => new T();
|
||||
public void Save(T entity) { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
### Zalety programowania generycznego
|
||||
|
||||
| Zaleta | Opis |
|
||||
|--------|------|
|
||||
| **Type safety** | Błędy wykrywane w czasie kompilacji |
|
||||
| **Brak duplikacji** | Jeden kod dla wielu typów |
|
||||
| **Wydajność** | C++: specjalizacja w kompilacji, brak rzutowania |
|
||||
| **Czytelność** | Jawne wymagania typów |
|
||||
|
||||
---
|
||||
|
||||
## 4. Interfejsy (Interfaces)
|
||||
|
||||
### Definicja
|
||||
**Interfejs** definiuje kontrakt (zestaw metod), który klasa musi zaimplementować. Oddziela "co" od "jak".
|
||||
|
||||
### Przykład
|
||||
|
||||
```java
|
||||
// Java - interfejs
|
||||
public interface Drawable {
|
||||
void draw();
|
||||
default void clear() { /* domyślna implementacja */ }
|
||||
}
|
||||
|
||||
public interface Resizable {
|
||||
void resize(int width, int height);
|
||||
}
|
||||
|
||||
// Klasa implementuje wiele interfejsów
|
||||
public class Rectangle implements Drawable, Resizable {
|
||||
@Override
|
||||
public void draw() { /* implementacja */ }
|
||||
|
||||
@Override
|
||||
public void resize(int w, int h) { /* implementacja */ }
|
||||
}
|
||||
```
|
||||
|
||||
```cpp
|
||||
// C++ - klasa abstrakcyjna jako interfejs
|
||||
class IDrawable {
|
||||
public:
|
||||
virtual void draw() = 0; // Pure virtual
|
||||
virtual ~IDrawable() = default;
|
||||
};
|
||||
|
||||
class IResizable {
|
||||
public:
|
||||
virtual void resize(int w, int h) = 0;
|
||||
virtual ~IResizable() = default;
|
||||
};
|
||||
|
||||
class Rectangle : public IDrawable, public IResizable {
|
||||
public:
|
||||
void draw() override { /* ... */ }
|
||||
void resize(int w, int h) override { /* ... */ }
|
||||
};
|
||||
```
|
||||
|
||||
### Interfejsy vs Klasy abstrakcyjne
|
||||
|
||||
| Cecha | Interfejs | Klasa abstrakcyjna |
|
||||
|-------|-----------|-------------------|
|
||||
| Wielodziedziczenie | TAK | NIE (Java/C#) |
|
||||
| Pola | NIE (do Java 8) | TAK |
|
||||
| Konstruktor | NIE | TAK |
|
||||
| Implementacja metod | default (Java 8+) | TAK |
|
||||
| Cel | Definiuje kontrakt | Współdzieli implementację |
|
||||
|
||||
---
|
||||
|
||||
## 5. Delegacja (Delegation)
|
||||
|
||||
### Definicja
|
||||
**Delegacja** to przekazywanie odpowiedzialności za wykonanie operacji do innego obiektu.
|
||||
|
||||
```cpp
|
||||
// Bez delegacji - dziedziczenie
|
||||
class LoggingList : public std::list<int> {
|
||||
public:
|
||||
void push_back(int x) {
|
||||
log("Adding: " + std::to_string(x));
|
||||
std::list<int>::push_back(x);
|
||||
}
|
||||
};
|
||||
|
||||
// Z delegacją - kompozycja
|
||||
class LoggingList {
|
||||
private:
|
||||
std::list<int> delegate; // Delegat
|
||||
|
||||
public:
|
||||
void push_back(int x) {
|
||||
log("Adding: " + std::to_string(x));
|
||||
delegate.push_back(x); // Delegacja
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return delegate.size(); // Delegacja
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Wzorzec strategii (Strategy Pattern)
|
||||
|
||||
```cpp
|
||||
// Interfejs strategii
|
||||
class SortStrategy {
|
||||
public:
|
||||
virtual void sort(std::vector<int>& data) = 0;
|
||||
virtual ~SortStrategy() = default;
|
||||
};
|
||||
|
||||
class QuickSort : public SortStrategy {
|
||||
public:
|
||||
void sort(std::vector<int>& data) override { /* quicksort */ }
|
||||
};
|
||||
|
||||
class MergeSort : public SortStrategy {
|
||||
public:
|
||||
void sort(std::vector<int>& data) override { /* mergesort */ }
|
||||
};
|
||||
|
||||
// Kontekst deleguje sortowanie do strategii
|
||||
class Sorter {
|
||||
private:
|
||||
std::unique_ptr<SortStrategy> strategy;
|
||||
|
||||
public:
|
||||
void setStrategy(std::unique_ptr<SortStrategy> s) {
|
||||
strategy = std::move(s);
|
||||
}
|
||||
|
||||
void performSort(std::vector<int>& data) {
|
||||
strategy->sort(data); // Delegacja
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Mixiny i Traity
|
||||
|
||||
### Mixiny (Mixins)
|
||||
Klasy dostarczające funkcjonalność do "wmieszania" do innych klas.
|
||||
|
||||
```python
|
||||
# Python - mixiny przez wielodziedziczenie
|
||||
class JSONSerializableMixin:
|
||||
def to_json(self):
|
||||
import json
|
||||
return json.dumps(self.__dict__)
|
||||
|
||||
class XMLSerializableMixin:
|
||||
def to_xml(self):
|
||||
# implementacja...
|
||||
pass
|
||||
|
||||
class User(JSONSerializableMixin, XMLSerializableMixin):
|
||||
def __init__(self, name, email):
|
||||
self.name = name
|
||||
self.email = email
|
||||
|
||||
user = User("Jan", "jan@example.com")
|
||||
print(user.to_json()) # {"name": "Jan", "email": "jan@example.com"}
|
||||
```
|
||||
|
||||
### Traity (Traits)
|
||||
|
||||
```rust
|
||||
// Rust - traits
|
||||
trait Drawable {
|
||||
fn draw(&self);
|
||||
}
|
||||
|
||||
trait Movable {
|
||||
fn move_to(&mut self, x: i32, y: i32);
|
||||
}
|
||||
|
||||
struct Circle {
|
||||
x: i32,
|
||||
y: i32,
|
||||
radius: i32,
|
||||
}
|
||||
|
||||
impl Drawable for Circle {
|
||||
fn draw(&self) { /* ... */ }
|
||||
}
|
||||
|
||||
impl Movable for Circle {
|
||||
fn move_to(&mut self, x: i32, y: i32) {
|
||||
self.x = x;
|
||||
self.y = y;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```php
|
||||
// PHP - traits
|
||||
trait Timestampable {
|
||||
public $createdAt;
|
||||
public $updatedAt;
|
||||
|
||||
public function touch() {
|
||||
$this->updatedAt = new DateTime();
|
||||
}
|
||||
}
|
||||
|
||||
trait SoftDeletable {
|
||||
public $deletedAt;
|
||||
|
||||
public function softDelete() {
|
||||
$this->deletedAt = new DateTime();
|
||||
}
|
||||
}
|
||||
|
||||
class Article {
|
||||
use Timestampable, SoftDeletable;
|
||||
|
||||
public $title;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Biblioteki i frameworki
|
||||
|
||||
### Poziomy reużywalności
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ FRAMEWORK │
|
||||
│ (IoC, definiuje architekturę aplikacji) │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ BIBLIOTEKA │
|
||||
│ (kolekcja klas/funkcji, wywołujesz Ty) │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ MODUŁ/PAKIET │
|
||||
│ (logicznie powiązane klasy) │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ KLASA │
|
||||
│ (jednostka enkapsulacji) │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ FUNKCJA │
|
||||
│ (najmniejsza jednostka reużywalna) │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Przykłady
|
||||
|
||||
| Poziom | Przykłady |
|
||||
|--------|-----------|
|
||||
| Framework | Spring, .NET, Unity, Django |
|
||||
| Biblioteka | STL, Boost, jQuery, NumPy |
|
||||
| Moduł | java.util, System.IO |
|
||||
| Klasa | ArrayList, HttpClient |
|
||||
|
||||
---
|
||||
|
||||
## 8. Wzorce projektowe (Design Patterns)
|
||||
|
||||
### Wzorce wspierające reużywalność
|
||||
|
||||
| Wzorzec | Typ | Cel |
|
||||
|---------|-----|-----|
|
||||
| **Factory Method** | Kreacyjny | Delegacja tworzenia obiektów |
|
||||
| **Abstract Factory** | Kreacyjny | Rodziny powiązanych obiektów |
|
||||
| **Prototype** | Kreacyjny | Klonowanie obiektów |
|
||||
| **Adapter** | Strukturalny | Dopasowanie interfejsów |
|
||||
| **Decorator** | Strukturalny | Dynamiczne rozszerzanie |
|
||||
| **Strategy** | Behawioralny | Wymienne algorytmy |
|
||||
| **Template Method** | Behawioralny | Szkielet algorytmu z krokami |
|
||||
|
||||
### Przykład: Template Method
|
||||
|
||||
```cpp
|
||||
// Szkielet algorytmu w klasie bazowej
|
||||
class DataParser {
|
||||
public:
|
||||
// Template method - definiuje szkielet
|
||||
void parse(const std::string& data) {
|
||||
openFile();
|
||||
readHeader();
|
||||
processData(data); // Krok abstrakcyjny
|
||||
closeFile();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void openFile() { /* domyślna impl */ }
|
||||
virtual void readHeader() { /* domyślna impl */ }
|
||||
virtual void processData(const std::string& data) = 0; // PURE
|
||||
virtual void closeFile() { /* domyślna impl */ }
|
||||
};
|
||||
|
||||
// Konkretne implementacje
|
||||
class JSONParser : public DataParser {
|
||||
protected:
|
||||
void processData(const std::string& data) override {
|
||||
// Parsowanie JSON
|
||||
}
|
||||
};
|
||||
|
||||
class XMLParser : public DataParser {
|
||||
protected:
|
||||
void processData(const std::string& data) override {
|
||||
// Parsowanie XML
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Porównanie metod reużywalności
|
||||
|
||||
| Metoda | Wiązanie | Elastyczność | Złożoność |
|
||||
|--------|----------|--------------|-----------|
|
||||
| Dziedziczenie | Statyczne | Niska | Średnia |
|
||||
| Kompozycja | Dynamiczne | Wysoka | Niska |
|
||||
| Interfejsy | Statyczne* | Wysoka | Niska |
|
||||
| Generyki | Statyczne | Wysoka | Średnia |
|
||||
| Delegacja | Dynamiczne | Wysoka | Średnia |
|
||||
| Mixiny/Traity | Statyczne | Średnia | Średnia |
|
||||
|
||||
*ale implementacja może być dynamiczna (polimorfizm)
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "SOLID" - zasady dobrego OOP:
|
||||
- **S**ingle Responsibility - jedna odpowiedzialność
|
||||
- **O**pen/Closed - otwarte na rozszerzenia, zamknięte na modyfikacje
|
||||
- **L**iskov Substitution - podtyp zastępuje typ bazowy
|
||||
- **I**nterface Segregation - wiele małych interfejsów > jeden duży
|
||||
- **D**ependency Inversion - zależność od abstrakcji, nie konkretu
|
||||
|
||||
### "HAS-A przed IS-A":
|
||||
- **HAS-A** = kompozycja (Samochód HAS-A Silnik)
|
||||
- **IS-A** = dziedziczenie (Samochód IS-A Pojazd)
|
||||
- Preferuj HAS-A!
|
||||
|
||||
### "DRIED" dla reużywalności:
|
||||
- **D**on't **R**epeat - nie powtarzaj kodu
|
||||
- **I**nterfaces - definiuj kontrakty
|
||||
- **E**ncapsulate - ukrywaj szczegóły
|
||||
- **D**elegate - przekazuj odpowiedzialność
|
||||
|
||||
### "GIT" dla generyków:
|
||||
- **G**eneric - niezależne od typu
|
||||
- **I**nvariant - sprawdzane w kompilacji
|
||||
- **T**ype-safe - bezpieczne typowanie
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Kiedy dziedziczenie, a kiedy kompozycja?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Użyj dziedziczenia gdy: | Użyj kompozycji gdy: |
|
||||
|------------------------|---------------------|
|
||||
| Relacja "jest" (is-a) | Relacja "zawiera" (has-a) |
|
||||
| Potrzebujesz polimorfizmu | Potrzebujesz elastyczności |
|
||||
| Klasa pochodna JEST typem bazowym | Chcesz zmieniać zachowanie w runtime |
|
||||
| Zasada Liskov jest spełniona | Chcesz uniknąć problemów z hierarchią |
|
||||
|
||||
**Przykład decyzji:**
|
||||
- Ptak IS-A Zwierzę → dziedziczenie OK
|
||||
- Samochód HAS-A Silnik → kompozycja!
|
||||
- Stack IS-A Vector? → NIE! Kompozycja.
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Co to jest zasada substytucji Liskov?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
> "Obiekty klasy bazowej powinny być zastępowalne obiektami klas pochodnych bez zmiany poprawności programu."
|
||||
|
||||
**Naruszenie LSP:**
|
||||
```cpp
|
||||
class Rectangle {
|
||||
public:
|
||||
virtual void setWidth(int w) { width = w; }
|
||||
virtual void setHeight(int h) { height = h; }
|
||||
int area() { return width * height; }
|
||||
protected:
|
||||
int width, height;
|
||||
};
|
||||
|
||||
class Square : public Rectangle { // PROBLEM!
|
||||
public:
|
||||
void setWidth(int w) override { width = height = w; }
|
||||
void setHeight(int h) override { width = height = h; }
|
||||
};
|
||||
|
||||
// Kod klienta
|
||||
void resize(Rectangle& r) {
|
||||
r.setWidth(5);
|
||||
r.setHeight(10);
|
||||
assert(r.area() == 50); // FAIL dla Square!
|
||||
}
|
||||
```
|
||||
|
||||
**Rozwiązanie:** Kwadrat nie powinien dziedziczyć po prostokącie (matematycznie IS-A, programistycznie NIE).
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Czym różnią się szablony C++ od generyków Java?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Cecha | C++ Templates | Java Generics |
|
||||
|-------|---------------|---------------|
|
||||
| Implementacja | Kompilacja (code generation) | Type erasure (runtime) |
|
||||
| Specjalizacja | TAK | NIE |
|
||||
| Prymitywy | TAK (int, double...) | NIE (tylko obiekty) |
|
||||
| Sprawdzanie typu | W czasie instancjacji | W czasie kompilacji |
|
||||
| Ograniczenia | Concepts (C++20) | Bounded types |
|
||||
| Wydajność | Optymalna | Rzutowanie w runtime |
|
||||
|
||||
```cpp
|
||||
// C++ - specjalizacja szablonu
|
||||
template<typename T>
|
||||
class Container { /* ogólna implementacja */ };
|
||||
|
||||
template<>
|
||||
class Container<bool> { /* specjalna dla bool - bitset */ };
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Co to jest Dependency Injection?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Dependency Injection (DI)** = wzorzec przekazywania zależności z zewnątrz zamiast tworzenia ich wewnątrz.
|
||||
|
||||
```cpp
|
||||
// BEZ DI - silne wiązanie
|
||||
class OrderService {
|
||||
private:
|
||||
MySQLDatabase db; // Zależność "zahardkodowana"
|
||||
public:
|
||||
OrderService() : db() {}
|
||||
};
|
||||
|
||||
// Z DI - luźne wiązanie
|
||||
class OrderService {
|
||||
private:
|
||||
IDatabase& db; // Zależność od abstrakcji
|
||||
public:
|
||||
OrderService(IDatabase& database) : db(database) {} // Injection
|
||||
};
|
||||
|
||||
// Użycie
|
||||
MySQLDatabase mysql;
|
||||
PostgresDatabase postgres;
|
||||
|
||||
OrderService service1(mysql); // Możemy łatwo zmienić
|
||||
OrderService service2(postgres); // implementację
|
||||
```
|
||||
|
||||
**Typy DI:**
|
||||
1. Constructor Injection (preferowany)
|
||||
2. Setter Injection
|
||||
3. Interface Injection
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Jak wzorce projektowe wspierają reużywalność?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Wzorzec | Mechanizm reużywalności |
|
||||
|---------|------------------------|
|
||||
| **Factory** | Oddziela tworzenie od użycia |
|
||||
| **Strategy** | Wymienna rodzina algorytmów |
|
||||
| **Decorator** | Dynamiczne dodawanie funkcji |
|
||||
| **Adapter** | Reużycie niekompatybilnych klas |
|
||||
| **Template Method** | Reużycie szkieletu algorytmu |
|
||||
| **Composite** | Jednolite traktowanie obiektów i kolekcji |
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Wyjaśnij różnicę między agregacją a kompozycją"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Cecha | Kompozycja | Agregacja |
|
||||
|-------|------------|-----------|
|
||||
| Siła związku | Silna ("owns") | Słaba ("uses") |
|
||||
| Cykl życia | Zależny | Niezależny |
|
||||
| UML | Wypełniony romb ◆ | Pusty romb ◇ |
|
||||
| Przykład | Samochód → Silnik | Firma → Pracownik |
|
||||
|
||||
```cpp
|
||||
// Kompozycja - silnik jest częścią samochodu
|
||||
class Car {
|
||||
Engine engine; // Engine tworzony z Car, niszczony z Car
|
||||
};
|
||||
|
||||
// Agregacja - pracownik może istnieć bez firmy
|
||||
class Company {
|
||||
std::vector<Employee*> employees; // Wskaźniki - nie "posiada"
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **Kompozycja > Dziedziczenie** - elastyczność, luźne wiązanie
|
||||
2. **Interfejsy oddzielają** kontrakt od implementacji
|
||||
3. **Generyki eliminują** duplikację kodu dla różnych typów
|
||||
4. **SOLID** - 5 zasad dobrego OOP
|
||||
5. **Delegacja** - przekazuj odpowiedzialność
|
||||
6. **Wzorce projektowe** - sprawdzone rozwiązania typowych problemów
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Gamma et al. - "Design Patterns: Elements of Reusable OO Software" (GoF)
|
||||
2. Martin, R. - "Clean Code" i "Clean Architecture"
|
||||
3. Meyers, S. - "Effective C++"
|
||||
4. Bloch, J. - "Effective Java"
|
||||
@ -1,426 +0,0 @@
|
||||
# Pytanie 7: Serwery DNS i buforowanie zapytań
|
||||
|
||||
## Pytanie
|
||||
**"Które serwery DNS najwięcej zyskują dzięki buforowaniu zapytań (caching) w serwerach rekursywnych? Jakie znasz rodzaje serwerów DNS?"**
|
||||
|
||||
Przedmiot: SKM (Sieci Komputerowe)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie do DNS
|
||||
|
||||
**DNS (Domain Name System)** to hierarchiczny, rozproszony system tłumaczenia nazw domenowych na adresy IP (i odwrotnie).
|
||||
|
||||
```
|
||||
www.example.com → 93.184.216.34
|
||||
```
|
||||
|
||||
### Hierarchia DNS
|
||||
|
||||
```
|
||||
. (root)
|
||||
/|\
|
||||
/ | \
|
||||
com org pl
|
||||
/|\ |
|
||||
/ | \ |
|
||||
google amazon pw
|
||||
| |
|
||||
www elka
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Rodzaje serwerów DNS
|
||||
|
||||
### 1.1 Serwery autorytatywne (Authoritative)
|
||||
|
||||
**Definicja:** Przechowują oryginalne rekordy DNS dla danej domeny. Są "źródłem prawdy".
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SERWERY AUTORYTATYWNE │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ROOT SERVERS (.) - 13 klastrów (a.root-servers.net ... m.) │
|
||||
│ ↓ │
|
||||
│ TLD SERVERS (.com, .org, .pl) - zarządzane przez rejestry │
|
||||
│ ↓ │
|
||||
│ AUTHORITATIVE NS - serwery konkretnych domen (ns1.example.com)│
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Root Servers (Serwery główne)
|
||||
- **13 logicznych serwerów:** a.root-servers.net do m.root-servers.net
|
||||
- **Fizycznie:** Setki serwerów (anycast)
|
||||
- **Funkcja:** Wskazują serwery TLD
|
||||
|
||||
#### TLD Servers (Top-Level Domain)
|
||||
- **gTLD:** .com, .org, .net (generic)
|
||||
- **ccTLD:** .pl, .de, .uk (country code)
|
||||
- **Nowe gTLD:** .shop, .app, .xyz
|
||||
- **Funkcja:** Wskazują autoryzacyjne NS domen
|
||||
|
||||
#### Authoritative Name Servers
|
||||
- **Primary (Master):** Oryginalne rekordy, edytowalne
|
||||
- **Secondary (Slave):** Kopie przez transfer stref (AXFR/IXFR)
|
||||
- **Funkcja:** Odpowiadają na zapytania o konkretną domenę
|
||||
|
||||
### 1.2 Serwery rekursywne (Recursive Resolvers)
|
||||
|
||||
**Definicja:** Wykonują pełne rozwiązywanie nazw w imieniu klienta, pytając kolejno serwery autorytatywne.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SERWERY REKURSYWNE │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ISP Resolvers - dostarczane przez dostawcę Internetu │
|
||||
│ Public Resolvers - Google (8.8.8.8), Cloudflare (1.1.1.1) │
|
||||
│ Enterprise Resolvers - wewnętrzne serwery firmowe │
|
||||
│ Local Resolvers - np. router domowy, Pi-hole │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.3 Stub Resolvers (Resolwery klienckie)
|
||||
|
||||
**Definicja:** Prosty klient DNS w systemie operacyjnym. Wysyła zapytanie do rekursywnego resolvera i czeka na odpowiedź.
|
||||
|
||||
- Windows: usługa DNS Client
|
||||
- Linux: libc resolver (nsswitch.conf, resolv.conf)
|
||||
- Nie wykonuje rekurencji sam
|
||||
|
||||
### 1.4 Forwarding Servers (Przekazujące)
|
||||
|
||||
**Definicja:** Przyjmują zapytania i przekazują je do innego resolvera zamiast samodzielnie rozwiązywać.
|
||||
|
||||
```
|
||||
Klient → Forwarder → Recursive Resolver → Authoritative
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Proces rozwiązywania DNS (Resolution)
|
||||
|
||||
### Zapytanie rekursywne vs iteracyjne
|
||||
|
||||
```
|
||||
ZAPYTANIE REKURSYWNE (klient → resolver):
|
||||
"Daj mi odpowiedź na www.example.com"
|
||||
→ Resolver musi zwrócić ostateczną odpowiedź lub błąd
|
||||
|
||||
ZAPYTANIE ITERACYJNE (resolver → authoritative):
|
||||
"Co wiesz o www.example.com?"
|
||||
→ Serwer zwraca odpowiedź lub odesłanie (referral)
|
||||
```
|
||||
|
||||
### Pełny proces rozwiązywania
|
||||
|
||||
```
|
||||
Klient Recursive Root .com TLD example.com
|
||||
│ Resolver │ │ │
|
||||
│──(1) www.example.com?──→│ │ │ │
|
||||
│ │──(2) query?───→│ │ │
|
||||
│ │←─(3) refer .com┘ │ │
|
||||
│ │──(4) query?────────────────→│ │
|
||||
│ │←─(5) refer example.com─────┘ │
|
||||
│ │──(6) query?─────────────────────────────→│
|
||||
│ │←─(7) 93.184.216.34──────────────────────┘
|
||||
│←─(8) 93.184.216.34─────┘
|
||||
│ │
|
||||
│ [CACHE zapisuje wszystkie odpowiedzi]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Buforowanie (Caching) w DNS
|
||||
|
||||
### Jak działa caching?
|
||||
|
||||
1. **Resolver otrzymuje odpowiedź** z serwera autorytatywnego
|
||||
2. **Zapisuje w cache** wraz z TTL (Time To Live)
|
||||
3. **Przy kolejnym zapytaniu** o tę samą nazwę - zwraca z cache
|
||||
4. **Po wygaśnięciu TTL** - pyta ponownie serwer autorytatywny
|
||||
|
||||
### TTL (Time To Live)
|
||||
|
||||
```
|
||||
; Fragment strefy DNS
|
||||
www.example.com. 300 IN A 93.184.216.34
|
||||
↑
|
||||
TTL = 300 sekund (5 minut)
|
||||
```
|
||||
|
||||
| Typowe TTL | Zastosowanie |
|
||||
|------------|--------------|
|
||||
| 60-300 s | Dynamiczne usługi, failover |
|
||||
| 3600 s (1h) | Standardowe strony |
|
||||
| 86400 s (24h) | Stabilne serwisy |
|
||||
| 604800 s (7d) | Rzadko zmieniane |
|
||||
|
||||
---
|
||||
|
||||
## 4. Które serwery zyskują najwięcej na cachingu?
|
||||
|
||||
### 🏆 Odpowiedź: **ROOT SERVERS i TLD SERVERS**
|
||||
|
||||
### Dlaczego root servers zyskują najwięcej?
|
||||
|
||||
```
|
||||
BEZ CACHINGU:
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ Każde zapytanie DNS → najpierw pytanie do root server │
|
||||
│ Miliardy zapytań dziennie → root servers byłyby przeciążone! │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
|
||||
Z CACHINGIEM:
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ Resolver pyta root server RAZ o serwery .com │
|
||||
│ Cache przechowuje referral przez długi czas (np. 48h) │
|
||||
│ Kolejne tysiące zapytań o .com → z cache, bez root │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Analiza ilościowa
|
||||
|
||||
| Poziom | Liczba domen | Zapytania bez cache | Z cache |
|
||||
|--------|--------------|---------------------|---------|
|
||||
| **Root** | 1 (.) | ~100% zapytań | ~0.01% |
|
||||
| **TLD** | ~1500 | ~100% zapytań | ~0.1% |
|
||||
| **Authoritative** | Miliony | Proporcjonalnie | Zależne od TTL |
|
||||
|
||||
### Dlaczego ROOT i TLD zyskują więcej niż authoritative?
|
||||
|
||||
1. **Mniejsza liczba = więcej zapytań na serwer:**
|
||||
- 13 root servers vs miliony domen
|
||||
- Każde zapytanie o DOWOLNĄ domenę musi przejść przez root i TLD
|
||||
|
||||
2. **Długie TTL referrali:**
|
||||
- Root NS referrals: TTL 48h - 7 dni
|
||||
- TLD NS referrals: TTL 24h - 48h
|
||||
- Authoritative records: często krótsze (minuty-godziny)
|
||||
|
||||
3. **Hierarchiczna struktura:**
|
||||
```
|
||||
Zapytanie o www.google.com:
|
||||
- Root: "Oto serwery .com" → cached
|
||||
- TLD: "Oto serwery google.com" → cached
|
||||
- Auth: "Oto IP www.google.com" → cached (ale krótszy TTL)
|
||||
|
||||
Zapytanie o www.facebook.com:
|
||||
- Root: z cache! ✓
|
||||
- TLD: z cache! ✓ (ten sam .com)
|
||||
- Auth: trzeba pytać (inna domena)
|
||||
```
|
||||
|
||||
### Podsumowanie zysków z cachingu
|
||||
|
||||
```
|
||||
REDUKCJA RUCHU DZIĘKI CACHINGOWI:
|
||||
|
||||
Root Servers: ████████████████████████████░░ ~99.9% redukcja
|
||||
TLD Servers: ██████████████████████████░░░░ ~99% redukcja
|
||||
Authoritative: ████████████░░░░░░░░░░░░░░░░░░ ~50-90% redukcja*
|
||||
|
||||
*zależy od TTL i popularności domeny
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Typy rekordów DNS
|
||||
|
||||
| Rekord | Przeznaczenie | Przykład |
|
||||
|--------|---------------|----------|
|
||||
| **A** | IPv4 address | www → 93.184.216.34 |
|
||||
| **AAAA** | IPv6 address | www → 2606:2800:220:1:... |
|
||||
| **CNAME** | Alias (canonical name) | blog → www.example.com |
|
||||
| **MX** | Mail server | @ → 10 mail.example.com |
|
||||
| **NS** | Name server | @ → ns1.example.com |
|
||||
| **TXT** | Tekst (SPF, DKIM) | @ → "v=spf1 ..." |
|
||||
| **SOA** | Start of Authority | Metadata strefy |
|
||||
| **PTR** | Reverse DNS | IP → nazwa |
|
||||
| **SRV** | Service location | _sip._tcp → server:5060 |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tabela porównawcza serwerów DNS
|
||||
|
||||
| Typ serwera | Funkcja | Cache | Autorytatywny |
|
||||
|-------------|---------|-------|---------------|
|
||||
| **Root** | Wskazuje TLD | Nie | Tak (dla .) |
|
||||
| **TLD** | Wskazuje NS domen | Nie | Tak (dla TLD) |
|
||||
| **Authoritative** | Przechowuje rekordy | Nie | Tak |
|
||||
| **Recursive** | Rozwiązuje dla klientów | **TAK** | Nie |
|
||||
| **Forwarder** | Przekazuje zapytania | Może | Nie |
|
||||
| **Stub** | Klient systemu | Minimalny | Nie |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "RATS" dla hierarchii DNS:
|
||||
- **R**oot - korzeń drzewa
|
||||
- **A**uthoritative TLD - .com, .pl...
|
||||
- **T**arget NS - ns1.example.com
|
||||
- **S**tub resolver - klient
|
||||
|
||||
### "ROOT COOL" dla zysków z cache:
|
||||
- **ROOT** = **C**ache **O**ffers **O**verwhelming **L**oad reduction
|
||||
- Root servers byłyby przeciążone bez cache w resolverach
|
||||
|
||||
### "TRIP" dla procesu rozwiązywania:
|
||||
- **T**ranslate - tłumaczenie nazwy na IP
|
||||
- **R**ecursive - resolver robi pracę
|
||||
- **I**terative - serwery autorytatywne odpowiadają lub odsyłają
|
||||
- **P**ersist - cache przechowuje wynik
|
||||
|
||||
### "A-QUAD" dla popularnych rekordów:
|
||||
- **A** - Address (IPv4)
|
||||
- **AAAA** - Address (IPv6) - 4×A
|
||||
- **D**NS - NS record
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Jak działa anycast w kontekście root servers?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Anycast** = ten sam adres IP na wielu serwerach geograficznie rozproszonych.
|
||||
|
||||
```
|
||||
Użytkownik w Polsce → najbliższy serwer a.root-servers.net (Frankfurt)
|
||||
Użytkownik w USA → najbliższy serwer a.root-servers.net (Virginia)
|
||||
Użytkownik w Japonii → najbliższy serwer a.root-servers.net (Tokyo)
|
||||
|
||||
Wszystkie mają ten sam adres IP!
|
||||
Routing BGP kieruje do najbliższego.
|
||||
```
|
||||
|
||||
**Korzyści:**
|
||||
- Niższe opóźnienia (latency)
|
||||
- Odporność na DDoS
|
||||
- Load balancing geograficzny
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Co to jest DNS poisoning/spoofing?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**DNS Cache Poisoning** = atak polegający na wstrzyknięciu fałszywych rekordów do cache resolvera.
|
||||
|
||||
```
|
||||
Atakujący → fałszywa odpowiedź "google.com = 1.2.3.4"
|
||||
↓
|
||||
Resolver zapisuje w cache
|
||||
↓
|
||||
Użytkownicy kierowani na serwer atakującego
|
||||
```
|
||||
|
||||
**Zabezpieczenia:**
|
||||
- **DNSSEC** - podpisy kryptograficzne rekordów
|
||||
- **Randomizacja portów źródłowych**
|
||||
- **0x20 encoding** - randomizacja wielkości liter
|
||||
- **DNS over HTTPS (DoH)** / **DNS over TLS (DoT)**
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Co to jest DNSSEC?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**DNSSEC (DNS Security Extensions)** = rozszerzenie dodające kryptograficzne podpisy do rekordów DNS.
|
||||
|
||||
**Nowe typy rekordów:**
|
||||
- **RRSIG** - podpis rekordu
|
||||
- **DNSKEY** - klucz publiczny
|
||||
- **DS** - delegacja bezpieczeństwa (u rodzica)
|
||||
- **NSEC/NSEC3** - dowód nieistnienia
|
||||
|
||||
**Łańcuch zaufania:**
|
||||
```
|
||||
Root (.) → podpisuje DS dla .com
|
||||
.com → podpisuje DS dla example.com
|
||||
example.com → podpisuje A dla www
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Czym różni się DNS over HTTPS od DNS over TLS?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Cecha | DoT (DNS over TLS) | DoH (DNS over HTTPS) |
|
||||
|-------|-------------------|---------------------|
|
||||
| Port | 853 (dedykowany) | 443 (jak HTTPS) |
|
||||
| Protokół | TLS | HTTPS |
|
||||
| Widoczność | Łatwy do zablokowania | Trudny do odróżnienia |
|
||||
| Format | Wire format DNS | Wire lub JSON |
|
||||
| Klient | Systemowy resolver | Przeglądarka/aplikacja |
|
||||
|
||||
**DoH** jest trudniejszy do blokowania/monitorowania - wygląda jak normalny ruch HTTPS.
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co się stanie, jeśli wszystkie root servers przestaną działać?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Krótkoterminowo (godziny):** Większość działa dzięki cache
|
||||
- Resolwery mają w cache adresy TLD servers
|
||||
- TTL root referrals: ~48h
|
||||
|
||||
**Średnioterminowo (dni):** Stopniowa degradacja
|
||||
- Cache wygasa
|
||||
- Nowe domeny nierozwiązywalne
|
||||
- Istniejące z długim TTL jeszcze działają
|
||||
|
||||
**W praktyce:** Niemożliwe do osiągnięcia
|
||||
- 13 klastrów anycast
|
||||
- Setki fizycznych serwerów
|
||||
- Geograficzne rozproszenie
|
||||
- Różni operatorzy
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Jak działa Negative Caching?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Negative caching** = cache'owanie odpowiedzi "nie istnieje" (NXDOMAIN).
|
||||
|
||||
```
|
||||
Zapytanie: nieistniejaca.example.com
|
||||
Odpowiedź: NXDOMAIN (SOA z TTL dla negative cache)
|
||||
Cache: "nieistniejaca.example.com = NXDOMAIN" przez TTL
|
||||
```
|
||||
|
||||
**Korzyści:**
|
||||
- Redukcja ruchu przy literówkach
|
||||
- Szybsza odpowiedź dla nieistniejących domen
|
||||
- Ochrona przed niektórymi atakami
|
||||
|
||||
**RFC 2308** definiuje negative caching.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **ROOT i TLD zyskują NAJWIĘCEJ** na cachingu w resolverach
|
||||
2. **Recursive resolver** = wykonuje pełne rozwiązywanie + cache
|
||||
3. **Authoritative** = źródło prawdy, nie cache'uje
|
||||
4. **Hierarchia:** Root → TLD → Authoritative NS
|
||||
5. **TTL** określa czas życia rekordu w cache
|
||||
6. **Anycast** pozwala 13 root serwerom obsługiwać cały Internet
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. RFC 1034, 1035 - DNS specification
|
||||
2. RFC 2308 - Negative caching
|
||||
3. RFC 4033-4035 - DNSSEC
|
||||
4. Cricket Liu - "DNS and BIND"
|
||||
5. root-servers.org - informacje o root servers
|
||||
@ -1,433 +0,0 @@
|
||||
# Pytanie 8: TCP Three-Way Handshake
|
||||
|
||||
## Pytanie
|
||||
**"Jaki jest cel uzgadniania trójetapowego (three way handshake) w protokole TCP? Jaka jest interpretacja numerów sekwencyjnych i potwierdzenia? Jaka jest wartość początkowa numeru sekwencyjnego?"**
|
||||
|
||||
Przedmiot: SKM (Sieci Komputerowe)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie do TCP
|
||||
|
||||
**TCP (Transmission Control Protocol)** to protokół warstwy transportowej zapewniający:
|
||||
- Niezawodne dostarczanie danych
|
||||
- Kontrolę przepływu
|
||||
- Kontrolę przeciążenia
|
||||
- Połączeniowość (connection-oriented)
|
||||
|
||||
---
|
||||
|
||||
## 1. Three-Way Handshake - cel i przebieg
|
||||
|
||||
### Cele uzgadniania trójetapowego
|
||||
|
||||
1. **Nawiązanie połączenia** - obie strony zgadzają się na komunikację
|
||||
2. **Synchronizacja numerów sekwencyjnych** - ISN (Initial Sequence Number)
|
||||
3. **Uzgodnienie parametrów** - MSS, Window Scale, SACK, Timestamps
|
||||
4. **Weryfikacja dostępności** - obie strony są aktywne i gotowe
|
||||
|
||||
### Przebieg (diagram)
|
||||
|
||||
```
|
||||
Klient Serwer
|
||||
│ │
|
||||
│ (1) SYN, seq=x │
|
||||
│──────────────────────────────────────────→│
|
||||
│ │
|
||||
│ (2) SYN+ACK, seq=y, ack=x+1 │
|
||||
│←──────────────────────────────────────────│
|
||||
│ │
|
||||
│ (3) ACK, seq=x+1, ack=y+1 │
|
||||
│──────────────────────────────────────────→│
|
||||
│ │
|
||||
│ [POŁĄCZENIE NAWIĄZANE] │
|
||||
│ │
|
||||
```
|
||||
|
||||
### Szczegółowy opis kroków
|
||||
|
||||
#### Krok 1: SYN (Synchronize)
|
||||
```
|
||||
Klient → Serwer:
|
||||
┌────────────────────────────────────────┐
|
||||
│ Flaga: SYN = 1 │
|
||||
│ Sequence Number: x (ISN klienta) │
|
||||
│ Acknowledgment Number: 0 (nieistotny) │
|
||||
│ Opcje: MSS, Window Scale, SACK, etc. │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
- Klient inicjuje połączenie
|
||||
- Wysyła swój ISN (Initial Sequence Number)
|
||||
- Stan klienta: SYN_SENT
|
||||
|
||||
#### Krok 2: SYN-ACK (Synchronize-Acknowledge)
|
||||
```
|
||||
Serwer → Klient:
|
||||
┌────────────────────────────────────────┐
|
||||
│ Flagi: SYN = 1, ACK = 1 │
|
||||
│ Sequence Number: y (ISN serwera) │
|
||||
│ Acknowledgment Number: x + 1 │
|
||||
│ Opcje: MSS, Window Scale, etc. │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
- Serwer potwierdza otrzymanie SYN (ACK = x+1)
|
||||
- Serwer wysyła swój ISN
|
||||
- Stan serwera: SYN_RECEIVED
|
||||
|
||||
#### Krok 3: ACK (Acknowledge)
|
||||
```
|
||||
Klient → Serwer:
|
||||
┌────────────────────────────────────────┐
|
||||
│ Flaga: ACK = 1 │
|
||||
│ Sequence Number: x + 1 │
|
||||
│ Acknowledgment Number: y + 1 │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
- Klient potwierdza otrzymanie SYN serwera
|
||||
- Połączenie nawiązane (ESTABLISHED)
|
||||
- Może zawierać już dane (TCP Fast Open)
|
||||
|
||||
---
|
||||
|
||||
## 2. Numery sekwencyjne (Sequence Numbers)
|
||||
|
||||
### Interpretacja
|
||||
|
||||
**Sequence Number (SEQ)** = numer pierwszego bajtu danych w segmencie
|
||||
|
||||
```
|
||||
Strumień danych:
|
||||
Bajty: [0][1][2][3][4][5][6][7][8][9][10][11][12]...
|
||||
|
||||
Segment 1: SEQ=0, dane = bajty 0-4 (5 bajtów)
|
||||
Segment 2: SEQ=5, dane = bajty 5-9 (5 bajtów)
|
||||
Segment 3: SEQ=10, dane = bajty 10-12 (3 bajty)
|
||||
```
|
||||
|
||||
### Funkcje numerów sekwencyjnych
|
||||
|
||||
| Funkcja | Opis |
|
||||
|---------|------|
|
||||
| **Kolejność** | Odbiorca składa segmenty we właściwej kolejności |
|
||||
| **Wykrywanie duplikatów** | Ten sam SEQ = duplikat |
|
||||
| **Wykrywanie braków** | Luka w SEQ = brakujący segment |
|
||||
| **Potwierdzanie** | ACK wskazuje oczekiwany następny SEQ |
|
||||
|
||||
### Przykład transmisji
|
||||
|
||||
```
|
||||
Klient (ISN=1000) Serwer (ISN=5000)
|
||||
│ │
|
||||
│ SEQ=1000, "Hello" (5 bytes) │
|
||||
│────────────────────────────────────→│
|
||||
│ │
|
||||
│ SEQ=5000, ACK=1005, "Hi" (2 bytes) │
|
||||
│←────────────────────────────────────│
|
||||
│ │
|
||||
│ SEQ=1005, ACK=5002, "World" (5 b) │
|
||||
│────────────────────────────────────→│
|
||||
│ │
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Numery potwierdzenia (Acknowledgment Numbers)
|
||||
|
||||
### Interpretacja
|
||||
|
||||
**Acknowledgment Number (ACK)** = numer **następnego oczekiwanego** bajtu
|
||||
|
||||
```
|
||||
ACK = ostatni_otrzymany_SEQ + liczba_otrzymanych_bajtów
|
||||
```
|
||||
|
||||
### Kumulatywne potwierdzenia
|
||||
|
||||
TCP używa **cumulative ACK** - potwierdza wszystkie bajty do danego numeru:
|
||||
|
||||
```
|
||||
Otrzymano: SEQ=100 (10 bajtów), SEQ=110 (10 bajtów)
|
||||
ACK = 120 (potwierdza bajty 100-119)
|
||||
|
||||
Otrzymano: SEQ=100 (10 bajtów), BRAK SEQ=110, SEQ=120 (10 bajtów)
|
||||
ACK = 110 (nie można potwierdzić 120, bo brakuje 110-119!)
|
||||
```
|
||||
|
||||
### Selective ACK (SACK)
|
||||
|
||||
Opcja TCP pozwalająca potwierdzać niesąsiednie bloki:
|
||||
|
||||
```
|
||||
Otrzymano: SEQ=100, BRAK SEQ=110, SEQ=120
|
||||
ACK = 110
|
||||
SACK: [120-130] ← "mam też te bajty"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Wartość początkowa numeru sekwencyjnego (ISN)
|
||||
|
||||
### Dlaczego ISN nie zaczyna od 0?
|
||||
|
||||
1. **Bezpieczeństwo** - przewidywalny ISN umożliwia ataki (TCP hijacking)
|
||||
2. **Unikanie kolizji** - stare segmenty z poprzednich połączeń nie będą mylone z nowymi
|
||||
|
||||
### Generowanie ISN
|
||||
|
||||
#### Historycznie (RFC 793):
|
||||
```
|
||||
ISN = (4 mikrosekundy timer) mod 2^32
|
||||
```
|
||||
Zwiększany o 1 co 4μs → pełny cykl co ~4.55 godziny
|
||||
|
||||
#### Współcześnie (RFC 6528):
|
||||
```
|
||||
ISN = M + F(localhost, localport, remotehost, remoteport, secretkey)
|
||||
```
|
||||
Gdzie:
|
||||
- **M** = timer (jak wyżej)
|
||||
- **F** = funkcja kryptograficzna (MD5/SHA)
|
||||
- **secretkey** = tajny klucz serwera
|
||||
|
||||
### Właściwości dobrego ISN
|
||||
|
||||
| Właściwość | Powód |
|
||||
|------------|-------|
|
||||
| **Losowy** | Utrudnia ataki typu sequence prediction |
|
||||
| **Unikalny** | Różny dla każdego połączenia |
|
||||
| **Monotonicznie rosnący** | Unikanie kolizji z poprzednimi połączeniami |
|
||||
|
||||
### Zakres numerów sekwencyjnych
|
||||
|
||||
```
|
||||
SEQ: 32 bity → zakres 0 do 4,294,967,295 (2^32 - 1)
|
||||
|
||||
Przy szybkości 1 Gbps:
|
||||
- 125 MB/s danych
|
||||
- Przepełnienie (wrap-around) co ~34 sekundy!
|
||||
|
||||
Rozwiązanie: PAWS (Protection Against Wrapped Sequences)
|
||||
- Używa opcji Timestamp do rozróżniania "starych" i "nowych" numerów
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Stany połączenia TCP
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
┌────────→│ CLOSED │←────────┐
|
||||
│ └─────────────┘ │
|
||||
│ │ │
|
||||
(timeout) (passive open) (active open)
|
||||
│ ↓ │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ LISTEN │ │
|
||||
│ └─────────────┘ │
|
||||
│ │ │
|
||||
│ (recv SYN) (send SYN)
|
||||
│ ↓ ↓
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ TIME_WAIT │ │ SYN_RECEIVED│ │ SYN_SENT │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
↑ │ │
|
||||
(recv FIN+ACK) (send SYN+ACK) (recv SYN+ACK)
|
||||
│ ↓ ↓
|
||||
┌─────────────┐ ┌─────────────────────────────┐
|
||||
│ FIN_WAIT_2 │ │ ESTABLISHED │
|
||||
└─────────────┘ └─────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Zamykanie połączenia (Four-Way Handshake)
|
||||
|
||||
```
|
||||
Klient Serwer
|
||||
│ │
|
||||
│ (1) FIN, seq=u │
|
||||
│──────────────────────────────────────────→│
|
||||
│ │
|
||||
│ (2) ACK, ack=u+1 │
|
||||
│←──────────────────────────────────────────│
|
||||
│ │
|
||||
│ (serwer może jeszcze wysyłać dane) │
|
||||
│ │
|
||||
│ (3) FIN, seq=v │
|
||||
│←──────────────────────────────────────────│
|
||||
│ │
|
||||
│ (4) ACK, ack=v+1 │
|
||||
│──────────────────────────────────────────→│
|
||||
│ │
|
||||
│ [TIME_WAIT: 2×MSL] │
|
||||
│ │
|
||||
```
|
||||
|
||||
**MSL (Maximum Segment Lifetime)** = maksymalny czas życia segmentu (~2 minuty)
|
||||
**TIME_WAIT = 2×MSL** = ~4 minuty (oczekiwanie na zagubione segmenty)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Podsumowanie Three-Way Handshake
|
||||
|
||||
| Krok | Kierunek | Flagi | SEQ | ACK | Cel |
|
||||
|------|----------|-------|-----|-----|-----|
|
||||
| 1 | C→S | SYN | x | - | Inicjacja, ISN klienta |
|
||||
| 2 | S→C | SYN+ACK | y | x+1 | Akceptacja, ISN serwera |
|
||||
| 3 | C→S | ACK | x+1 | y+1 | Potwierdzenie, połączenie gotowe |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "SYN-SYN/ACK-ACK" - trzy kroki:
|
||||
- **SYN** - "Chcę rozmawiać" (klient)
|
||||
- **SYN/ACK** - "OK, ja też" (serwer)
|
||||
- **ACK** - "Super, zaczynamy" (klient)
|
||||
|
||||
### "SEQ = Sent, ACK = Expected":
|
||||
- **SEQ**uence = numer wysyłanego bajtu
|
||||
- **ACK**nowledgment = numer oczekiwanego bajtu
|
||||
|
||||
### "ISN = Initial Secret Number":
|
||||
- **I**nitial - początkowy
|
||||
- **S**ecret - losowy dla bezpieczeństwa
|
||||
- **N**umber - 32-bitowa liczba
|
||||
|
||||
### "ESTABLISHED po trzech krokach":
|
||||
- 1: SYN_SENT
|
||||
- 2: SYN_RECEIVED
|
||||
- 3: **ESTABLISHED** (obie strony)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Dlaczego trzy kroki, nie dwa?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
Dwa kroki nie wystarczą do synchronizacji **obu** ISN:
|
||||
|
||||
```
|
||||
Dwa kroki (hipotetycznie):
|
||||
Klient: SYN, seq=x → Serwer zna ISN klienta
|
||||
Serwer: SYN+ACK, seq=y → Klient zna ISN serwera
|
||||
→ Ale serwer NIE WIE, czy klient otrzymał y!
|
||||
|
||||
Trzy kroki:
|
||||
Klient: SYN, seq=x → Serwer zna ISN klienta
|
||||
Serwer: SYN+ACK, seq=y → Klient zna ISN serwera
|
||||
Klient: ACK, ack=y+1 → Serwer WIE, że klient otrzymał y ✓
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Co to jest SYN flood attack?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**SYN flood** = atak DoS wysyłający masę SYN bez dokończenia handshake'a.
|
||||
|
||||
```
|
||||
Atakujący: SYN, SYN, SYN, SYN... (tysiące)
|
||||
Serwer: SYN+ACK, SYN+ACK... (czeka na ACK)
|
||||
→ Kolejka half-open connections pełna
|
||||
→ Serwer nie może przyjąć nowych połączeń
|
||||
```
|
||||
|
||||
**Obrona:**
|
||||
- **SYN cookies** - serwer nie przechowuje stanu, koduje go w ISN
|
||||
- **Zwiększenie kolejki SYN**
|
||||
- **Zmniejszenie timeout SYN_RECEIVED**
|
||||
- **Firewall/IDS**
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Co to jest TCP Fast Open (TFO)?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**TFO** pozwala wysyłać dane już w pierwszym SYN (0-RTT):
|
||||
|
||||
```
|
||||
Standardowo: TFO:
|
||||
SYN → SYN + dane →
|
||||
← SYN+ACK ← SYN+ACK + dane
|
||||
ACK + dane → ACK →
|
||||
|
||||
3 RTT do danych 1 RTT do danych!
|
||||
```
|
||||
|
||||
**Wymaga:** Cookie TFO z poprzedniego połączenia (uzyskany przy pierwszym handshake).
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Jak działa retransmisja w TCP?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
1. **Timeout (RTO):** Brak ACK w określonym czasie → retransmisja
|
||||
2. **Fast Retransmit:** 3 duplikaty ACK → retransmisja bez czekania na timeout
|
||||
|
||||
```
|
||||
Wysłano: SEQ=100, SEQ=200, SEQ=300
|
||||
Zgubiono: SEQ=200
|
||||
|
||||
Odbiorca: ACK=200, ACK=200, ACK=200 (3× duplikat)
|
||||
Nadawca: "Ah, brakuje 200!" → retransmisja SEQ=200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co oznacza flaga RST?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**RST (Reset)** = natychmiastowe przerwanie połączenia.
|
||||
|
||||
**Kiedy wysyłane:**
|
||||
- Segment do zamkniętego portu
|
||||
- Segment do nieistniejącego połączenia
|
||||
- Połączenie w nieprawidłowym stanie
|
||||
- Aplikacja chce natychmiast zamknąć (bez FIN handshake)
|
||||
|
||||
```
|
||||
RST nie wymaga potwierdzenia - połączenie natychmiast zamknięte.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Wyjaśnij opcje negocjowane podczas handshake"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Opcja | Opis | Wartość typowa |
|
||||
|-------|------|----------------|
|
||||
| **MSS** | Maximum Segment Size | 1460 (Ethernet) |
|
||||
| **Window Scale** | Mnożnik okna (>65535) | 0-14 (×2^n) |
|
||||
| **SACK Permitted** | Selective ACK dozwolone | tak/nie |
|
||||
| **Timestamp** | Pomiar RTT, PAWS | 32-bit timer |
|
||||
| **NOP** | Padding | - |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **3 kroki:** SYN → SYN+ACK → ACK
|
||||
2. **SEQ** = numer pierwszego bajtu w segmencie
|
||||
3. **ACK** = numer **następnego oczekiwanego** bajtu
|
||||
4. **ISN** = losowy, dla bezpieczeństwa i unikania kolizji
|
||||
5. **Zamknięcie:** 4 kroki (FIN → ACK → FIN → ACK) + TIME_WAIT
|
||||
6. **SYN flood** - atak DoS, obrona: SYN cookies
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. RFC 793 - TCP Specification
|
||||
2. RFC 6528 - Defending Against Sequence Number Attacks
|
||||
3. RFC 7413 - TCP Fast Open
|
||||
4. Stevens - "TCP/IP Illustrated, Volume 1"
|
||||
@ -1,673 +0,0 @@
|
||||
# Pytanie 9: Procesy i wątki w systemie operacyjnym
|
||||
|
||||
## Pytanie
|
||||
**"Procesy i wątki w systemie operacyjnym. Omówić budowę, szybkość działania i zakres zastosowania. Przedstawić problemy i możliwości komunikacji i synchronizacji."**
|
||||
|
||||
Przedmiot: SOI (Systemy Operacyjne)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
**Proces** i **wątek** to podstawowe jednostki wykonania w systemach operacyjnych. Różnią się poziomem izolacji i kosztami przełączania.
|
||||
|
||||
---
|
||||
|
||||
## 1. Proces (Process)
|
||||
|
||||
### Definicja
|
||||
**Proces** = program w trakcie wykonania + jego kontekst (zasoby, stan).
|
||||
|
||||
### Budowa procesu
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PRZESTRZEŃ ADRESOWA PROCESU │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────────┐ │
|
||||
│ │ STOS │ ← zmienne lokalne, adresy powrotu │
|
||||
│ │ (Stack) │ rośnie w dół ↓ │
|
||||
│ ├─────────────────┤ │
|
||||
│ │ ↓ │ │
|
||||
│ │ │ ← wolna przestrzeń │
|
||||
│ │ ↑ │ │
|
||||
│ ├─────────────────┤ │
|
||||
│ │ STERTA │ ← pamięć dynamiczna (malloc/new) │
|
||||
│ │ (Heap) │ rośnie w górę ↑ │
|
||||
│ ├─────────────────┤ │
|
||||
│ │ BSS │ ← zmienne globalne niezainicjowane │
|
||||
│ ├─────────────────┤ │
|
||||
│ │ DATA │ ← zmienne globalne zainicjowane │
|
||||
│ ├─────────────────┤ │
|
||||
│ │ TEXT │ ← kod programu (read-only) │
|
||||
│ │ (Code) │ │
|
||||
│ └─────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### PCB (Process Control Block)
|
||||
|
||||
Struktura w jądrze przechowująca informacje o procesie:
|
||||
|
||||
| Pole | Opis |
|
||||
|------|------|
|
||||
| **PID** | Identyfikator procesu |
|
||||
| **Stan** | Running, Ready, Blocked, etc. |
|
||||
| **Rejestry CPU** | PC, SP, flagi, rejestry ogólne |
|
||||
| **Informacje o pamięci** | Tablice stron, limity |
|
||||
| **Informacje I/O** | Otwarte pliki, urządzenia |
|
||||
| **Informacje rozliczeniowe** | Czas CPU, limity |
|
||||
| **Priorytet** | Szeregowanie |
|
||||
| **Wskaźniki** | Rodzic, dzieci, kolejki |
|
||||
|
||||
### Stany procesu
|
||||
|
||||
```
|
||||
┌──────────────────┐
|
||||
(utworzenie) │ │ (zakończenie)
|
||||
↓ │ │ ↓
|
||||
┌─────────┐ │ ┌──────────┐ │ ┌──────────┐
|
||||
│ NEW │───┼──→│ READY │←──┼──│TERMINATED│
|
||||
└─────────┘ │ └──────────┘ │ └──────────┘
|
||||
│ ↑↓ │
|
||||
│ (scheduler) │
|
||||
│ ↓↑ │
|
||||
│ ┌──────────┐ │
|
||||
│ │ RUNNING │ │
|
||||
│ └──────────┘ │
|
||||
│ │ │
|
||||
│ (I/O, wait) │
|
||||
│ ↓ │
|
||||
│ ┌──────────┐ │
|
||||
└───│ BLOCKED │───┘
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Wątek (Thread)
|
||||
|
||||
### Definicja
|
||||
**Wątek** = lekka jednostka wykonania współdzieląca przestrzeń adresową procesu.
|
||||
|
||||
### Budowa wątku
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PROCES │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ WSPÓŁDZIELONE: PRYWATNE (per wątek): │
|
||||
│ ┌─────────────────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ Przestrzeń │ │ Stos │ │ Stos │ │ Stos │ │
|
||||
│ │ adresowa │ │ W1 │ │ W2 │ │ W3 │ │
|
||||
│ ├─────────────────┤ ├───────┤ ├───────┤ ├───────┤ │
|
||||
│ │ Kod (TEXT) │ │Rejestry│ │Rejestry│ │Rejestry│ │
|
||||
│ ├─────────────────┤ │ CPU │ │ CPU │ │ CPU │ │
|
||||
│ │ Dane globalne │ ├───────┤ ├───────┤ ├───────┤ │
|
||||
│ ├─────────────────┤ │ PC │ │ PC │ │ PC │ │
|
||||
│ │ Sterta (Heap) │ ├───────┤ ├───────┤ ├───────┤ │
|
||||
│ ├─────────────────┤ │ TID │ │ TID │ │ TID │ │
|
||||
│ │ Otwarte pliki │ └───────┘ └───────┘ └───────┘ │
|
||||
│ │ Sygnały │ Wątek 1 Wątek 2 Wątek 3 │
|
||||
│ └─────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### TCB (Thread Control Block)
|
||||
|
||||
| Pole | Opis |
|
||||
|------|------|
|
||||
| **TID** | Identyfikator wątku |
|
||||
| **Stan** | Running, Ready, Blocked |
|
||||
| **Rejestry** | PC, SP, rejestry ogólne |
|
||||
| **Stos** | Wskaźnik do prywatnego stosu |
|
||||
| **Priorytet** | Szeregowanie |
|
||||
| **Wskaźnik do PCB** | Proces macierzysty |
|
||||
|
||||
---
|
||||
|
||||
## 3. Porównanie: Proces vs Wątek
|
||||
|
||||
### Tabela porównawcza
|
||||
|
||||
| Cecha | Proces | Wątek |
|
||||
|-------|--------|-------|
|
||||
| **Przestrzeń adresowa** | Własna, izolowana | Współdzielona z procesem |
|
||||
| **Tworzenie** | Wolne (~ms) | Szybkie (~μs) |
|
||||
| **Przełączanie kontekstu** | Wolne (TLB flush) | Szybkie (tylko rejestry) |
|
||||
| **Komunikacja** | IPC (pipe, socket, shm) | Bezpośrednia (współdzielona pamięć) |
|
||||
| **Izolacja** | Pełna | Brak (awaria = awaria procesu) |
|
||||
| **Zasoby** | Własne | Współdzielone |
|
||||
| **Wieloprocesorowość** | Naturalna | Wymaga synchronizacji |
|
||||
|
||||
### Koszty czasowe (typowe)
|
||||
|
||||
| Operacja | Czas |
|
||||
|----------|------|
|
||||
| Tworzenie procesu | 1-10 ms |
|
||||
| Tworzenie wątku | 10-100 μs |
|
||||
| Przełączanie procesu | 1-10 μs |
|
||||
| Przełączanie wątku | 0.1-1 μs |
|
||||
| Komunikacja IPC | 1-100 μs |
|
||||
| Współdzielona pamięć | 10-100 ns |
|
||||
|
||||
---
|
||||
|
||||
## 4. Typy wątków
|
||||
|
||||
### Wątki użytkownika (User-level Threads)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ PRZESTRZEŃ UŻYTKOWNIKA │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ Biblioteka wątków (pthread) │ │
|
||||
│ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │
|
||||
│ │ │ W1 │ │ W2 │ │ W3 │ │ │
|
||||
│ │ └─────┘ └─────┘ └─────┘ │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
├─────────────────────────────────────────┤
|
||||
│ JĄDRO │
|
||||
│ Widzi tylko JEDEN wątek (proces) │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Zalety:** Szybkie przełączanie, przenośność
|
||||
**Wady:** Blokujące wywołanie blokuje wszystkie wątki, brak prawdziwej równoległości
|
||||
|
||||
### Wątki jądra (Kernel-level Threads)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ PRZESTRZEŃ UŻYTKOWNIKA │
|
||||
│ ┌─────┐ ┌─────┐ ┌─────┐ │
|
||||
│ │ W1 │ │ W2 │ │ W3 │ │
|
||||
│ └──┬──┘ └──┬──┘ └──┬──┘ │
|
||||
├─────────┼───────┼───────┼───────────────┤
|
||||
│ ↓ ↓ ↓ │
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ JĄDRO (scheduler) │ │
|
||||
│ │ Zarządza wszystkimi wątkami│ │
|
||||
│ └─────────────────────────────┘ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Zalety:** Prawdziwa równoległość, blokada jednego nie blokuje innych
|
||||
**Wady:** Wolniejsze operacje (wywołanie systemowe)
|
||||
|
||||
### Modele mapowania
|
||||
|
||||
| Model | Opis | Przykłady |
|
||||
|-------|------|-----------|
|
||||
| **1:1** | 1 wątek user = 1 wątek kernel | Linux, Windows |
|
||||
| **N:1** | N wątków user = 1 wątek kernel | Green threads |
|
||||
| **M:N** | M wątków user = N wątków kernel | Solaris, Go goroutines |
|
||||
|
||||
---
|
||||
|
||||
## 5. Komunikacja między procesami (IPC)
|
||||
|
||||
### Mechanizmy IPC
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ MECHANIZMY IPC │
|
||||
├─────────────────┬─────────────────┬─────────────────────────────┤
|
||||
│ SYGNAŁY │ POTOKI │ PAMIĘĆ WSPÓŁDZIELONA │
|
||||
│ (Signals) │ (Pipes) │ (Shared Memory) │
|
||||
├─────────────────┼─────────────────┼─────────────────────────────┤
|
||||
│ KOLEJKI │ GNIAZDA │ PLIKI MAPOWANE │
|
||||
│ KOMUNIKATÓW │ (Sockets) │ (Memory-mapped) │
|
||||
│ (Msg Queues) │ │ │
|
||||
└─────────────────┴─────────────────┴─────────────────────────────┘
|
||||
```
|
||||
|
||||
### Szczegóły mechanizmów
|
||||
|
||||
#### Potoki (Pipes)
|
||||
|
||||
```c
|
||||
// Potok nienazwany (anonimowy)
|
||||
int fd[2];
|
||||
pipe(fd);
|
||||
// fd[0] - odczyt, fd[1] - zapis
|
||||
|
||||
// Potok nazwany (FIFO)
|
||||
mkfifo("/tmp/myfifo", 0666);
|
||||
```
|
||||
|
||||
**Cechy:** Jednokierunkowe, FIFO, między powiązanymi procesami (anonimowe)
|
||||
|
||||
#### Pamięć współdzielona (Shared Memory)
|
||||
|
||||
```c
|
||||
// POSIX shared memory
|
||||
int fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
|
||||
ftruncate(fd, SIZE);
|
||||
void* ptr = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
// Użycie
|
||||
strcpy(ptr, "Hello from process A");
|
||||
// Proces B może odczytać przez ten sam shm_open
|
||||
```
|
||||
|
||||
**Cechy:** Najszybszy IPC, wymaga synchronizacji!
|
||||
|
||||
#### Gniazda (Sockets)
|
||||
|
||||
```c
|
||||
// Unix domain socket (lokalne)
|
||||
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
// Network socket (sieciowe)
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
```
|
||||
|
||||
**Cechy:** Uniwersalne, lokalne i sieciowe, dwukierunkowe
|
||||
|
||||
#### Kolejki komunikatów (Message Queues)
|
||||
|
||||
```c
|
||||
// POSIX message queue
|
||||
mqd_t mq = mq_open("/my_queue", O_CREAT | O_RDWR, 0666, &attr);
|
||||
mq_send(mq, message, strlen(message), priority);
|
||||
mq_receive(mq, buffer, MAX_SIZE, &priority);
|
||||
```
|
||||
|
||||
**Cechy:** Asynchroniczne, z priorytetami, zachowują granice wiadomości
|
||||
|
||||
---
|
||||
|
||||
## 6. Synchronizacja
|
||||
|
||||
### Problemy współbieżności
|
||||
|
||||
#### 1. Wyścig (Race Condition)
|
||||
|
||||
```c
|
||||
// Dwa wątki wykonują:
|
||||
counter++; // NIE ATOMOWE!
|
||||
|
||||
// W asemblerze:
|
||||
// LOAD counter → reg
|
||||
// ADD 1 → reg
|
||||
// STORE reg → counter
|
||||
|
||||
// Możliwy przebieg:
|
||||
// Wątek A: LOAD (counter=5)
|
||||
// Wątek B: LOAD (counter=5)
|
||||
// Wątek A: ADD (reg=6)
|
||||
// Wątek B: ADD (reg=6)
|
||||
// Wątek A: STORE (counter=6)
|
||||
// Wątek B: STORE (counter=6)
|
||||
// Wynik: 6 zamiast 7!
|
||||
```
|
||||
|
||||
#### 2. Zakleszczenie (Deadlock)
|
||||
|
||||
```
|
||||
Wątek A: lock(mutex1) → czeka na mutex2
|
||||
Wątek B: lock(mutex2) → czeka na mutex1
|
||||
|
||||
→ DEADLOCK! (wzajemne oczekiwanie)
|
||||
```
|
||||
|
||||
**Warunki Coffmana (wszystkie muszą być spełnione):**
|
||||
1. **Mutual exclusion** - zasób może mieć tylko jeden właściciel
|
||||
2. **Hold and wait** - trzymaj i czekaj na więcej
|
||||
3. **No preemption** - nie można odebrać zasobu
|
||||
4. **Circular wait** - cykliczne oczekiwanie
|
||||
|
||||
#### 3. Głodzenie (Starvation)
|
||||
|
||||
Proces nigdy nie dostaje zasobu, bo inni mają wyższy priorytet.
|
||||
|
||||
#### 4. Inwersja priorytetów (Priority Inversion)
|
||||
|
||||
Proces o niskim priorytecie blokuje proces o wysokim priorytecie (przez mutex).
|
||||
|
||||
---
|
||||
|
||||
### Mechanizmy synchronizacji
|
||||
|
||||
#### Mutex (Mutual Exclusion)
|
||||
|
||||
```c
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
// Sekcja krytyczna
|
||||
counter++;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
```
|
||||
|
||||
#### Semafor (Semaphore)
|
||||
|
||||
```c
|
||||
sem_t sem;
|
||||
sem_init(&sem, 0, 3); // Wartość początkowa 3
|
||||
|
||||
sem_wait(&sem); // P() - dekrementuj, blokuj jeśli 0
|
||||
// Sekcja krytyczna
|
||||
sem_post(&sem); // V() - inkrementuj
|
||||
```
|
||||
|
||||
**Typy:**
|
||||
- **Binarny** (0/1) - jak mutex
|
||||
- **Licznikowy** - ogranicza liczbę wątków (np. pula połączeń)
|
||||
|
||||
#### Zmienna warunkowa (Condition Variable)
|
||||
|
||||
```c
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
|
||||
// Producent
|
||||
pthread_mutex_lock(&mutex);
|
||||
buffer[in] = item;
|
||||
pthread_cond_signal(&cond); // Obudź czekającego
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
// Konsument
|
||||
pthread_mutex_lock(&mutex);
|
||||
while (buffer_empty) {
|
||||
pthread_cond_wait(&cond, &mutex); // Zwalnia mutex i czeka
|
||||
}
|
||||
item = buffer[out];
|
||||
pthread_mutex_unlock(&mutex);
|
||||
```
|
||||
|
||||
#### Bariera (Barrier)
|
||||
|
||||
```c
|
||||
pthread_barrier_t barrier;
|
||||
pthread_barrier_init(&barrier, NULL, NUM_THREADS);
|
||||
|
||||
// W każdym wątku:
|
||||
// ... obliczenia ...
|
||||
pthread_barrier_wait(&barrier); // Czekaj na wszystkich
|
||||
// ... dalsze obliczenia ...
|
||||
```
|
||||
|
||||
#### Read-Write Lock
|
||||
|
||||
```c
|
||||
pthread_rwlock_t rwlock;
|
||||
|
||||
// Czytelnik
|
||||
pthread_rwlock_rdlock(&rwlock); // Wielu może czytać
|
||||
// ... czytanie ...
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
|
||||
// Pisarz
|
||||
pthread_rwlock_wrlock(&rwlock); // Wyłączny dostęp
|
||||
// ... pisanie ...
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Porównanie mechanizmów synchronizacji
|
||||
|
||||
| Mechanizm | Blokujący | Użycie | Koszt |
|
||||
|-----------|-----------|--------|-------|
|
||||
| **Mutex** | Tak | Sekcja krytyczna | Niski |
|
||||
| **Spinlock** | Tak (aktywne) | Krótkie sekcje, SMP | Bardzo niski* |
|
||||
| **Semafor** | Tak | Ograniczanie zasobów | Niski |
|
||||
| **Cond. var.** | Tak | Oczekiwanie na warunek | Niski |
|
||||
| **Bariera** | Tak | Synchronizacja fazowa | Średni |
|
||||
| **RW Lock** | Tak | Wielu czytelników | Średni |
|
||||
| **Atomics** | Nie | Proste operacje | Najniższy |
|
||||
|
||||
*jeśli sekcja krytyczna krótka
|
||||
|
||||
---
|
||||
|
||||
## 7. Zastosowania
|
||||
|
||||
### Kiedy procesy?
|
||||
|
||||
- **Izolacja** - awaria jednego nie wpływa na inne
|
||||
- **Bezpieczeństwo** - różne uprawnienia
|
||||
- **Różne języki/technologie** - mikrousługi
|
||||
- **Niezawodność** - restart bez wpływu na system
|
||||
|
||||
**Przykłady:** Serwery WWW (fork), przeglądarki (proces per tab), bazy danych
|
||||
|
||||
### Kiedy wątki?
|
||||
|
||||
- **Współdzielenie danych** - bez kopiowania
|
||||
- **Responsywność** - UI thread + worker threads
|
||||
- **Równoległość CPU** - obliczenia na wielu rdzeniach
|
||||
- **I/O asynchroniczne** - czekanie nie blokuje wszystkiego
|
||||
|
||||
**Przykłady:** Gry, serwery aplikacji, przetwarzanie obrazu/wideo
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "PEST" dla różnic Proces-wątek:
|
||||
- **P**amięć - proces ma własną, wątek współdzieli
|
||||
- **E**fektywność - wątek szybszy
|
||||
- **S**ynchronizacja - wątki wymagają więcej
|
||||
- **T**worzenie - proces wolniejsze
|
||||
|
||||
### "SPIN WAIT SLEEP" dla oczekiwania:
|
||||
- **Spinlock** - aktywne czekanie (pętla)
|
||||
- **Mutex** - uśpienie, wybudzenie przez scheduler
|
||||
|
||||
### "COFFMAN" dla warunków deadlocka:
|
||||
- **C**ircular wait - cykliczne oczekiwanie
|
||||
- **O**nly one - mutual exclusion
|
||||
- **F**orever hold - hold and wait
|
||||
- **F**orced release - no preemption (brak)
|
||||
|
||||
### "PV" dla semafora:
|
||||
- **P** = Proberen (testuj) = wait = down = dekrementuj
|
||||
- **V** = Verhogen (zwiększ) = signal = up = inkrementuj
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Jak unikać deadlocka?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
1. **Zapobieganie** - złam jeden z warunków Coffmana:
|
||||
- Zamawianie zasobów (zawsze lock A przed B)
|
||||
- Żądaj wszystkich zasobów naraz
|
||||
- Timeout na blokady
|
||||
|
||||
2. **Unikanie** - algorytm bankiera (sprawdź czy bezpieczne)
|
||||
|
||||
3. **Wykrywanie i naprawianie** - graf oczekiwania, zabij proces
|
||||
|
||||
```c
|
||||
// Zapobieganie przez porządek
|
||||
// Zawsze: mutex1 przed mutex2
|
||||
pthread_mutex_lock(&mutex1);
|
||||
pthread_mutex_lock(&mutex2);
|
||||
// ...
|
||||
pthread_mutex_unlock(&mutex2);
|
||||
pthread_mutex_unlock(&mutex1);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Czym różni się fork() od pthread_create()?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| fork() | pthread_create() |
|
||||
|--------|------------------|
|
||||
| Tworzy nowy proces | Tworzy nowy wątek |
|
||||
| Kopiuje przestrzeń adresową (COW) | Współdzieli przestrzeń |
|
||||
| Nowy PID | Ten sam PID, nowy TID |
|
||||
| Komunikacja przez IPC | Komunikacja przez pamięć |
|
||||
| Wolne (~ms) | Szybkie (~μs) |
|
||||
|
||||
```c
|
||||
// fork()
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
// Proces potomny
|
||||
} else {
|
||||
// Proces rodzic
|
||||
}
|
||||
|
||||
// pthread_create()
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, thread_function, arg);
|
||||
pthread_join(thread, NULL);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Co to jest Copy-on-Write (COW)?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**COW** = optymalizacja fork() - strony pamięci są współdzielone dopóki nie zostaną zmodyfikowane.
|
||||
|
||||
```
|
||||
Przed fork():
|
||||
Proces A: [strona 1] [strona 2] [strona 3]
|
||||
|
||||
Po fork() (bez COW):
|
||||
Proces A: [strona 1] [strona 2] [strona 3] ← kopia
|
||||
Proces B: [strona 1] [strona 2] [strona 3] ← kopia
|
||||
(kopiowanie całej pamięci - WOLNE!)
|
||||
|
||||
Po fork() (z COW):
|
||||
Proces A: [strona 1 (shared, RO)]
|
||||
↑
|
||||
Proces B: [strona 1 (shared, RO)]
|
||||
(współdzielenie - SZYBKIE!)
|
||||
|
||||
Po modyfikacji przez A:
|
||||
Proces A: [strona 1 (kopia, RW)] ← kopia dopiero teraz!
|
||||
Proces B: [strona 1 (shared, RO)]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Wyjaśnij problem producent-konsument"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Problem:** Producent wytwarza dane, konsument je pobiera. Bufor ograniczony.
|
||||
|
||||
```c
|
||||
#define BUFFER_SIZE 10
|
||||
int buffer[BUFFER_SIZE];
|
||||
int count = 0;
|
||||
|
||||
sem_t empty, full;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
// Inicjalizacja
|
||||
sem_init(&empty, 0, BUFFER_SIZE); // Wolne miejsca
|
||||
sem_init(&full, 0, 0); // Zajęte miejsca
|
||||
|
||||
void* producer(void* arg) {
|
||||
while (1) {
|
||||
int item = produce();
|
||||
|
||||
sem_wait(&empty); // Czekaj na wolne miejsce
|
||||
pthread_mutex_lock(&mutex);
|
||||
buffer[in] = item;
|
||||
in = (in + 1) % BUFFER_SIZE;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
sem_post(&full); // Sygnalizuj dane
|
||||
}
|
||||
}
|
||||
|
||||
void* consumer(void* arg) {
|
||||
while (1) {
|
||||
sem_wait(&full); // Czekaj na dane
|
||||
pthread_mutex_lock(&mutex);
|
||||
int item = buffer[out];
|
||||
out = (out + 1) % BUFFER_SIZE;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
sem_post(&empty); // Sygnalizuj wolne miejsce
|
||||
|
||||
consume(item);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co to są coroutines/goroutines?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Coroutines** = współprogramy - lekkie "wątki" zarządzane w przestrzeni użytkownika.
|
||||
|
||||
| Cecha | Wątki | Coroutines |
|
||||
|-------|-------|------------|
|
||||
| Scheduling | Preemptive (OS) | Cooperative (yield) |
|
||||
| Stos | ~1-8 MB | ~2-8 KB |
|
||||
| Tworzenie | ~10-100 μs | ~100 ns |
|
||||
| Liczba | Setki-tysiące | Miliony |
|
||||
|
||||
**Goroutines (Go):**
|
||||
```go
|
||||
go func() {
|
||||
fmt.Println("Hello from goroutine")
|
||||
}()
|
||||
```
|
||||
|
||||
**Async/await (Python, C#, JavaScript):**
|
||||
```python
|
||||
async def fetch_data():
|
||||
data = await http_client.get(url)
|
||||
return data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Jak działa scheduler wątków?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Algorytmy schedulingu:**
|
||||
|
||||
| Algorytm | Opis | Użycie |
|
||||
|----------|------|--------|
|
||||
| **FIFO** | Pierwszy przyszedł, pierwszy obsłużony | Prosty, batch |
|
||||
| **Round Robin** | Kwant czasu, rotacja | Interaktywne |
|
||||
| **Priority** | Wyższy priorytet pierwszy | Real-time |
|
||||
| **CFS** | Completely Fair Scheduler | Linux |
|
||||
| **Multi-level Feedback** | Priorytety + promocja/degradacja | Windows |
|
||||
|
||||
**CFS (Linux):**
|
||||
- Wirtualny czas wykonania (vruntime)
|
||||
- Czerwono-czarne drzewo
|
||||
- Sprawiedliwy podział CPU
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **Proces** = izolacja, własna pamięć, wolne tworzenie
|
||||
2. **Wątek** = współdzielenie, szybkie, wymaga synchronizacji
|
||||
3. **IPC:** Pipes, shared memory, sockets, message queues
|
||||
4. **Synchronizacja:** Mutex, semafor, cond var, bariera
|
||||
5. **Deadlock:** 4 warunki Coffmana, zapobiegaj przez porządek
|
||||
6. **Race condition:** Atomowe operacje lub blokady
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Silberschatz, Galvin - "Operating System Concepts"
|
||||
2. Tanenbaum - "Modern Operating Systems"
|
||||
3. Love, R. - "Linux Kernel Development"
|
||||
4. Butenhof - "Programming with POSIX Threads"
|
||||
@ -1,600 +0,0 @@
|
||||
# Pytanie 10: Zarządzanie pamięcią - stronicowanie i segmentacja
|
||||
|
||||
## Pytanie
|
||||
**"Scharakteryzować problemy i mechanizmy zarządzania pamięcią. Porównać cechy i przeznaczenie mechanizmów stronicowania i segmentacji."**
|
||||
|
||||
Przedmiot: SOI (Systemy Operacyjne)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
**Zarządzanie pamięcią** to jeden z kluczowych zadań systemu operacyjnego:
|
||||
- Przydzielanie pamięci procesom
|
||||
- Ochrona pamięci między procesami
|
||||
- Efektywne wykorzystanie ograniczonego zasobu
|
||||
- Abstrakcja (programista nie musi znać fizycznych adresów)
|
||||
|
||||
---
|
||||
|
||||
## 1. Problemy zarządzania pamięcią
|
||||
|
||||
### 1.1 Fragmentacja
|
||||
|
||||
#### Fragmentacja zewnętrzna (External Fragmentation)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Pamięć fizyczna: │
|
||||
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
|
||||
│ │PROC│ │FREE│ │PROC│ │FREE│ │PROC│ │FREE│ │PROC│ │
|
||||
│ │ A │ │ 2K │ │ B │ │ 3K │ │ C │ │ 1K │ │ D │ │
|
||||
│ └────┘ └────┘ └────┘ └────┘ └────┘ └────┘ └────┘ │
|
||||
│ │
|
||||
│ Suma wolnej pamięci: 6K │
|
||||
│ Ale nie można przydzielić bloku 5K! (fragmentacja) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Problem:** Wolna pamięć jest rozproszona w małych, nieciągłych blokach.
|
||||
|
||||
#### Fragmentacja wewnętrzna (Internal Fragmentation)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Przydzielono blok 4KB, proces potrzebuje 3.5KB: │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ │ WYKORZYSTANE (3.5KB) │ ZMARNOWANE (0.5KB) │ │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ ↑ │
|
||||
│ Fragmentacja wewnętrzna │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Problem:** Przydzielony blok jest większy niż potrzeba.
|
||||
|
||||
### 1.2 Ochrona pamięci
|
||||
|
||||
- Proces A nie może czytać/pisać pamięci procesu B
|
||||
- Jądro chronione przed aplikacjami użytkownika
|
||||
- Mechanizmy: rejestry bazowy/graniczny, bity ochrony, ringi
|
||||
|
||||
### 1.3 Relokacja
|
||||
|
||||
**Problem:** Program kompilowany z założeniem konkretnych adresów musi działać pod różnymi adresami.
|
||||
|
||||
**Rozwiązania:**
|
||||
- Relokacja statyczna (loader)
|
||||
- Relokacja dynamiczna (MMU - Memory Management Unit)
|
||||
|
||||
### 1.4 Współdzielenie
|
||||
|
||||
- Biblioteki współdzielone (DLL, .so)
|
||||
- Pamięć współdzielona między procesami
|
||||
- Copy-on-Write (COW)
|
||||
|
||||
### 1.5 Ograniczona pamięć fizyczna
|
||||
|
||||
- Więcej procesów niż RAM
|
||||
- Rozwiązanie: pamięć wirtualna + swap
|
||||
|
||||
---
|
||||
|
||||
## 2. Mechanizmy zarządzania pamięcią
|
||||
|
||||
### 2.1 Partycjonowanie stałe (Fixed Partitioning)
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ Pamięć podzielona na stałe partycje: │
|
||||
│ ┌──────────┬──────────┬──────────┬──────────┐ │
|
||||
│ │ Partycja │ Partycja │ Partycja │ Partycja │ │
|
||||
│ │ 1MB │ 2MB │ 4MB │ 8MB │ │
|
||||
│ └──────────┴──────────┴──────────┴──────────┘ │
|
||||
│ │
|
||||
│ Zalety: Proste, brak fragmentacji zewnętrznej │
|
||||
│ Wady: Fragmentacja wewnętrzna, maks. rozmiar procesu ograniczony│
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 Partycjonowanie dynamiczne (Dynamic Partitioning)
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ Partycje tworzone według potrzeb: │
|
||||
│ ┌─────┬───────────┬────────┬─────────────────────────────┐ │
|
||||
│ │ P1 │ P2 │ P3 │ WOLNA │ │
|
||||
│ │ 3MB │ 5MB │ 2MB │ 10MB │ │
|
||||
│ └─────┴───────────┴────────┴─────────────────────────────┘ │
|
||||
│ │
|
||||
│ Zalety: Brak fragmentacji wewnętrznej, elastyczność │
|
||||
│ Wady: Fragmentacja zewnętrzna! │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Algorytmy przydziału:**
|
||||
|
||||
| Algorytm | Opis | Zalety | Wady |
|
||||
|----------|------|--------|------|
|
||||
| **First Fit** | Pierwszy wystarczający blok | Szybki | Fragmentacja na początku |
|
||||
| **Best Fit** | Najmniejszy wystarczający | Oszczędza duże bloki | Wiele małych fragmentów |
|
||||
| **Worst Fit** | Największy blok | Pozostawia użyteczne resztki | Niszczy duże bloki |
|
||||
| **Next Fit** | First Fit od ostatniego miejsca | Rozproszenie | Fragmentacja |
|
||||
|
||||
---
|
||||
|
||||
## 3. Stronicowanie (Paging)
|
||||
|
||||
### Idea
|
||||
|
||||
Dzielimy pamięć na **równe bloki** (strony/ramki):
|
||||
- **Strona (Page)** - blok pamięci wirtualnej (4KB typowo)
|
||||
- **Ramka (Frame)** - blok pamięci fizycznej (ten sam rozmiar)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PAMIĘĆ WIRTUALNA PAMIĘĆ FIZYCZNA │
|
||||
│ (przestrzeń adresowa) (RAM) │
|
||||
│ │
|
||||
│ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ Strona 0│─────────────────────────│ Ramka 5 │ │
|
||||
│ ├─────────┤ ├─────────┤ │
|
||||
│ │ Strona 1│──────────┐ │ Ramka 1 │ │
|
||||
│ ├─────────┤ │ ├─────────┤ │
|
||||
│ │ Strona 2│────┐ │ │ Ramka 2 │←──────────┐ │
|
||||
│ ├─────────┤ │ │ ├─────────┤ │ │
|
||||
│ │ Strona 3│ │ └─────────────→│ Ramka 3 │ │ │
|
||||
│ └─────────┘ │ ├─────────┤ │ │
|
||||
│ │ │ Ramka 4 │ │ │
|
||||
│ │ ├─────────┤ │ │
|
||||
│ └───────────────────→│ Ramka 7 │ │ │
|
||||
│ └─────────┘ │ │
|
||||
│ │ │
|
||||
│ TABLICA STRON (Page Table) Strona 2 → Ramka 7────┘ │
|
||||
│ ┌──────────────────────┐ │
|
||||
│ │ Strona │ Ramka │Flagi│ │
|
||||
│ │ 0 │ 5 │ RW │ │
|
||||
│ │ 1 │ 3 │ R │ │
|
||||
│ │ 2 │ 7 │ RW │ │
|
||||
│ │ 3 │ - │ INV │ ← Strona nie w pamięci (page fault) │
|
||||
│ └──────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Translacja adresu
|
||||
|
||||
```
|
||||
Adres wirtualny (32-bit, strony 4KB):
|
||||
┌────────────────────────┬──────────────┐
|
||||
│ Numer strony (20b) │ Offset (12b) │
|
||||
└────────────────────────┴──────────────┘
|
||||
│ │
|
||||
↓ │
|
||||
Tablica stron │
|
||||
│ │
|
||||
↓ │
|
||||
┌────────────────────────┬──────────────┐
|
||||
│ Numer ramki (20b) │ Offset (12b) │
|
||||
└────────────────────────┴──────────────┘
|
||||
Adres fizyczny
|
||||
```
|
||||
|
||||
### Wielopoziomowe tablice stron
|
||||
|
||||
**Problem:** Tablica stron dla 32-bit przestrzeni z 4KB stronami = 2²⁰ wpisów × 4B = **4MB per proces!**
|
||||
|
||||
**Rozwiązanie:** Hierarchiczna tablica stron
|
||||
|
||||
```
|
||||
Adres wirtualny (32-bit, 2 poziomy):
|
||||
┌────────────┬────────────┬──────────────┐
|
||||
│ Katalog(10)│ Tabela(10) │ Offset (12) │
|
||||
└────────────┴────────────┴──────────────┘
|
||||
│ │ │
|
||||
↓ ↓ │
|
||||
┌──────────┐ ┌──────────┐ │
|
||||
│ Page │ │ Page │ │
|
||||
│Directory │→ │ Table │→ Ramka + Offset
|
||||
└──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
**64-bit (x86-64):** 4 poziomy (PML4 → PDPT → PD → PT)
|
||||
|
||||
### TLB (Translation Lookaside Buffer)
|
||||
|
||||
**Problem:** Każdy dostęp do pamięci wymaga 2+ odczytów (tablica + dane).
|
||||
|
||||
**Rozwiązanie:** Cache translacji adresów
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ TLB │
|
||||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||
│ │ Strona wirtualna │ Ramka fizyczna │ Flagi │ ASID │ │
|
||||
│ │ 0x12345 │ 0x789AB │ RW │ 42 │ │
|
||||
│ │ 0x12346 │ 0x789AC │ R │ 42 │ │
|
||||
│ │ ... │ ... │ ... │ ... │ │
|
||||
│ └───────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ TLB hit: ~1 cykl │
|
||||
│ TLB miss: ~100+ cykli (page walk) │
|
||||
│ Hit rate: >99% typowo │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Zalety i wady stronicowania
|
||||
|
||||
| Zalety | Wady |
|
||||
|--------|------|
|
||||
| Brak fragmentacji zewnętrznej | Fragmentacja wewnętrzna (ostatnia strona) |
|
||||
| Prosta alokacja (bitmapa ramek) | Narzut tablicy stron |
|
||||
| Łatwe współdzielenie (COW) | TLB miss kosztowny |
|
||||
| Pamięć wirtualna naturalna | Nie odpowiada strukturze programu |
|
||||
|
||||
---
|
||||
|
||||
## 4. Segmentacja (Segmentation)
|
||||
|
||||
### Idea
|
||||
|
||||
Dzielimy pamięć na **logiczne segmenty** odpowiadające strukturze programu:
|
||||
- Segment kodu
|
||||
- Segment danych
|
||||
- Segment stosu
|
||||
- Segment bibliotek
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PRZESTRZEŃ LOGICZNA PAMIĘĆ FIZYCZNA │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ Segment 0 │ │ │ │
|
||||
│ │ (Kod) │─────────────────│→ 0x1000 - 0x3FFF │ │
|
||||
│ │ Rozmiar: 12KB │ │ │ │
|
||||
│ └─────────────────┘ ├─────────────────────┤ │
|
||||
│ ┌─────────────────┐ │ │ │
|
||||
│ │ Segment 1 │─────────────────│→ 0x8000 - 0xBFFF │ │
|
||||
│ │ (Dane) │ │ │ │
|
||||
│ │ Rozmiar: 16KB │ ├─────────────────────┤ │
|
||||
│ └─────────────────┘ │ │ │
|
||||
│ ┌─────────────────┐ │ │ │
|
||||
│ │ Segment 2 │─────────────────│→ 0xF000 - 0xF7FF │ │
|
||||
│ │ (Stos) │ │ │ │
|
||||
│ │ Rozmiar: 2KB │ └─────────────────────┘ │
|
||||
│ └─────────────────┘ │
|
||||
│ │
|
||||
│ TABLICA SEGMENTÓW │
|
||||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||
│ │ Segment │ Baza │ Limit │ Prawa │ │ │
|
||||
│ │ 0 │ 0x1000 │ 12KB │ RX │ (kod - execute) │ │
|
||||
│ │ 1 │ 0x8000 │ 16KB │ RW │ (dane - read/write) │ │
|
||||
│ │ 2 │ 0xF000 │ 2KB │ RW │ (stos) │ │
|
||||
│ └───────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Translacja adresu
|
||||
|
||||
```
|
||||
Adres logiczny:
|
||||
┌────────────────────┬──────────────────────┐
|
||||
│ Numer segmentu (s) │ Offset (d) │
|
||||
└────────────────────┴──────────────────────┘
|
||||
│ │
|
||||
↓ │
|
||||
Tablica segmentów │
|
||||
┌──────┬───────┐ │
|
||||
│ Baza │ Limit │ │
|
||||
└──────┴───────┘ │
|
||||
│ │ │
|
||||
│ Sprawdź: d < Limit?
|
||||
│ │ │
|
||||
↓ ↓ │
|
||||
Adres fizyczny = Baza + Offset
|
||||
```
|
||||
|
||||
### Ochrona w segmentacji
|
||||
|
||||
Każdy segment ma **prawa dostępu:**
|
||||
- **R** (Read) - odczyt dozwolony
|
||||
- **W** (Write) - zapis dozwolony
|
||||
- **X** (Execute) - wykonanie dozwolone
|
||||
|
||||
```
|
||||
Segment kodu: RX (wykonaj, nie modyfikuj)
|
||||
Segment danych: RW (czytaj/pisz, nie wykonuj)
|
||||
Segment stosu: RW (bez wykonywania - ochrona przed exploitami)
|
||||
```
|
||||
|
||||
### Zalety i wady segmentacji
|
||||
|
||||
| Zalety | Wady |
|
||||
|--------|------|
|
||||
| Odpowiada strukturze programu | Fragmentacja zewnętrzna |
|
||||
| Naturalna ochrona (per segment) | Segmenty o zmiennej wielkości |
|
||||
| Łatwe współdzielenie (cały segment) | Kompaktowanie potrzebne |
|
||||
| Dynamiczny wzrost segmentów | Skomplikowana alokacja |
|
||||
|
||||
---
|
||||
|
||||
## 5. Porównanie: Stronicowanie vs Segmentacja
|
||||
|
||||
| Cecha | Stronicowanie | Segmentacja |
|
||||
|-------|---------------|-------------|
|
||||
| **Jednostka** | Strona (stały rozmiar) | Segment (zmienny rozmiar) |
|
||||
| **Widoczność dla programisty** | Niewidoczna | Widoczna (logiczne jednostki) |
|
||||
| **Fragmentacja zewnętrzna** | ❌ Brak | ✅ Występuje |
|
||||
| **Fragmentacja wewnętrzna** | ✅ Występuje | ❌ Brak |
|
||||
| **Tablica** | Tablica stron (duża) | Tablica segmentów (mała) |
|
||||
| **Ochrona** | Per strona (mniej naturalna) | Per segment (naturalna) |
|
||||
| **Współdzielenie** | Per strona | Per segment (całe moduły) |
|
||||
| **Pamięć wirtualna** | Łatwa (strony na dysk) | Trudniejsza |
|
||||
|
||||
---
|
||||
|
||||
## 6. Segmentacja ze stronicowaniem (Hybrid)
|
||||
|
||||
### Intel x86 (tryb chroniony)
|
||||
|
||||
Kombinacja obu mechanizmów:
|
||||
|
||||
```
|
||||
Adres logiczny (Selector:Offset)
|
||||
│
|
||||
↓
|
||||
SEGMENTACJA
|
||||
(Segment → Adres liniowy)
|
||||
│
|
||||
↓
|
||||
Adres liniowy
|
||||
│
|
||||
↓
|
||||
STRONICOWANIE
|
||||
(Strona → Ramka)
|
||||
│
|
||||
↓
|
||||
Adres fizyczny
|
||||
```
|
||||
|
||||
**Praktyka:** Współczesne OS (Linux, Windows) używają **flat memory model** - wszystkie segmenty pokrywają całą przestrzeń adresową, efektywnie wyłączając segmentację.
|
||||
|
||||
### Zalety hybrydowego podejścia
|
||||
|
||||
1. **Ochrona** z segmentacji (kod vs dane vs stos)
|
||||
2. **Brak fragmentacji zewnętrznej** ze stronicowania
|
||||
3. **Pamięć wirtualna** ze stronicowania
|
||||
|
||||
---
|
||||
|
||||
## 7. Pamięć wirtualna (Virtual Memory)
|
||||
|
||||
### Idea
|
||||
|
||||
Nie wszystkie strony muszą być w RAM - część może być na dysku (swap).
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ PAMIĘĆ WIRTUALNA RAM DYSK (Swap) │
|
||||
│ ┌─────────────┐ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ Strona 0 │ ────→│ Ramka 2 │ │ │ │
|
||||
│ │ Strona 1 │ │ │ │ Strona 3 │ │
|
||||
│ │ Strona 2 │ ────→│ Ramka 5 │ │ Strona 5 │ │
|
||||
│ │ Strona 3 │ ─────────────────────→ │ │ │
|
||||
│ │ Strona 4 │ ────→│ Ramka 1 │ │ │ │
|
||||
│ │ Strona 5 │ ─────────────────────→ │ │ │
|
||||
│ └─────────────┘ └──────────┘ └──────────────┘ │
|
||||
│ │
|
||||
│ Page fault: Strona 3 → załaduj z dysku do RAM │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Algorytmy zastępowania stron
|
||||
|
||||
| Algorytm | Opis | Właściwości |
|
||||
|----------|------|-------------|
|
||||
| **FIFO** | Najstarsza strona | Prosty, anomalia Bélády'ego |
|
||||
| **LRU** | Najdawniej używana | Optymalny offline, kosztowny |
|
||||
| **LRU Approximation** | Clock, Second Chance | Praktyczny kompromis |
|
||||
| **LFU** | Najrzadziej używana | Dobre dla hot data |
|
||||
| **OPT** | Najdalej używana | Teoretycznie optymalny, niemożliwy |
|
||||
|
||||
### Algorytm Clock (Second Chance)
|
||||
|
||||
```
|
||||
┌───┐
|
||||
┌──→│ 1 │──┐ Bit referencji:
|
||||
│ └───┘ │ 1 = używana ostatnio
|
||||
│ ↓ 0 = kandydat do usunięcia
|
||||
┌───┐ ┌───┐
|
||||
│ 0 │ │ 1 │ Wskazówka zegara:
|
||||
└───┘ └───┘ - Jeśli bit=1: zeruj, idź dalej
|
||||
↑ │ - Jeśli bit=0: zastąp tę stronę
|
||||
│ ┌───┐ │
|
||||
└───│ 0 │←─┘
|
||||
└───┘
|
||||
↑
|
||||
wskazówka
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "STRONY RÓWNE, SEGMENTY LOGICZNE":
|
||||
- **Strony** = wszystkie takie same (4KB)
|
||||
- **Segmenty** = różne rozmiary, logiczny podział
|
||||
|
||||
### "PAGE = Physical Allocation Generates Equality":
|
||||
- Fizyczne ramki równej wielkości
|
||||
- Brak fragmentacji zewnętrznej
|
||||
|
||||
### "SEGMENT = Software Entity with Guarded Memory, ENforcing Type safety":
|
||||
- Logiczne jednostki programu
|
||||
- Ochrona per segment
|
||||
|
||||
### "TLB = Translation Lightning-fast Buffer":
|
||||
- Cache dla translacji adresów
|
||||
- Hit = 1 cykl, Miss = 100+ cykli
|
||||
|
||||
### "LRU = Last Recently Used → pierwszy do usunięcia":
|
||||
- Najdawniej używana = najlepsza do wyrzucenia
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Co to jest Page Fault i jak jest obsługiwany?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Page Fault** = wyjątek gdy strona nie jest w RAM (bit valid=0 w tablicy stron).
|
||||
|
||||
```
|
||||
1. Proces odwołuje się do adresu w stronie 5
|
||||
2. MMU sprawdza tablicę stron: strona 5 invalid
|
||||
3. Page Fault exception
|
||||
4. OS:
|
||||
a) Znajdź stronę na dysku (swap)
|
||||
b) Znajdź wolną ramkę (lub zwolnij przez algorytm zastępowania)
|
||||
c) Załaduj stronę z dysku do RAM
|
||||
d) Zaktualizuj tablicę stron (valid=1, ramka=X)
|
||||
e) Wznów instrukcję
|
||||
5. Proces kontynuuje (nie wie, że był page fault)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Wyjaśnij anomalię Bélády'ego"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Anomalia Bélády'ego** = więcej ramek → więcej page faults (dla FIFO)!
|
||||
|
||||
```
|
||||
Sekwencja odwołań: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
|
||||
|
||||
3 ramki (FIFO): 9 page faults
|
||||
4 ramki (FIFO): 10 page faults (!!)
|
||||
|
||||
Wniosek: FIFO nie jest "stack algorithm" - nie ma tej właściwości:
|
||||
"Strony w pamięci z N ramkami ⊆ strony z N+1 ramkami"
|
||||
|
||||
LRU nie ma tej anomalii (jest stack algorithm).
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Co to jest thrashing?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Thrashing** = system spędza więcej czasu na page faults niż na wykonywaniu kodu.
|
||||
|
||||
```
|
||||
Przyczyna: Zbyt mało RAM dla working set procesów
|
||||
|
||||
Working set = zbiór stron aktywnie używanych przez proces
|
||||
|
||||
Symptomy:
|
||||
- CPU utilization spada
|
||||
- Dysk ciągle pracuje (swap in/out)
|
||||
- System "zamiera"
|
||||
|
||||
Rozwiązania:
|
||||
- Zwiększ RAM
|
||||
- Zmniejsz multiprogramming
|
||||
- Working set model (przydziel RAM proporcjonalnie)
|
||||
- Swap na SSD
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Jak działa Copy-on-Write?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**COW** = odroczenie kopiowania do momentu modyfikacji.
|
||||
|
||||
```
|
||||
fork() bez COW:
|
||||
Rodzic: [Strona A] [Strona B] [Strona C]
|
||||
↓ kopiowanie
|
||||
Dziecko: [Strona A'] [Strona B'] [Strona C']
|
||||
→ Kosztowne!
|
||||
|
||||
fork() z COW:
|
||||
Rodzic: [Strona A (RO)] [Strona B (RO)] [Strona C (RO)]
|
||||
↓ shared ↓ shared ↓ shared
|
||||
Dziecko: [Strona A (RO)] [Strona B (RO)] [Strona C (RO)]
|
||||
→ Szybkie! (tylko tablice stron)
|
||||
|
||||
Dziecko pisze do Strony B:
|
||||
1. Page fault (strona RO)
|
||||
2. OS kopiuje Stronę B → B'
|
||||
3. Dziecko dostaje B' (RW), rodzic zachowuje B (RW)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Jaki jest typowy rozmiar strony i dlaczego?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Rozmiar | Zalety | Wady |
|
||||
|---------|--------|------|
|
||||
| **Mały (1KB)** | Mała fragmentacja wewnętrzna | Duża tablica stron |
|
||||
| **Duży (64KB)** | Mała tablica stron | Duża fragmentacja wewnętrzna |
|
||||
| **4KB (typowy)** | Kompromis | Kompromis |
|
||||
|
||||
**Dlaczego 4KB?**
|
||||
- Rozmiar bloku dysku (sektor 512B × 8 lub 4K native)
|
||||
- Rozsądna fragmentacja (~2KB średnio)
|
||||
- Rozsądna tablica stron
|
||||
- Historyczne (VAX, Unix)
|
||||
|
||||
**Huge Pages (2MB, 1GB):**
|
||||
- Dla dużych aplikacji (bazy danych)
|
||||
- Mniej wpisów TLB
|
||||
- Mniej page faults
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Jak segmentacja jest używana w x86-64?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**x86-64 praktycznie nie używa segmentacji:**
|
||||
|
||||
```
|
||||
CS, DS, ES, SS → Baza = 0, Limit = maksymalny
|
||||
→ Efektywnie "flat model"
|
||||
|
||||
Wyjątki:
|
||||
- FS, GS → używane dla Thread Local Storage (TLS)
|
||||
- CS → poziom uprzywilejowania (ring 0/3)
|
||||
```
|
||||
|
||||
**Powód:** Segmentacja komplikuje pamięć wirtualną i nie jest potrzebna z ochroną per-strona (NX bit, SMEP, SMAP).
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **Stronicowanie** = równe strony/ramki, brak fragmentacji zewnętrznej
|
||||
2. **Segmentacja** = logiczne jednostki, fragmentacja zewnętrzna
|
||||
3. **Współczesne OS** = stronicowanie (segmentacja wyłączona)
|
||||
4. **TLB** = cache translacji, kluczowy dla wydajności
|
||||
5. **Page fault** = strona nie w RAM, załaduj z dysku
|
||||
6. **Thrashing** = za mało RAM, ciągłe page faults
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. Silberschatz, Galvin - "Operating System Concepts"
|
||||
2. Tanenbaum - "Modern Operating Systems"
|
||||
3. Intel Manual Vol. 3 - System Programming Guide
|
||||
4. Linux kernel documentation - Memory Management
|
||||
@ -1,575 +0,0 @@
|
||||
# Pytanie 11: Standardy i narzędzia do modelowania procesów biznesowych
|
||||
|
||||
## Pytanie
|
||||
**"Scharakteryzować standardy i narzędzia do modelowania procesów biznesowych."**
|
||||
|
||||
Przedmiot: WSYZ (Wstęp do Systemów Zarządzania)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
**Modelowanie procesów biznesowych** to graficzne przedstawienie przepływu pracy, działań i decyzji w organizacji. Służy do:
|
||||
- Dokumentowania procesów
|
||||
- Analizy i optymalizacji
|
||||
- Automatyzacji (workflow, BPM)
|
||||
- Komunikacji między działami
|
||||
|
||||
---
|
||||
|
||||
## 1. Główne standardy modelowania
|
||||
|
||||
### Przegląd standardów
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ STANDARDY MODELOWANIA PROCESÓW │
|
||||
├─────────────────┬─────────────────┬─────────────────────────────┤
|
||||
│ BPMN │ UML │ EPC │
|
||||
│ Business │ Activity │ Event-driven │
|
||||
│ Process Model │ Diagrams │ Process Chain │
|
||||
│ and Notation │ │ │
|
||||
├─────────────────┼─────────────────┼─────────────────────────────┤
|
||||
│ IDEF0 │ Flowcharts │ Value Stream Map │
|
||||
│ Function │ (Schematy │ (Lean Manufacturing) │
|
||||
│ Modeling │ blokowe) │ │
|
||||
└─────────────────┴─────────────────┴─────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. BPMN (Business Process Model and Notation)
|
||||
|
||||
### Charakterystyka
|
||||
|
||||
- **Standard:** OMG (Object Management Group)
|
||||
- **Wersja aktualna:** BPMN 2.0 (2011)
|
||||
- **Cel:** Uniwersalny język dla analityków, architektów i programistów
|
||||
- **Format:** Graficzny + XML (dla automatyzacji)
|
||||
|
||||
### Podstawowe elementy BPMN
|
||||
|
||||
#### Flow Objects (Obiekty przepływu)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZDARZENIA (Events) │
|
||||
│ │
|
||||
│ ○ Zdarzenie startowe (Start Event) │
|
||||
│ │
|
||||
│ ◎ Zdarzenie pośrednie (Intermediate Event) │
|
||||
│ │
|
||||
│ ◉ Zdarzenie końcowe (End Event) │
|
||||
│ │
|
||||
│ Modyfikatory: Timer ⏱, Message ✉, Error ⚡, Signal 📶 │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ CZYNNOŚCI (Activities) │
|
||||
│ │
|
||||
│ ┌─────────┐ │
|
||||
│ │ │ Zadanie (Task) - atomowa czynność │
|
||||
│ └─────────┘ │
|
||||
│ │
|
||||
│ ┌─────────┐ │
|
||||
│ │ [+] │ Podproces (Sub-Process) - zagnieżdżony │
|
||||
│ └─────────┘ │
|
||||
│ │
|
||||
│ Typy zadań: User, Service, Script, Manual, Send, Receive │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ BRAMKI (Gateways) │
|
||||
│ │
|
||||
│ ◇ Exclusive (XOR) - jeden z wielu ścieżek │
|
||||
│ │
|
||||
│ ◆ Parallel (AND) - wszystkie ścieżki równolegle │
|
||||
│ │
|
||||
│ ○◇ Inclusive (OR) - jedna lub więcej ścieżek │
|
||||
│ │
|
||||
│ ⊕ Event-based - wybór na podstawie zdarzenia │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Connecting Objects (Łączniki)
|
||||
|
||||
| Symbol | Nazwa | Użycie |
|
||||
|--------|-------|--------|
|
||||
| ────→ | Sequence Flow | Kolejność czynności |
|
||||
| - - -→ | Message Flow | Komunikacja między uczestnikami |
|
||||
| · · ·→ | Association | Powiązanie z artefaktem |
|
||||
|
||||
#### Swimlanes (Tory)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Pool: Firma XYZ │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Lane: Dział Sprzedaży │
|
||||
│ ○────→[Przyjmij zamówienie]────→◇────→[Potwierdź] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Lane: Magazyn │
|
||||
│ └──→[Skompletuj]────→◉ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Artefakty
|
||||
|
||||
| Symbol | Nazwa | Użycie |
|
||||
|--------|-------|--------|
|
||||
| 📄 | Data Object | Dane wejściowe/wyjściowe |
|
||||
| 📁 | Data Store | Baza danych, repozytorium |
|
||||
| 📝 | Annotation | Komentarz |
|
||||
| [ ] | Group | Grupowanie elementów |
|
||||
|
||||
### Przykład procesu BPMN
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Proces: Obsługa reklamacji │
|
||||
│ │
|
||||
│ ○────→[Przyjmij ]────→◇────→[Weryfikuj ]────→◇ │
|
||||
│ [reklamację ] │ [produkt ] │ │
|
||||
│ │ │ │
|
||||
│ [Brak danych] [OK] │[NOK] │
|
||||
│ │ │ │ │
|
||||
│ ↓ │ ↓ │
|
||||
│ [Poproś o ] │ [Odrzuć ]│
|
||||
│ [uzupełnienie] │ [reklamację]│
|
||||
│ │ │ │ │
|
||||
│ └─────────────────→◆←────┘ │
|
||||
│ │ │
|
||||
│ ↓ │
|
||||
│ [Wyślij ] │
|
||||
│ [odpowiedź ] │
|
||||
│ │ │
|
||||
│ ↓ │
|
||||
│ ◉ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. UML Activity Diagrams
|
||||
|
||||
### Charakterystyka
|
||||
|
||||
- **Standard:** OMG (część UML 2.x)
|
||||
- **Cel:** Modelowanie przepływu sterowania i danych
|
||||
- **Pochodzenie:** Rozszerzenie flowcharts + Petri nets
|
||||
|
||||
### Elementy Activity Diagrams
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WĘZŁY AKCJI │
|
||||
│ │
|
||||
│ ╭─────────╮ │
|
||||
│ │ Akcja │ Action Node - pojedyncza czynność │
|
||||
│ ╰─────────╯ │
|
||||
│ │
|
||||
│ ╭──[warunek]──╮ │
|
||||
│ │ Akcja │ z Guard - akcja warunkowa │
|
||||
│ ╰─────────────╯ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WĘZŁY STERUJĄCE │
|
||||
│ │
|
||||
│ ● Initial Node (początek) │
|
||||
│ ◉ Activity Final (koniec całości) │
|
||||
│ ⊗ Flow Final (koniec przepływu) │
|
||||
│ │
|
||||
│ ◇ Decision/Merge Node │
|
||||
│ ▬ Fork/Join Node (równoległość) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PRZEPŁYW OBIEKTÓW │
|
||||
│ │
|
||||
│ [Zamówienie] Object Node │
|
||||
│ │
|
||||
│ ▭▭▭▭▭▭▭▭▭▭ Datastore │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Porównanie BPMN vs UML Activity
|
||||
|
||||
| Cecha | BPMN | UML Activity |
|
||||
|-------|------|--------------|
|
||||
| **Cel** | Procesy biznesowe | Logika oprogramowania |
|
||||
| **Odbiorcy** | Analitycy, biznes | Programiści, architekci |
|
||||
| **Swimlanes** | Pool/Lane | Partition |
|
||||
| **Zdarzenia** | Bogate (timer, message...) | Ograniczone |
|
||||
| **Automatyzacja** | BPEL, silniki BPM | Generowanie kodu |
|
||||
|
||||
---
|
||||
|
||||
## 4. EPC (Event-driven Process Chain)
|
||||
|
||||
### Charakterystyka
|
||||
|
||||
- **Pochodzenie:** ARIS (Architecture of Integrated Information Systems)
|
||||
- **Twórca:** Prof. August-Wilhelm Scheer (1992)
|
||||
- **Zastosowanie:** SAP, modelowanie procesów ERP
|
||||
|
||||
### Elementy EPC
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ ⬡ Zdarzenie (Event) - pasywne, opisuje stan │
|
||||
│ np. "Zamówienie otrzymane" │
|
||||
│ │
|
||||
│ ▭ Funkcja (Function) - aktywna, opisuje działanie │
|
||||
│ np. "Sprawdź dostępność" │
|
||||
│ │
|
||||
│ ∧ AND - wszystkie ścieżki │
|
||||
│ ∨ OR - jedna lub więcej │
|
||||
│ XOR XOR - dokładnie jedna │
|
||||
│ │
|
||||
│ ○ Organizational Unit │
|
||||
│ □ Information Object │
|
||||
│ ◇ IT System │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Reguły EPC
|
||||
|
||||
1. **Start i koniec:** Zdarzenie
|
||||
2. **Naprzemienność:** Zdarzenie → Funkcja → Zdarzenie
|
||||
3. **Łączniki:** Między zdarzeniami a funkcjami
|
||||
|
||||
```
|
||||
EPC: Proces zamówienia
|
||||
|
||||
⬡ Zamówienie otrzymane
|
||||
│
|
||||
↓
|
||||
▭ Sprawdź dostępność
|
||||
│
|
||||
↓
|
||||
XOR
|
||||
/ \
|
||||
↓ ↓
|
||||
⬡ Produkt ⬡ Produkt
|
||||
dostępny niedostępny
|
||||
│ │
|
||||
↓ ↓
|
||||
▭ Przygotuj ▭ Złóż
|
||||
wysyłkę zamówienie
|
||||
│ u dostawcy
|
||||
↓ │
|
||||
⬡ Wysyłka ↓
|
||||
gotowa ⬡ Zamówienie
|
||||
złożone
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. IDEF (Integration DEFinition)
|
||||
|
||||
### Rodzina IDEF
|
||||
|
||||
| Standard | Nazwa | Zastosowanie |
|
||||
|----------|-------|--------------|
|
||||
| **IDEF0** | Function Modeling | Hierarchia funkcji |
|
||||
| **IDEF1** | Information Modeling | Struktura danych |
|
||||
| **IDEF1X** | Data Modeling | Bazy danych (ERD) |
|
||||
| **IDEF3** | Process Description | Przepływ procesów |
|
||||
| **IDEF4** | Object-Oriented Design | Projektowanie OO |
|
||||
| **IDEF5** | Ontology Description | Ontologie |
|
||||
|
||||
### IDEF0 - Modelowanie funkcji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ KONTROLA (C) │
|
||||
│ │ │
|
||||
│ ↓ │
|
||||
│ WEJŚCIE (I) ────→ ┌───────────┐ ────→ WYJŚCIE (O) │
|
||||
│ │ FUNKCJA │ │
|
||||
│ └───────────┘ │
|
||||
│ ↑ │
|
||||
│ │ │
|
||||
│ MECHANIZM (M) │
|
||||
│ │
|
||||
│ I = Input (co jest przetwarzane) │
|
||||
│ C = Control (reguły, ograniczenia) │
|
||||
│ O = Output (rezultat) │
|
||||
│ M = Mechanism (kto/co wykonuje) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Dekompozycja IDEF0
|
||||
|
||||
```
|
||||
Poziom 0: A0 - Całość procesu
|
||||
│
|
||||
├── A1 - Podfunkcja 1
|
||||
│ ├── A11
|
||||
│ ├── A12
|
||||
│ └── A13
|
||||
│
|
||||
├── A2 - Podfunkcja 2
|
||||
│
|
||||
└── A3 - Podfunkcja 3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Inne notacje i podejścia
|
||||
|
||||
### Flowcharts (Schematy blokowe)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Symbole: │
|
||||
│ │
|
||||
│ ⬭ Terminal (Start/End) │
|
||||
│ ▭ Process (Operacja) │
|
||||
│ ◇ Decision (Decyzja) │
|
||||
│ ▱ I/O (Wejście/Wyjście) │
|
||||
│ ─→ Flow (Przepływ) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Zalety:** Proste, uniwersalne, znane
|
||||
**Wady:** Brak standaryzacji, niewystarczające dla złożonych procesów
|
||||
|
||||
### Value Stream Map (VSM)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Lean Manufacturing │
|
||||
│ │
|
||||
│ Supplier ──→ [Magazyn] ──→ [Produkcja] ──→ [QC] ──→ Customer │
|
||||
│ Inv: 5d PT: 2h PT: 30min │
|
||||
│ CT: 45s │
|
||||
│ │
|
||||
│ PT = Processing Time (czas przetwarzania) │
|
||||
│ CT = Cycle Time (czas cyklu) │
|
||||
│ Inv = Inventory (zapas) │
|
||||
│ │
|
||||
│ Cel: Identyfikacja MUDA (marnotrawstwo) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Petri Nets (Sieci Petriego)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Formalizm matematyczny dla współbieżności │
|
||||
│ │
|
||||
│ ○ Place (Miejsce) - stan │
|
||||
│ ▭ Transition (Przejście) - akcja │
|
||||
│ ● Token (Żeton) - znacznik │
|
||||
│ │
|
||||
│ ●○────→▭────→○ │
|
||||
│ │
|
||||
│ Zastosowanie: Analiza deadlocków, weryfikacja formalna │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Narzędzia do modelowania
|
||||
|
||||
### Przegląd narzędzi
|
||||
|
||||
| Narzędzie | Standardy | Typ | Cena |
|
||||
|-----------|-----------|-----|------|
|
||||
| **Bizagi Modeler** | BPMN | Dedykowane | Free/Paid |
|
||||
| **Camunda Modeler** | BPMN, DMN | Open Source | Free |
|
||||
| **Signavio** | BPMN, EPC | Cloud | Paid |
|
||||
| **ARIS** | EPC, BPMN | Enterprise | Paid |
|
||||
| **Enterprise Architect** | UML, BPMN | Uniwersalne | Paid |
|
||||
| **Lucidchart** | Wszystkie | Cloud | Free/Paid |
|
||||
| **draw.io** | Wszystkie | Free | Free |
|
||||
| **Visio** | Flowcharts, BPMN | Desktop | Paid |
|
||||
| **ProcessMaker** | BPMN | BPM Suite | Paid |
|
||||
| **Bonita** | BPMN | Open Source | Free/Paid |
|
||||
|
||||
### Funkcjonalności narzędzi
|
||||
|
||||
| Funkcja | Podstawowe | Zaawansowane |
|
||||
|---------|------------|--------------|
|
||||
| Modelowanie graficzne | ✓ | ✓ |
|
||||
| Walidacja modelu | ✗ | ✓ |
|
||||
| Symulacja | ✗ | ✓ |
|
||||
| Wykonywanie (engine) | ✗ | ✓ |
|
||||
| Eksport (XML, PDF) | ✓ | ✓ |
|
||||
| Współpraca | ✗/Cloud | ✓ |
|
||||
| Integracja z IT | ✗ | ✓ |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Porównanie standardów
|
||||
|
||||
| Cecha | BPMN | UML Activity | EPC | IDEF0 |
|
||||
|-------|------|--------------|-----|-------|
|
||||
| **Cel główny** | Procesy biznesowe | Logika systemu | Procesy ERP | Funkcje |
|
||||
| **Złożoność** | Średnia-wysoka | Średnia | Średnia | Niska |
|
||||
| **Automatyzacja** | Tak (BPEL) | Częściowo | Tak (SAP) | Nie |
|
||||
| **Popularność** | Bardzo wysoka | Wysoka | Średnia (SAP) | Niska |
|
||||
| **Krzywa uczenia** | Stroma | Średnia | Płaska | Płaska |
|
||||
| **Standaryzacja** | OMG (ISO) | OMG | ARIS | NIST |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "BPMN = Business Process Modeling Notation":
|
||||
- **B**iznesowe procesy
|
||||
- **P**ule i tory (swimlanes)
|
||||
- **M**odele graficzne + XML
|
||||
- **N**otacja standardowa (OMG)
|
||||
|
||||
### "EPC = Event → Process → Control":
|
||||
- **E**vent startuje i kończy
|
||||
- **P**roces (funkcja) działa
|
||||
- **C**ontrol przez XOR/AND/OR
|
||||
|
||||
### "ICOM" dla IDEF0:
|
||||
- **I**nput - co wchodzi
|
||||
- **C**ontrol - co kontroluje
|
||||
- **O**utput - co wychodzi
|
||||
- **M**echanism - kto/co wykonuje
|
||||
|
||||
### "Bramki BPMN - X AND OR":
|
||||
- **X** (XOR) - wyłącznie jedna ścieżka
|
||||
- **AND** (+) - wszystkie ścieżki
|
||||
- **OR** (○) - jedna lub więcej
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe (follow-up)
|
||||
|
||||
### Q1: "Jakie są poziomy dojrzałości modelowania procesów?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**CMMI-like dla BPM:**
|
||||
|
||||
| Poziom | Nazwa | Charakterystyka |
|
||||
|--------|-------|-----------------|
|
||||
| 1 | **Initial** | Ad-hoc, brak dokumentacji |
|
||||
| 2 | **Repeatable** | Podstawowa dokumentacja |
|
||||
| 3 | **Defined** | Procesy zdefiniowane, BPMN |
|
||||
| 4 | **Managed** | Mierzone KPI, optymalizacja |
|
||||
| 5 | **Optimizing** | Ciągłe doskonalenie, automatyzacja |
|
||||
|
||||
---
|
||||
|
||||
### Q2: "Co to jest BPEL i jak się ma do BPMN?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**BPEL (Business Process Execution Language)** = język XML do wykonywania procesów przez silniki workflow.
|
||||
|
||||
```
|
||||
BPMN (graficzny) → eksport → BPEL (XML) → silnik BPM → wykonanie
|
||||
```
|
||||
|
||||
| Cecha | BPMN | BPEL |
|
||||
|-------|------|------|
|
||||
| Format | Graficzny | XML |
|
||||
| Cel | Modelowanie | Wykonanie |
|
||||
| Odbiorcy | Analitycy | Systemy IT |
|
||||
| Czytelność | Wysoka | Niska |
|
||||
|
||||
---
|
||||
|
||||
### Q3: "Jakie metryki procesów można monitorować?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**KPI procesów biznesowych:**
|
||||
|
||||
| Metryka | Opis | Przykład |
|
||||
|---------|------|----------|
|
||||
| **Cycle Time** | Czas od początku do końca | 5 dni na zamówienie |
|
||||
| **Throughput** | Liczba zakończonych instancji | 100 zamówień/dzień |
|
||||
| **Cost per Transaction** | Koszt pojedynczej instancji | 50 PLN/zamówienie |
|
||||
| **Error Rate** | Procent błędów/odrzuceń | 2% reklamacji |
|
||||
| **SLA Compliance** | Zgodność z umową | 95% w terminie |
|
||||
| **Resource Utilization** | Wykorzystanie zasobów | 80% czasu pracy |
|
||||
|
||||
---
|
||||
|
||||
### Q4: "Czym różni się proces od procedury?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
| Aspekt | Proces | Procedura |
|
||||
|--------|--------|-----------|
|
||||
| **Definicja** | CO robimy (flow) | JAK robimy (instrukcja) |
|
||||
| **Zakres** | End-to-end | Pojedyncza czynność |
|
||||
| **Format** | Diagram (BPMN) | Tekst, checklist |
|
||||
| **Cel** | Optymalizacja, automatyzacja | Standaryzacja, jakość |
|
||||
| **Przykład** | Proces reklamacji | Procedura weryfikacji produktu |
|
||||
|
||||
---
|
||||
|
||||
### Q5: "Co to jest DMN i jak współpracuje z BPMN?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**DMN (Decision Model and Notation)** = standard OMG do modelowania decyzji.
|
||||
|
||||
```
|
||||
BPMN: [Oceń ryzyko kredytowe] ←── połączenie ──→ DMN: Tabela decyzyjna
|
||||
┌─────────────┐
|
||||
│Dochód │Wynik│
|
||||
│>10k │ OK │
|
||||
│<10k │ NOK │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
**Zalety:**
|
||||
- Oddzielenie logiki decyzji od przepływu
|
||||
- Łatwiejsze utrzymanie reguł biznesowych
|
||||
- Zrozumiałe dla biznesu (tabele decyzyjne)
|
||||
|
||||
---
|
||||
|
||||
### Q6: "Jakie są zasady poprawnego modelowania BPMN?"
|
||||
|
||||
**Odpowiedź:**
|
||||
|
||||
**Dobre praktyki:**
|
||||
|
||||
1. **Jeden start, jeden koniec** (per proces)
|
||||
2. **Nazwy = czasownik + rzeczownik** ("Sprawdź zamówienie")
|
||||
3. **Bramki w parach** (split → merge)
|
||||
4. **Unikaj krzyżowania linii**
|
||||
5. **Swimlanes = role, nie osoby**
|
||||
6. **Poziom szczegółowości = cel modelu**
|
||||
7. **Happy path główny, wyjątki osobno**
|
||||
|
||||
**Błędy częste:**
|
||||
- Brak bramki po decyzji
|
||||
- Mieszanie XOR i AND bez merge
|
||||
- Zbyt szczegółowe lub zbyt ogólne
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty do zapamiętania
|
||||
|
||||
1. **BPMN** = standard przemysłowy, OMG, automatyzacja
|
||||
2. **UML Activity** = dla programistów, część UML
|
||||
3. **EPC** = SAP, zdarzenia-funkcje-łączniki
|
||||
4. **IDEF0** = hierarchia funkcji, ICOM
|
||||
5. **Narzędzia:** Bizagi, Camunda, draw.io, Visio
|
||||
6. **Cel:** Dokumentacja → Analiza → Optymalizacja → Automatyzacja
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła do pogłębienia
|
||||
|
||||
1. OMG - "Business Process Model and Notation (BPMN) 2.0"
|
||||
2. Weske, M. - "Business Process Management"
|
||||
3. Dumas, M. et al. - "Fundamentals of Business Process Management"
|
||||
4. Scheer, A.-W. - "ARIS - Business Process Modeling"
|
||||
@ -1,281 +0,0 @@
|
||||
# Pytanie 12: Sieciowe modele optymalizacji w systemach zarządzania
|
||||
|
||||
## Pytanie
|
||||
**"Przedstawić sieciowe modele optymalizacji stosowane w systemach zarządzania. Omówić ich właściwości."**
|
||||
|
||||
Przedmiot: WSYZ (Wstęp do Systemów Zarządzania)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### Wprowadzenie
|
||||
|
||||
**Sieciowe modele optymalizacji** to matematyczne reprezentacje problemów decyzyjnych w postaci grafów (sieci), gdzie:
|
||||
- **Węzły** = punkty decyzyjne, lokalizacje, zdarzenia
|
||||
- **Krawędzie** = połączenia, przepływy, zależności
|
||||
- **Wagi** = koszty, czasy, przepustowości
|
||||
|
||||
---
|
||||
|
||||
## 1. Problem najkrótszej ścieżki (Shortest Path)
|
||||
|
||||
### Definicja
|
||||
Znaleźć ścieżkę o minimalnej sumie wag między węzłem źródłowym a docelowym.
|
||||
|
||||
```
|
||||
2
|
||||
A ────→ B
|
||||
│ │
|
||||
1 │ │ 3
|
||||
↓ ↓
|
||||
C ────→ D
|
||||
1
|
||||
|
||||
Najkrótsza ścieżka A→D: A→C→D (koszt: 2)
|
||||
```
|
||||
|
||||
### Algorytmy
|
||||
| Algorytm | Złożoność | Wagi ujemne | Zastosowanie |
|
||||
|----------|-----------|-------------|--------------|
|
||||
| **Dijkstra** | O(V² lub E log V) | ❌ | GPS, routing |
|
||||
| **Bellman-Ford** | O(VE) | ✅ | Finanse, arbitraż |
|
||||
| **A*** | O(E) średnio | ❌ | Gry, nawigacja |
|
||||
|
||||
### Zastosowania w zarządzaniu
|
||||
- Optymalizacja tras dostaw
|
||||
- Planowanie logistyki
|
||||
- Routing w sieciach telekomunikacyjnych
|
||||
|
||||
---
|
||||
|
||||
## 2. Problem maksymalnego przepływu (Max Flow)
|
||||
|
||||
### Definicja
|
||||
Znaleźć maksymalny przepływ ze źródła (s) do ujścia (t) przy ograniczeniach przepustowości.
|
||||
|
||||
```
|
||||
10 10
|
||||
s ────→ A ────→ t
|
||||
│ ↑ ↑
|
||||
5 │ 5 │ │ 10
|
||||
↓ │ │
|
||||
B ──────┴───────┘
|
||||
15
|
||||
|
||||
Max flow = 15 (przez A: 10, przez B: 5)
|
||||
```
|
||||
|
||||
### Algorytmy
|
||||
| Algorytm | Złożoność | Uwagi |
|
||||
|----------|-----------|-------|
|
||||
| **Ford-Fulkerson** | O(E × max_flow) | Metoda ścieżek powiększających |
|
||||
| **Edmonds-Karp** | O(VE²) | BFS dla ścieżek |
|
||||
| **Dinic** | O(V²E) | Przepływy blokujące |
|
||||
|
||||
### Zastosowania
|
||||
- Planowanie produkcji (przepustowość linii)
|
||||
- Zarządzanie siecią dystrybucji
|
||||
- Przydział zasobów
|
||||
|
||||
---
|
||||
|
||||
## 3. Problem minimalnego kosztu przepływu (Min Cost Flow)
|
||||
|
||||
### Definicja
|
||||
Przepływ o zadanej wielkości przy minimalnym koszcie (każda krawędź ma przepustowość i koszt jednostkowy).
|
||||
|
||||
```
|
||||
(cap=10, cost=2)
|
||||
s ─────────────────→ A
|
||||
│ │
|
||||
│(cap=5, cost=1) │(cap=10, cost=3)
|
||||
↓ ↓
|
||||
B ─────────────────→ t
|
||||
(cap=15, cost=1)
|
||||
|
||||
Wymagany przepływ: 10
|
||||
Min koszt = ?
|
||||
```
|
||||
|
||||
### Zastosowania
|
||||
- Transport towarów (minimalizacja kosztów)
|
||||
- Przydział zadań pracownikom
|
||||
- Optymalizacja łańcucha dostaw
|
||||
|
||||
---
|
||||
|
||||
## 4. Problem przydziału (Assignment Problem)
|
||||
|
||||
### Definicja
|
||||
Przypisanie n zadań do n wykonawców przy minimalnym koszcie (jeden do jednego).
|
||||
|
||||
```
|
||||
Zadanie 1 Zadanie 2 Zadanie 3
|
||||
Prac. A 8 4 7
|
||||
Prac. B 5 2 3
|
||||
Prac. C 9 6 4
|
||||
|
||||
Optymalny przydział: A→Z2, B→Z1, C→Z3 (koszt: 4+5+4=13)
|
||||
```
|
||||
|
||||
### Algorytm węgierski (Hungarian)
|
||||
- Złożoność: O(n³)
|
||||
- Gwarantuje optimum
|
||||
|
||||
### Zastosowania
|
||||
- Planowanie grafików pracy
|
||||
- Przydział maszyn do zleceń
|
||||
- Matching w HR (rekrutacja)
|
||||
|
||||
---
|
||||
|
||||
## 5. Problem komiwojażera (TSP - Travelling Salesman)
|
||||
|
||||
### Definicja
|
||||
Odwiedzić wszystkie węzły dokładnie raz i wrócić do startu przy minimalnym koszcie.
|
||||
|
||||
```
|
||||
A ──5── B
|
||||
│╲ ╱│
|
||||
4│ ╲3╱ │6
|
||||
│ ╳ │
|
||||
2│ ╱ ╲ │7
|
||||
│╱ ╲│
|
||||
C ──8── D
|
||||
|
||||
Optymalna trasa: A→C→D→B→A (koszt: 2+8+6+5=21)
|
||||
```
|
||||
|
||||
### Właściwości
|
||||
- **NP-trudny** - brak algorytmu wielomianowego
|
||||
- Dokładne: Branch & Bound, programowanie dynamiczne
|
||||
- Heurystyki: Nearest Neighbor, 2-opt, symulowane wyżarzanie
|
||||
|
||||
### Zastosowania
|
||||
- Planowanie tras kurierów
|
||||
- Optymalizacja wizyt serwisowych
|
||||
- Sekwencjonowanie produkcji
|
||||
|
||||
---
|
||||
|
||||
## 6. CPM/PERT - Harmonogramowanie projektów
|
||||
|
||||
### CPM (Critical Path Method)
|
||||
|
||||
```
|
||||
┌──B(3)──┐
|
||||
╱ ╲
|
||||
A(2)──┤ ├──E(2)──F(1)
|
||||
╲ ╱
|
||||
└──C(4)──D(1)
|
||||
|
||||
Ścieżka krytyczna: A→C→D→E→F (czas: 2+4+1+2+1=10)
|
||||
```
|
||||
|
||||
### Właściwości
|
||||
| Cecha | CPM | PERT |
|
||||
|-------|-----|------|
|
||||
| Czasy | Deterministyczne | Probabilistyczne (a,m,b) |
|
||||
| Zastosowanie | Projekty powtarzalne | Projekty R&D |
|
||||
| Wynik | Ścieżka krytyczna | Rozkład prawdopodobieństwa |
|
||||
|
||||
### Zastosowania
|
||||
- Zarządzanie projektami budowlanymi
|
||||
- Planowanie wdrożeń IT
|
||||
- Koordynacja produkcji
|
||||
|
||||
---
|
||||
|
||||
## 7. Drzewo rozpinające (MST - Minimum Spanning Tree)
|
||||
|
||||
### Definicja
|
||||
Połączyć wszystkie węzły przy minimalnym koszcie (bez cykli).
|
||||
|
||||
```
|
||||
Przed: Po (MST):
|
||||
2 2
|
||||
A──────B A──────B
|
||||
│╲ ╱│ │
|
||||
│3╲1╱ │4 │3
|
||||
│ C │ → │ C
|
||||
│ ╱╲ │ │ ╱
|
||||
│╱5 ╲6│ │╱5
|
||||
D──────E D E
|
||||
7
|
||||
|
||||
Koszt MST: 2+3+1+5=11
|
||||
```
|
||||
|
||||
### Algorytmy
|
||||
| Algorytm | Złożoność | Strategia |
|
||||
|----------|-----------|-----------|
|
||||
| **Kruskal** | O(E log E) | Sortuj krawędzie, Union-Find |
|
||||
| **Prim** | O(E log V) | Rozbudowa od węzła |
|
||||
|
||||
### Zastosowania
|
||||
- Projektowanie sieci (elektrycznych, telekomunikacyjnych)
|
||||
- Klasteryzacja danych
|
||||
- Minimalizacja okablowania
|
||||
|
||||
---
|
||||
|
||||
## 📊 Porównanie modeli
|
||||
|
||||
| Model | Typ problemu | Złożoność | Przykład zastosowania |
|
||||
|-------|--------------|-----------|----------------------|
|
||||
| Shortest Path | P | O(E log V) | Nawigacja GPS |
|
||||
| Max Flow | P | O(V²E) | Planowanie produkcji |
|
||||
| Min Cost Flow | P | O(V³) | Transport towarów |
|
||||
| Assignment | P | O(n³) | Grafiki pracy |
|
||||
| TSP | NP-hard | Wykładnicza | Trasy kurierów |
|
||||
| CPM/PERT | P | O(V+E) | Projekty |
|
||||
| MST | P | O(E log V) | Sieci infrastruktury |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "SPAM-CT" - modele sieciowe:
|
||||
- **S**hortest Path
|
||||
- **P**rzepływ (Max Flow)
|
||||
- **A**ssignment
|
||||
- **M**ST
|
||||
- **C**PM/PERT
|
||||
- **T**SP
|
||||
|
||||
### "Graf = Węzły + Krawędzie + Wagi":
|
||||
- Węzły = lokalizacje/decyzje
|
||||
- Krawędzie = połączenia
|
||||
- Wagi = koszty/czasy/przepustowości
|
||||
|
||||
---
|
||||
|
||||
## ❓ Możliwe pytania dodatkowe
|
||||
|
||||
### Q1: "Jaka jest różnica między CPM a PERT?"
|
||||
**Odpowiedź:** CPM używa deterministycznych czasów (znanych), PERT używa trzech estymacji (optymistyczna, najbardziej prawdopodobna, pesymistyczna) i rozkładu beta. CPM dla projektów powtarzalnych, PERT dla R&D z niepewnością.
|
||||
|
||||
### Q2: "Kiedy stosować heurystyki zamiast algorytmów dokładnych?"
|
||||
**Odpowiedź:** Gdy problem jest NP-trudny (TSP) lub dane wejściowe bardzo duże. Heurystyki dają "dość dobre" rozwiązanie w rozsądnym czasie. Przykład: 2-opt dla TSP daje rozwiązanie ~5% od optimum w O(n²).
|
||||
|
||||
### Q3: "Co to jest slack/float w CPM?"
|
||||
**Odpowiedź:** Zapas czasu zadania = najpóźniejszy start − najwcześniejszy start. Zadania na ścieżce krytycznej mają slack=0 (opóźnienie opóźni cały projekt).
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Sieciowe modele** = problemy jako grafy (węzły, krawędzie, wagi)
|
||||
2. **Shortest Path, Max Flow, MST** = rozwiązywalne w czasie wielomianowym
|
||||
3. **TSP** = NP-trudny, wymaga heurystyk
|
||||
4. **CPM/PERT** = harmonogramowanie, ścieżka krytyczna
|
||||
5. **Assignment** = optymalne dopasowanie 1:1
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Hillier, Lieberman - "Introduction to Operations Research"
|
||||
2. Cormen et al. - "Introduction to Algorithms"
|
||||
3. Winston - "Operations Research: Applications and Algorithms"
|
||||
@ -1,248 +0,0 @@
|
||||
# Pytanie 13: Systemy agentowe i aktorowe - teorie, standardy, narzędzia
|
||||
|
||||
## Pytanie
|
||||
**"Omówić szczegółowo teorie, definicje, standardy i narzędzia wykorzystywane przy projektowaniu i implementacji systemów opartych na koncepcji agenta i aktora."**
|
||||
|
||||
Przedmiot: AASD (Agentowe i Aktorowe Systemy Decyzyjne)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Definicje fundamentalne
|
||||
|
||||
#### Agent (wg Wooldridge & Jennings)
|
||||
**Agent** = system komputerowy umieszczony w środowisku, zdolny do **autonomicznego działania** w celu realizacji celów.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ŚRODOWISKO │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ Percepcja ┌─────────┐ Akcja │ │
|
||||
│ │ ─────────────────→ │ AGENT │ ─────────────────→ │ │
|
||||
│ │ (sensory) │ │ (effectors) │ │
|
||||
│ │ │ Cele │ │ │
|
||||
│ │ │ Wiedza │ │ │
|
||||
│ │ │ Plany │ │ │
|
||||
│ │ └─────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Właściwości agenta (AARC)
|
||||
|
||||
| Właściwość | Opis |
|
||||
|------------|------|
|
||||
| **Autonomiczność** | Działa bez bezpośredniej interwencji |
|
||||
| **Reaktywność** | Reaguje na zmiany środowiska |
|
||||
| **Proaktywność** | Inicjuje działania do realizacji celów |
|
||||
| **Społeczność** | Komunikuje się z innymi agentami |
|
||||
|
||||
#### Aktor (model Hewitta, 1973)
|
||||
**Aktor** = fundamentalna jednostka obliczeń, która:
|
||||
- Ma **prywatny stan**
|
||||
- Komunikuje się wyłącznie przez **wiadomości**
|
||||
- Może tworzyć nowych aktorów
|
||||
- Przetwarza jedną wiadomość naraz
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ AKTOR │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ Mailbox │ ← wiadomości (kolejka) │
|
||||
│ │ ┌─┬─┬─┬─┐ │ │
|
||||
│ │ │m│m│m│m│ │ │
|
||||
│ │ └─┴─┴─┴─┘ │ │
|
||||
│ │ ↓ │ │
|
||||
│ │ Behavior │ → przetwarzanie sekwencyjne │
|
||||
│ │ (zachowanie) │ │
|
||||
│ │ ↓ │ │
|
||||
│ │ Stan prywatny │ → izolowany, niemutowalny z zewnątrz │
|
||||
│ └──────────────────┘ │
|
||||
│ │
|
||||
│ Reakcje na wiadomość: │
|
||||
│ 1. Wyślij wiadomości do innych aktorów │
|
||||
│ 2. Utwórz nowych aktorów │
|
||||
│ 3. Zmień własne zachowanie (become) │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Agent vs Aktor
|
||||
|
||||
| Cecha | Agent | Aktor |
|
||||
|-------|-------|-------|
|
||||
| **Cel** | Inteligentne zachowanie | Współbieżność |
|
||||
| **Stan** | Beliefs, Goals, Intentions | Prywatny, izolowany |
|
||||
| **Komunikacja** | ACL (semantyka) | Wiadomości (asynchroniczne) |
|
||||
| **Autonomia** | Wysoka (decyzje) | Średnia (reaktywność) |
|
||||
| **Pochodzenie** | AI, systemy rozproszone | Teoria obliczeń |
|
||||
|
||||
---
|
||||
|
||||
### 3. Architektury agentów
|
||||
|
||||
#### BDI (Belief-Desire-Intention)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ARCHITEKTURA BDI │
|
||||
│ │
|
||||
│ Percepcja → BELIEFS (przekonania o świecie) │
|
||||
│ ↓ │
|
||||
│ DESIRES (cele do osiągnięcia) │
|
||||
│ ↓ │
|
||||
│ INTENTIONS (wybrane plany) │
|
||||
│ ↓ │
|
||||
│ Akcja │
|
||||
│ │
|
||||
│ Przykład: │
|
||||
│ B: "Jest czerwone światło" │
|
||||
│ D: "Chcę dojechać do celu" │
|
||||
│ I: "Zatrzymam się i poczekam" │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Subsumption Architecture (Brooks)
|
||||
|
||||
```
|
||||
Warstwa 3: [Eksploruj] → najwyższy priorytet
|
||||
↓ suppress
|
||||
Warstwa 2: [Unikaj przeszkód]
|
||||
↓ suppress
|
||||
Warstwa 1: [Idź przed siebie]
|
||||
↓
|
||||
Effektory
|
||||
|
||||
Zachowania niskopoziomowe mogą być "nadpisane" przez wyższe.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Standardy komunikacji agentów
|
||||
|
||||
#### FIPA (Foundation for Intelligent Physical Agents)
|
||||
|
||||
**FIPA-ACL** (Agent Communication Language):
|
||||
|
||||
```
|
||||
(inform
|
||||
:sender agent1
|
||||
:receiver agent2
|
||||
:content (price item1 100)
|
||||
:language FIPA-SL
|
||||
:ontology trading-ontology
|
||||
)
|
||||
```
|
||||
|
||||
**Performatywy FIPA:**
|
||||
|
||||
| Performatyw | Znaczenie |
|
||||
|-------------|-----------|
|
||||
| `inform` | Informuje o fakcie |
|
||||
| `request` | Prosi o wykonanie akcji |
|
||||
| `query-if` | Pyta czy coś jest prawdą |
|
||||
| `propose` | Proponuje transakcję |
|
||||
| `accept-proposal` | Akceptuje propozycję |
|
||||
| `reject-proposal` | Odrzuca propozycję |
|
||||
| `cfp` | Call for Proposals |
|
||||
|
||||
#### KQML (Knowledge Query and Manipulation Language)
|
||||
Starszy standard, podobny do FIPA-ACL.
|
||||
|
||||
---
|
||||
|
||||
### 5. Narzędzia i frameworki
|
||||
|
||||
#### Systemy agentowe
|
||||
|
||||
| Narzędzie | Język | Opis |
|
||||
|-----------|-------|------|
|
||||
| **JADE** | Java | FIPA-compliant, najpopularniejszy |
|
||||
| **Jason** | AgentSpeak | BDI, deklaratywny |
|
||||
| **SPADE** | Python | Asynchroniczny, XMPP |
|
||||
| **NetLogo** | Logo | Symulacje, edukacja |
|
||||
| **MASON** | Java | Symulacje wieloagentowe |
|
||||
|
||||
#### Systemy aktorowe
|
||||
|
||||
| Narzędzie | Język | Opis |
|
||||
|-----------|-------|------|
|
||||
| **Akka** | Scala/Java | Produkcyjny, dojrzały |
|
||||
| **Erlang/OTP** | Erlang | Telekomunikacja, fault-tolerant |
|
||||
| **Orleans** | C# | Microsoft, Virtual Actors |
|
||||
| **Pony** | Pony | Capabilities, bezpieczny |
|
||||
| **Ray** | Python | ML, distributed computing |
|
||||
|
||||
---
|
||||
|
||||
### 6. Protokoły interakcji
|
||||
|
||||
#### Contract Net Protocol
|
||||
|
||||
```
|
||||
┌─────────┐ cfp ┌─────────┐
|
||||
│ Manager │───────────────────→│ Bidder1 │
|
||||
│ │←──────propose──────│ │
|
||||
│ │ cfp ├─────────┤
|
||||
│ │───────────────────→│ Bidder2 │
|
||||
│ │←──────propose──────│ │
|
||||
│ │ ├─────────┤
|
||||
│ │───accept-proposal─→│ Winner │
|
||||
│ │←─────inform────────│ │
|
||||
└─────────┘ └─────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "BDI = Believe, Desire, Intend":
|
||||
- **B**eliefs = co wiem o świecie
|
||||
- **D**esires = czego chcę
|
||||
- **I**ntentions = co zamierzam zrobić
|
||||
|
||||
### "ARPS" - właściwości agenta:
|
||||
- **A**utonomiczność
|
||||
- **R**eaktywność
|
||||
- **P**roaktywność
|
||||
- **S**połeczność
|
||||
|
||||
### "Aktor = Mailbox + Behavior + State":
|
||||
- Kolejka wiadomości
|
||||
- Logika przetwarzania
|
||||
- Izolowany stan
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Czym różni się JADE od Akka?"
|
||||
**Odpowiedź:** JADE to framework agentowy (FIPA, ACL, inteligentne zachowania), Akka to framework aktorowy (współbieżność, fault-tolerance, reactive streams). JADE dla AI/MAS, Akka dla systemów rozproszonych.
|
||||
|
||||
### Q2: "Co to jest Yellow Pages w systemach agentowych?"
|
||||
**Odpowiedź:** Usługa katalogowa (Directory Facilitator w FIPA) gdzie agenty rejestrują swoje usługi. Inne agenty mogą wyszukiwać agenty oferujące konkretne usługi. Analogia do książki telefonicznej.
|
||||
|
||||
### Q3: "Jak Akka zapewnia fault-tolerance?"
|
||||
**Odpowiedź:** Supervision trees - każdy aktor ma supervisora, który decyduje o reakcji na błąd (restart, stop, eskaluj). "Let it crash" philosophy - izolacja błędów.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Agent** = autonomiczny, reaktywny, proaktywny, społeczny
|
||||
2. **Aktor** = mailbox + behavior + isolated state
|
||||
3. **BDI** = Beliefs-Desires-Intentions (architektura)
|
||||
4. **FIPA-ACL** = standard komunikacji agentów
|
||||
5. **JADE** = agenty (Java), **Akka** = aktorzy (Scala)
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Wooldridge - "An Introduction to MultiAgent Systems"
|
||||
2. Hewitt - "A Universal Modular Actor Formalism for AI"
|
||||
3. FIPA Specifications - fipa.org
|
||||
4. Akka Documentation - akka.io
|
||||
@ -1,302 +0,0 @@
|
||||
# Pytanie 14: Algorytmy i metody w systemach wieloagentowych i aktorowych
|
||||
|
||||
## Pytanie
|
||||
**"Wymienić i szczegółowo opisać wybrane algorytmy i metody wykorzystywane w systemach wieloagentowych i aktorowych."**
|
||||
|
||||
Przedmiot: AASD (Agentowe i Aktorowe Systemy Decyzyjne)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Algorytmy negocjacji i aukcji
|
||||
|
||||
#### Contract Net Protocol (CNP)
|
||||
|
||||
```
|
||||
Fazy:
|
||||
1. ANNOUNCEMENT - Manager ogłasza zadanie (cfp)
|
||||
2. BIDDING - Wykonawcy składają oferty (propose)
|
||||
3. AWARDING - Manager wybiera najlepszą (accept/reject)
|
||||
4. EXECUTION - Wybrany wykonuje zadanie (inform)
|
||||
|
||||
Manager Contractors
|
||||
│ ┌───┬───┬───┐
|
||||
│────── cfp ──────────→│ A │ B │ C │
|
||||
│ └───┴───┴───┘
|
||||
│←───── propose ─────── │ │
|
||||
│←───── propose ──────────── │
|
||||
│←───── propose ─────────────────
|
||||
│
|
||||
│── accept-proposal ──→ B (winner)
|
||||
│── reject-proposal ──→ A, C
|
||||
│
|
||||
│←───── inform ─────── B (result)
|
||||
```
|
||||
|
||||
**Zastosowania:** Przydział zadań, zarządzanie zasobami, e-commerce
|
||||
|
||||
#### Aukcje wieloagentowe
|
||||
|
||||
| Typ aukcji | Mechanizm | Właściwości |
|
||||
|------------|-----------|-------------|
|
||||
| **English** | Rosnące stawki | Otwarta, winner's curse |
|
||||
| **Dutch** | Malejące stawki | Szybka, ryzykowna |
|
||||
| **First-price sealed** | Zapieczętowane | Strategiczne zaniżanie |
|
||||
| **Vickrey** | Second-price sealed | Truthful (incentive compatible) |
|
||||
|
||||
---
|
||||
|
||||
### 2. Algorytmy konsensusu
|
||||
|
||||
#### Raft (dla systemów aktorowych)
|
||||
|
||||
```
|
||||
Stany węzłów: FOLLOWER → CANDIDATE → LEADER
|
||||
|
||||
Leader Election:
|
||||
1. Follower timeout → staje się Candidate
|
||||
2. Candidate wysyła RequestVote do wszystkich
|
||||
3. Większość głosów → nowy Leader
|
||||
4. Leader wysyła heartbeats
|
||||
|
||||
Log Replication:
|
||||
1. Client → Leader (command)
|
||||
2. Leader → Followers (AppendEntries)
|
||||
3. Większość potwierdza → commit
|
||||
4. Leader → Client (success)
|
||||
```
|
||||
|
||||
#### PBFT (Practical Byzantine Fault Tolerance)
|
||||
|
||||
```
|
||||
Toleruje f błędnych węzłów przy n ≥ 3f + 1
|
||||
|
||||
Fazy:
|
||||
PRE-PREPARE → PREPARE → COMMIT → REPLY
|
||||
|
||||
Client ──request──→ Primary
|
||||
│
|
||||
┌──────────┼──────────┐
|
||||
↓ ↓ ↓
|
||||
Replica1 Replica2 Replica3
|
||||
└──────────┼──────────┘
|
||||
↓
|
||||
Reply
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Algorytmy koordynacji
|
||||
|
||||
#### Distributed Mutual Exclusion
|
||||
|
||||
**Algorytm Ricarta-Agrawali:**
|
||||
```
|
||||
Wejście do sekcji krytycznej:
|
||||
1. Wyślij REQUEST(timestamp) do wszystkich
|
||||
2. Czekaj na REPLY od wszystkich
|
||||
3. Wejdź do sekcji krytycznej
|
||||
|
||||
Odbiór REQUEST:
|
||||
- Jeśli nie chcę CS lub mój timestamp > nadawcy → wyślij REPLY
|
||||
- W przeciwnym razie → kolejkuj REQUEST
|
||||
```
|
||||
|
||||
**Złożoność:** 2(N-1) wiadomości na wejście do CS
|
||||
|
||||
#### Token Ring
|
||||
```
|
||||
┌───→ A ───→ B ───┐
|
||||
│ ↓
|
||||
│ [TOKEN] │
|
||||
│ │
|
||||
└─── D ←─── C ←───┘
|
||||
|
||||
Kto ma token → może wejść do CS
|
||||
Złożoność: 0 do N-1 wiadomości (średnio N/2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Algorytmy uczenia wieloagentowego
|
||||
|
||||
#### Q-Learning (Independent Learners)
|
||||
|
||||
```
|
||||
Każdy agent uczy się niezależnie:
|
||||
|
||||
Q(s,a) ← Q(s,a) + α[r + γ max Q(s',a') - Q(s,a)]
|
||||
|
||||
Problem: Środowisko niestacjonarne (inni agenci się zmieniają)
|
||||
```
|
||||
|
||||
#### Nash Q-Learning
|
||||
|
||||
```
|
||||
Uwzględnia akcje innych agentów:
|
||||
|
||||
Q_i(s, a₁, a₂, ..., aₙ) - wartość dla agenta i
|
||||
|
||||
Aktualizacja używa równowagi Nasha:
|
||||
Q_i ← Q_i + α[r_i + γ Nash(Q_i(s')) - Q_i]
|
||||
```
|
||||
|
||||
#### Fictitious Play
|
||||
```
|
||||
1. Obserwuj akcje przeciwników
|
||||
2. Buduj rozkład empiryczny ich strategii
|
||||
3. Graj best response wobec tego rozkładu
|
||||
4. Powtarzaj
|
||||
|
||||
Zbieżność do Nasha w grach z właściwością FP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Algorytmy dla aktorów
|
||||
|
||||
#### Supervision Strategies (Akka)
|
||||
|
||||
```scala
|
||||
// One-for-One: restart tylko tego aktora
|
||||
override val supervisorStrategy =
|
||||
OneForOneStrategy() {
|
||||
case _: ArithmeticException => Resume
|
||||
case _: NullPointerException => Restart
|
||||
case _: Exception => Stop
|
||||
}
|
||||
|
||||
// All-for-One: restart wszystkich dzieci
|
||||
override val supervisorStrategy =
|
||||
AllForOneStrategy() {
|
||||
case _: Exception => Restart
|
||||
}
|
||||
```
|
||||
|
||||
#### Routing Strategies
|
||||
|
||||
| Strategia | Opis |
|
||||
|-----------|------|
|
||||
| **Round Robin** | Po kolei do każdego |
|
||||
| **Random** | Losowo |
|
||||
| **Smallest Mailbox** | Do najmniej obciążonego |
|
||||
| **Broadcast** | Do wszystkich |
|
||||
| **Consistent Hashing** | Wg klucza (locality) |
|
||||
|
||||
---
|
||||
|
||||
### 6. Algorytmy planowania (BDI)
|
||||
|
||||
#### Means-Ends Reasoning
|
||||
|
||||
```
|
||||
Goal: be_at(destination)
|
||||
|
||||
Plans:
|
||||
plan1: walk(X,Y) :- distance(X,Y) < 1km
|
||||
plan2: drive(X,Y) :- have(car), distance(X,Y) >= 1km
|
||||
plan3: take_bus(X,Y) :- bus_available(X,Y)
|
||||
|
||||
Wybór planu na podstawie:
|
||||
- Kontekstu (beliefs)
|
||||
- Preferencji
|
||||
- Kosztu
|
||||
```
|
||||
|
||||
#### Partial Order Planning (POP)
|
||||
|
||||
```
|
||||
Cel: have(coffee) ∧ have(report)
|
||||
|
||||
Start
|
||||
│
|
||||
┌────┴────┐
|
||||
↓ ↓
|
||||
buy(coffee) write(report)
|
||||
│ │
|
||||
└────┬────┘
|
||||
↓
|
||||
Goal
|
||||
|
||||
Ordering constraints: flexible (równoległość gdy możliwa)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Algorytmy formowania koalicji
|
||||
|
||||
#### Shapley Value
|
||||
|
||||
```
|
||||
Sprawiedliwy podział zysków w koalicji:
|
||||
|
||||
φᵢ = Σ [|S|!(n-|S|-1)!/n!] × [v(S∪{i}) - v(S)]
|
||||
|
||||
Gdzie:
|
||||
- S = podzbiór agentów bez i
|
||||
- v(S) = wartość koalicji S
|
||||
- n = liczba agentów
|
||||
|
||||
Właściwości: efektywność, symetria, addytywność
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Podsumowanie algorytmów
|
||||
|
||||
| Kategoria | Algorytm | Zastosowanie |
|
||||
|-----------|----------|--------------|
|
||||
| Negocjacje | Contract Net | Przydział zadań |
|
||||
| Aukcje | Vickrey | Truthful bidding |
|
||||
| Konsensus | Raft, PBFT | Systemy rozproszone |
|
||||
| Koordynacja | Ricart-Agrawala | Mutual exclusion |
|
||||
| Uczenie | Nash Q-Learning | Gry wieloagentowe |
|
||||
| Aktorzy | Supervision | Fault tolerance |
|
||||
| Planowanie | Means-Ends | BDI agenty |
|
||||
| Koalicje | Shapley Value | Podział zysków |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "CNP = Call, Propose, Award, Execute":
|
||||
Fazy Contract Net Protocol
|
||||
|
||||
### "RAFT = Replicated And Fault Tolerant":
|
||||
Leader election + log replication
|
||||
|
||||
### "Vickrey = Second price = Truthful":
|
||||
Płacisz drugą cenę → opłaca się licytować prawdziwie
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Dlaczego aukcja Vickreya jest truthful?"
|
||||
**Odpowiedź:** Płacisz drugą najwyższą cenę, nie swoją. Licytowanie poniżej wartości = ryzyko przegranej. Licytowanie powyżej = ryzyko przepłacenia. Optymalna strategia = licytuj prawdziwą wartość.
|
||||
|
||||
### Q2: "Jak Raft radzi sobie z partycją sieci?"
|
||||
**Odpowiedź:** Tylko partycja z większością węzłów może wybrać lidera i commitować. Mniejszość jest zablokowana (read-only lub niedostępna). Po naprawie partycji - synchronizacja logów.
|
||||
|
||||
### Q3: "Czym różni się One-for-One od All-for-One supervision?"
|
||||
**Odpowiedź:** One-for-One: restart tylko wadliwego aktora (izolacja błędu). All-for-One: restart wszystkich dzieci (gdy stan jest współdzielony/zależny). Wybór zależy od zależności między aktorami.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Contract Net** = aukcja zadań między agentami
|
||||
2. **Raft/PBFT** = konsensus w systemach rozproszonych
|
||||
3. **Nash Q-Learning** = uczenie z uwzględnieniem innych
|
||||
4. **Supervision** = "let it crash" + automatic recovery
|
||||
5. **Shapley Value** = sprawiedliwy podział koalicji
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Shoham, Leyton-Brown - "Multiagent Systems"
|
||||
2. Ongaro, Ousterhout - "In Search of an Understandable Consensus Algorithm" (Raft)
|
||||
3. Akka Documentation - Supervision
|
||||
4. Sandholm - "Distributed Rational Decision Making"
|
||||
@ -1,219 +0,0 @@
|
||||
# Pytanie 15: Metody modelowania architektury systemów informatycznych
|
||||
|
||||
## Pytanie
|
||||
**"Omówić metody modelowania architektury systemów informatycznych. Przedstawić cele i metody modelowania architektury."**
|
||||
|
||||
Przedmiot: AIS (Architektura i Integracja Systemów)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Cele modelowania architektury
|
||||
|
||||
| Cel | Opis |
|
||||
|-----|------|
|
||||
| **Komunikacja** | Wspólny język dla stakeholderów |
|
||||
| **Dokumentacja** | Zapis decyzji architektonicznych |
|
||||
| **Analiza** | Weryfikacja atrybutów jakościowych |
|
||||
| **Planowanie** | Roadmapa rozwoju systemu |
|
||||
| **Zarządzanie złożonością** | Abstrakcja, dekompozycja |
|
||||
|
||||
---
|
||||
|
||||
### 2. Frameworki architektoniczne
|
||||
|
||||
#### TOGAF (The Open Group Architecture Framework)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ADM (Architecture Development Method) │
|
||||
│ │
|
||||
│ Preliminary │
|
||||
│ ↓ │
|
||||
│ ┌─── A. Architecture Vision ───┐ │
|
||||
│ ↓ ↓ │
|
||||
│ H. Architecture ←───────────→ B. Business │
|
||||
│ Change Mgmt Architecture │
|
||||
│ ↑ ↓ │
|
||||
│ G. Implementation ←── Requirements ── C. Information │
|
||||
│ Governance Management Systems Arch │
|
||||
│ ↑ ↓ │
|
||||
│ F. Migration ←───────────→ D. Technology │
|
||||
│ Planning Architecture │
|
||||
│ ↑ ↓ │
|
||||
│ └─── E. Opportunities & Solutions ───┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Domeny TOGAF:**
|
||||
- Business Architecture
|
||||
- Data Architecture
|
||||
- Application Architecture
|
||||
- Technology Architecture
|
||||
|
||||
#### Zachman Framework
|
||||
|
||||
```
|
||||
│ What │ How │ Where │ Who │ When │ Why
|
||||
─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────
|
||||
Planner │ Data │ Function│ Network │ People │ Time │ Motivation
|
||||
Owner │ Entity │ Process │ Location│ Org │ Schedule│ Goals
|
||||
Designer │ Model │ System │ Distrib │ Role │ Workflow│ Rules
|
||||
Builder │ Schema │ Program │ Infra │ UI │ Control │ Logic
|
||||
│ │ │ │ │ │
|
||||
```
|
||||
|
||||
#### 4+1 View Model (Kruchten)
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Scenarios │
|
||||
│ (Use Cases) │
|
||||
└────────┬────────┘
|
||||
│
|
||||
┌────────────────────┼────────────────────┐
|
||||
↓ ↓ ↓
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ Logical │ │ Process │ │ Development │
|
||||
│ View │ │ View │ │ View │
|
||||
│ (funkcjonalna)│ │ (współbieżn.) │ │ (organizacja) │
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
│
|
||||
┌────────┴────────┐
|
||||
│ Physical │
|
||||
│ View │
|
||||
│ (wdrożenie) │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Notacje i języki modelowania
|
||||
|
||||
#### UML (Unified Modeling Language)
|
||||
|
||||
| Diagram | Zastosowanie |
|
||||
|---------|--------------|
|
||||
| **Component** | Struktura modułów |
|
||||
| **Deployment** | Fizyczne rozmieszczenie |
|
||||
| **Package** | Organizacja logiczna |
|
||||
| **Sequence** | Interakcje czasowe |
|
||||
|
||||
#### ArchiMate
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Warstwy ArchiMate: │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐│
|
||||
│ │ Business Layer │ Actor, Role, Process, Service, Event ││
|
||||
│ ├─────────────────────────────────────────────────────────────┤│
|
||||
│ │ Application Layer │ Component, Interface, Function, Service ││
|
||||
│ ├─────────────────────────────────────────────────────────────┤│
|
||||
│ │ Technology Layer │ Node, Device, Network, Artifact ││
|
||||
│ └─────────────────────────────────────────────────────────────┘│
|
||||
│ │
|
||||
│ Aspekty: Passive (data), Behavior (process), Active (actor) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### C4 Model (Simon Brown)
|
||||
|
||||
```
|
||||
Level 1: System Context - System w kontekście użytkowników
|
||||
Level 2: Container - Aplikacje, bazy, serwisy
|
||||
Level 3: Component - Wewnętrzna struktura kontenera
|
||||
Level 4: Code - Klasy, interfejsy (opcjonalnie)
|
||||
|
||||
Zasada: Zoom in/out między poziomami
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. ADR (Architecture Decision Records)
|
||||
|
||||
```markdown
|
||||
# ADR-001: Wybór bazy danych
|
||||
|
||||
## Status: Accepted
|
||||
|
||||
## Context
|
||||
System wymaga przechowywania danych użytkowników...
|
||||
|
||||
## Decision
|
||||
Wybieramy PostgreSQL
|
||||
|
||||
## Consequences
|
||||
+ Dojrzały, stabilny
|
||||
+ Wsparcie JSON
|
||||
- Wymaga DBA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Metody analizy architektury
|
||||
|
||||
#### ATAM (Architecture Tradeoff Analysis Method)
|
||||
|
||||
```
|
||||
Fazy:
|
||||
1. Present architecture
|
||||
2. Identify quality attribute scenarios
|
||||
3. Generate quality attribute utility tree
|
||||
4. Analyze architectural approaches
|
||||
5. Identify sensitivity & tradeoff points
|
||||
6. Generate risks & non-risks
|
||||
```
|
||||
|
||||
#### Quality Attributes (ISO 25010)
|
||||
|
||||
| Atrybut | Opis |
|
||||
|---------|------|
|
||||
| **Performance** | Czas odpowiedzi, throughput |
|
||||
| **Security** | CIA (Confidentiality, Integrity, Availability) |
|
||||
| **Scalability** | Horizontal/Vertical scaling |
|
||||
| **Maintainability** | Modyfikowalność, testowalność |
|
||||
| **Reliability** | MTBF, MTTR |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "TOGAF ADM = A-H cycle":
|
||||
A-Vision, B-Business, C-IS, D-Tech, E-Opportunities, F-Migration, G-Governance, H-Change
|
||||
|
||||
### "C4 = Context, Container, Component, Code":
|
||||
4 poziomy zoomu architektury
|
||||
|
||||
### "4+1 = LDPP + Scenarios":
|
||||
Logical, Development, Process, Physical + Scenarios
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jaka jest różnica między TOGAF a Zachman?"
|
||||
**Odpowiedź:** TOGAF to metodyka (proces ADM), Zachman to taksonomia (klasyfikacja artefaktów). TOGAF mówi JAK tworzyć architekturę, Zachman CO dokumentować.
|
||||
|
||||
### Q2: "Kiedy używać C4 vs ArchiMate?"
|
||||
**Odpowiedź:** C4 dla programistów (proste, 4 poziomy), ArchiMate dla enterprise architects (formalne, warstwy biznes-aplikacja-technologia).
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **TOGAF** = metodyka ADM + 4 domeny
|
||||
2. **4+1** = 5 widoków (Logical, Process, Development, Physical, Scenarios)
|
||||
3. **C4** = 4 poziomy zoomu
|
||||
4. **ArchiMate** = 3 warstwy (Business, Application, Technology)
|
||||
5. **ADR** = dokumentacja decyzji
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. TOGAF 9.2 Standard - The Open Group
|
||||
2. Kruchten - "4+1 View Model"
|
||||
3. Simon Brown - "C4 Model" (c4model.com)
|
||||
4. ArchiMate 3.1 Specification
|
||||
@ -1,234 +0,0 @@
|
||||
# Pytanie 16: Wzorce architektoniczne
|
||||
|
||||
## Pytanie
|
||||
**"Czemu służą wzorce architektoniczne? Jak powstają? Jak są katalogowane? Omówić przykładowe wzorce architektoniczne."**
|
||||
|
||||
Przedmiot: AIS (Architektura i Integracja Systemów)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Cel wzorców architektonicznych
|
||||
|
||||
| Cel | Opis |
|
||||
|-----|------|
|
||||
| **Reużywalność** | Sprawdzone rozwiązania typowych problemów |
|
||||
| **Komunikacja** | Wspólne słownictwo ("używamy MVC") |
|
||||
| **Dokumentacja** | Zapis wiedzy architektonicznej |
|
||||
| **Jakość** | Adresowanie atrybutów jakościowych |
|
||||
| **Edukacja** | Nauka z doświadczeń innych |
|
||||
|
||||
---
|
||||
|
||||
### 2. Jak powstają wzorce
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 1. PROBLEM pojawia się wielokrotnie │
|
||||
│ ↓ │
|
||||
│ 2. Różni architekci znajdują PODOBNE ROZWIĄZANIA │
|
||||
│ ↓ │
|
||||
│ 3. UOGÓLNIENIE - wyodrębnienie wspólnych elementów │
|
||||
│ ↓ │
|
||||
│ 4. DOKUMENTACJA w formie wzorca │
|
||||
│ ↓ │
|
||||
│ 5. WALIDACJA przez społeczność (peer review) │
|
||||
│ ↓ │
|
||||
│ 6. KATALOGOWANIE w książkach/repozytoriach │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Format opisu wzorca:**
|
||||
- **Nazwa** - identyfikator
|
||||
- **Kontekst** - kiedy stosować
|
||||
- **Problem** - co rozwiązuje
|
||||
- **Rozwiązanie** - struktura i zachowanie
|
||||
- **Konsekwencje** - trade-offs
|
||||
- **Znane zastosowania** - przykłady
|
||||
|
||||
---
|
||||
|
||||
### 3. Katalogowanie wzorców
|
||||
|
||||
| Katalog | Zakres | Przykłady |
|
||||
|---------|--------|-----------|
|
||||
| **POSA** (Pattern-Oriented Software Architecture) | Architektura | Layers, Pipes&Filters |
|
||||
| **GoF** (Gang of Four) | Projektowe | Factory, Observer |
|
||||
| **EIP** (Enterprise Integration Patterns) | Integracja | Message Router, Aggregator |
|
||||
| **PoEAA** (Fowler) | Enterprise | Repository, Unit of Work |
|
||||
| **Cloud Patterns** | Chmura | Circuit Breaker, Sidecar |
|
||||
|
||||
---
|
||||
|
||||
### 4. Przykładowe wzorce architektoniczne
|
||||
|
||||
#### Layered Architecture (Warstwy)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Presentation Layer │ UI, Controllers
|
||||
├─────────────────────────────────────────┤
|
||||
│ Business Logic Layer │ Services, Domain
|
||||
├─────────────────────────────────────────┤
|
||||
│ Data Access Layer │ Repositories, ORM
|
||||
├─────────────────────────────────────────┤
|
||||
│ Database │ SQL, NoSQL
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
Zasada: Warstwa zna tylko warstwę bezpośrednio niższą
|
||||
+ Separacja odpowiedzialności
|
||||
- Sztywność, boilerplate
|
||||
```
|
||||
|
||||
#### Microservices
|
||||
|
||||
```
|
||||
┌─────┐ ┌─────┐ ┌─────┐
|
||||
│User │ │Order│ │Inv- │
|
||||
│Svc │ │Svc │ │entory│
|
||||
└──┬──┘ └──┬──┘ └──┬──┘
|
||||
│ │ │
|
||||
└────┬────┴────┬────┘
|
||||
│ │
|
||||
┌────┴────┐ │
|
||||
│API Gate │────┘
|
||||
│ way │
|
||||
└─────────┘
|
||||
|
||||
+ Niezależne wdrożenia, skalowalność
|
||||
- Złożoność operacyjna, komunikacja
|
||||
```
|
||||
|
||||
#### Event-Driven Architecture (EDA)
|
||||
|
||||
```
|
||||
┌──────────┐ event ┌──────────┐
|
||||
│ Producer │ ───────────→ │ Event │
|
||||
└──────────┘ │ Broker │
|
||||
│(Kafka) │
|
||||
┌──────────┐ event └────┬─────┘
|
||||
│ Consumer │ ←─────────────────┘
|
||||
│ A │
|
||||
└──────────┘
|
||||
┌──────────┐ event
|
||||
│ Consumer │ ←─────────────────┘
|
||||
│ B │
|
||||
└──────────┘
|
||||
|
||||
+ Loose coupling, skalowalność
|
||||
- Eventual consistency, debugging
|
||||
```
|
||||
|
||||
#### CQRS (Command Query Responsibility Segregation)
|
||||
|
||||
```
|
||||
Commands Queries
|
||||
│ │
|
||||
↓ ↓
|
||||
┌──────────┐ ┌──────────┐
|
||||
│ Write │ │ Read │
|
||||
│ Model │ │ Model │
|
||||
└────┬─────┘ └────┬─────┘
|
||||
│ │
|
||||
↓ ↓
|
||||
┌──────────┐ sync ┌──────────┐
|
||||
│ Write │ ─────────→ │ Read │
|
||||
│ DB │ │ DB │
|
||||
└──────────┘ └──────────┘
|
||||
|
||||
+ Optymalizacja read/write osobno
|
||||
- Złożoność, eventual consistency
|
||||
```
|
||||
|
||||
#### Hexagonal Architecture (Ports & Adapters)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Application Core │
|
||||
│ ┌───────────────────────────────┐ │
|
||||
Adapter │ │ │ │ Adapter
|
||||
(REST) ──┼──│► Port Domain Port ◄├──┼── (DB)
|
||||
│ │ (in) Logic (out) │ │
|
||||
│ └───────────────────────────────┘ │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
+ Testowalność, niezależność od frameworków
|
||||
- Więcej kodu (adaptery)
|
||||
```
|
||||
|
||||
#### Saga Pattern (dla transakcji rozproszonych)
|
||||
|
||||
```
|
||||
Orchestration:
|
||||
┌─────────┐ cmd ┌─────────┐ cmd ┌─────────┐
|
||||
│ Saga │ ───────→ │ Service │ ───────→ │ Service │
|
||||
│Orchestr.│ ←─reply── │ A │ ←─reply── │ B │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
│
|
||||
│ compensation (rollback) jeśli błąd
|
||||
↓
|
||||
|
||||
Choreography:
|
||||
Service A ──event──→ Service B ──event──→ Service C
|
||||
↑ │
|
||||
└────────── compensation event ──────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Porównanie wzorców
|
||||
|
||||
| Wzorzec | Skalowalność | Złożoność | Use Case |
|
||||
|---------|--------------|-----------|----------|
|
||||
| **Monolith** | Niska | Niska | MVP, małe zespoły |
|
||||
| **Layered** | Średnia | Niska | Enterprise CRUD |
|
||||
| **Microservices** | Wysoka | Wysoka | Duże systemy |
|
||||
| **Event-Driven** | Wysoka | Średnia | Real-time, IoT |
|
||||
| **CQRS** | Wysoka | Wysoka | Read-heavy systems |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "LAMP = Layers, API Gateway, Microservices, Pub/Sub":
|
||||
Ewolucja architektur
|
||||
|
||||
### "CQRS = Commands mutate, Queries read":
|
||||
Rozdzielenie zapisu od odczytu
|
||||
|
||||
### "Hexagonal = Inside-Out testing":
|
||||
Core nie zna zewnętrznych szczegółów
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy wybrać monolith zamiast microservices?"
|
||||
**Odpowiedź:** Mały zespół (<10), MVP, niejasne granice domen, brak DevOps maturity. "Monolith first" - rozdzielaj gdy wiesz gdzie granice.
|
||||
|
||||
### Q2: "Jak CQRS współpracuje z Event Sourcing?"
|
||||
**Odpowiedź:** Event Sourcing zapisuje zdarzenia (nie stan), CQRS buduje read model z eventów. Razem: audit trail, time-travel, ale złożoność.
|
||||
|
||||
### Q3: "Co to jest Strangler Fig Pattern?"
|
||||
**Odpowiedź:** Migracja z monolitu do microservices. Nowe funkcje jako mikroserwisy, stare stopniowo zastępowane. Routing przez facade. Nazwa od figi dusiciela.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Wzorce** = sprawdzone rozwiązania typowych problemów
|
||||
2. **Katalogi:** POSA, GoF, EIP, PoEAA
|
||||
3. **Layered** = separacja, proste, sztywne
|
||||
4. **Microservices** = niezależność, złożoność ops
|
||||
5. **Event-Driven** = loose coupling, eventual consistency
|
||||
6. **CQRS** = osobne modele read/write
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Buschmann et al. - "POSA Vol. 1"
|
||||
2. Fowler - "Patterns of Enterprise Application Architecture"
|
||||
3. Hohpe, Woolf - "Enterprise Integration Patterns"
|
||||
4. Richardson - "Microservices Patterns"
|
||||
@ -1,208 +0,0 @@
|
||||
# Pytanie 17: Optymalizacja nieliniowa - warunki optymalności
|
||||
|
||||
## Pytanie
|
||||
**"Przedstawić warunki konieczne i dostateczne optymalności różniczkowalnych zadań optymalizacji bez ograniczeń i z ograniczeniami oraz warunki regularności i omówić metody poszukiwania rozwiązań zadań optymalizacji nieliniowej."**
|
||||
|
||||
Przedmiot: AMO (Analiza i Metody Optymalizacji)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Optymalizacja bez ograniczeń
|
||||
|
||||
#### Problem
|
||||
$$\min_{x \in \mathbb{R}^n} f(x)$$
|
||||
|
||||
#### Warunki konieczne (I rzędu)
|
||||
Jeśli $x^*$ jest minimum lokalnym i $f$ jest różniczkowalna:
|
||||
$$\nabla f(x^*) = 0$$
|
||||
|
||||
(Gradient zerowy - punkt stacjonarny)
|
||||
|
||||
#### Warunki dostateczne (II rzędu)
|
||||
Jeśli $\nabla f(x^*) = 0$ oraz hesjan $H(x^*) = \nabla^2 f(x^*)$:
|
||||
|
||||
| Hesjan | Wniosek |
|
||||
|--------|---------|
|
||||
| $H \succ 0$ (dodatnio określony) | **Minimum lokalne** |
|
||||
| $H \prec 0$ (ujemnie określony) | Maximum lokalne |
|
||||
| $H$ nieokreślony | Punkt siodłowy |
|
||||
| $H \succeq 0$ (półdodatni) | Brak wniosku |
|
||||
|
||||
**Sprawdzenie:** Wszystkie wartości własne $\lambda_i > 0 \Rightarrow H \succ 0$
|
||||
|
||||
---
|
||||
|
||||
### 2. Optymalizacja z ograniczeniami
|
||||
|
||||
#### Problem ogólny
|
||||
$$\min_{x} f(x)$$
|
||||
$$\text{s.t. } g_i(x) \leq 0, \quad i = 1, \ldots, m$$
|
||||
$$\quad\quad h_j(x) = 0, \quad j = 1, \ldots, p$$
|
||||
|
||||
#### Lagrangian
|
||||
$$L(x, \lambda, \mu) = f(x) + \sum_{i=1}^{m} \lambda_i g_i(x) + \sum_{j=1}^{p} \mu_j h_j(x)$$
|
||||
|
||||
---
|
||||
|
||||
### 3. Warunki KKT (Karush-Kuhn-Tucker)
|
||||
|
||||
#### Warunki konieczne I rzędu
|
||||
|
||||
Jeśli $x^*$ jest minimum i spełnione są warunki regularności:
|
||||
|
||||
1. **Stacjonarność:**
|
||||
$$\nabla_x L(x^*, \lambda^*, \mu^*) = 0$$
|
||||
|
||||
2. **Dopuszczalność pierwotna:**
|
||||
$$g_i(x^*) \leq 0, \quad h_j(x^*) = 0$$
|
||||
|
||||
3. **Dopuszczalność dualna:**
|
||||
$$\lambda_i^* \geq 0$$
|
||||
|
||||
4. **Komplementarność:**
|
||||
$$\lambda_i^* g_i(x^*) = 0 \quad \forall i$$
|
||||
|
||||
```
|
||||
KKT interpretacja geometryczna:
|
||||
|
||||
∇f(x*)
|
||||
↑
|
||||
│ ∇g₁(x*)
|
||||
│ ↗
|
||||
─────●───── (granica ograniczenia)
|
||||
x*
|
||||
|
||||
W optimum: ∇f = -λ∇g (przeciwne kierunki, λ≥0)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Warunki regularności (Constraint Qualification)
|
||||
|
||||
Warunki zapewniające, że KKT są konieczne:
|
||||
|
||||
| Warunek | Definicja |
|
||||
|---------|-----------|
|
||||
| **LICQ** (Linear Independence CQ) | Gradienty aktywnych ograniczeń liniowo niezależne |
|
||||
| **MFCQ** (Mangasarian-Fromovitz CQ) | Słabsza wersja LICQ |
|
||||
| **Slater** | Istnieje punkt ściśle wewnątrz (dla wypukłych) |
|
||||
|
||||
**LICQ:** $\{\nabla g_i(x^*) : g_i(x^*) = 0\} \cup \{\nabla h_j(x^*)\}$ są liniowo niezależne
|
||||
|
||||
---
|
||||
|
||||
### 5. Warunki dostateczne II rzędu
|
||||
|
||||
Jeśli spełnione KKT i dla hesjanu Lagrangianu:
|
||||
$$d^T \nabla_{xx}^2 L(x^*, \lambda^*, \mu^*) d > 0$$
|
||||
|
||||
dla wszystkich $d \neq 0$ spełniających:
|
||||
- $\nabla g_i(x^*)^T d = 0$ dla aktywnych $g_i$
|
||||
- $\nabla h_j(x^*)^T d = 0$ dla wszystkich $h_j$
|
||||
|
||||
To $x^*$ jest **ścisłym minimum lokalnym**.
|
||||
|
||||
---
|
||||
|
||||
### 6. Metody optymalizacji nieliniowej
|
||||
|
||||
#### Metody gradientowe (bez ograniczeń)
|
||||
|
||||
| Metoda | Kierunek | Zbieżność |
|
||||
|--------|----------|-----------|
|
||||
| **Gradient Descent** | $d = -\nabla f$ | Liniowa |
|
||||
| **Newton** | $d = -H^{-1}\nabla f$ | Kwadratowa |
|
||||
| **BFGS** | Quasi-Newton | Superlinearna |
|
||||
| **Conjugate Gradient** | Sprzężone kierunki | Superlinearna |
|
||||
|
||||
```
|
||||
Gradient Descent:
|
||||
x_{k+1} = x_k - α_k ∇f(x_k)
|
||||
|
||||
Newton:
|
||||
x_{k+1} = x_k - [∇²f(x_k)]^{-1} ∇f(x_k)
|
||||
```
|
||||
|
||||
#### Metody z ograniczeniami
|
||||
|
||||
| Metoda | Idea |
|
||||
|--------|------|
|
||||
| **Kary zewnętrznej** | $\min f(x) + \rho \sum \max(0, g_i)^2$ |
|
||||
| **Kary wewnętrznej (Barrier)** | $\min f(x) - \mu \sum \log(-g_i)$ |
|
||||
| **SQP** (Sequential Quadratic Programming) | Iteracyjne rozwiązywanie QP |
|
||||
| **Interior Point** | Barrier + Newton |
|
||||
| **Augmented Lagrangian** | Lagrangian + kara |
|
||||
|
||||
#### SQP - Algorytm
|
||||
|
||||
```
|
||||
Repeat:
|
||||
1. Rozwiąż podproblem QP:
|
||||
min ∇f(x_k)^T d + ½ d^T H_k d
|
||||
s.t. g_i(x_k) + ∇g_i(x_k)^T d ≤ 0
|
||||
h_j(x_k) + ∇h_j(x_k)^T d = 0
|
||||
|
||||
2. x_{k+1} = x_k + α_k d_k
|
||||
|
||||
3. Aktualizuj H_k (BFGS)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Porównanie metod
|
||||
|
||||
| Metoda | Ograniczenia | Złożoność iter. | Zbieżność |
|
||||
|--------|--------------|-----------------|-----------|
|
||||
| **Gradient** | Bez | O(n) | Liniowa |
|
||||
| **Newton** | Bez | O(n³) | Kwadratowa |
|
||||
| **BFGS** | Bez | O(n²) | Superlinearna |
|
||||
| **SQP** | Z | O(n³) per QP | Superlinearna |
|
||||
| **Interior Point** | Z | O(n³) | Polinomialna |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "KKT = Keep Killing Troubles":
|
||||
- **K**ondycja stacjonarności (∇L = 0)
|
||||
- **K**onieczność dopuszczalności (g ≤ 0, h = 0, λ ≥ 0)
|
||||
- **T**rick komplementarności (λg = 0)
|
||||
|
||||
### "Hesjan dodatni = Minimum":
|
||||
$H \succ 0$ → punkt jest minimum (jak miska)
|
||||
|
||||
### "LICQ = Linear Independence":
|
||||
Gradienty aktywnych ograniczeń muszą być liniowo niezależne
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Co oznacza warunek komplementarności λᵢgᵢ = 0?"
|
||||
**Odpowiedź:** Albo ograniczenie nieaktywne ($g_i < 0$, wtedy $\lambda_i = 0$), albo aktywne ($g_i = 0$, wtedy $\lambda_i \geq 0$). Mnożnik niezerowy tylko dla "ciasnych" ograniczeń.
|
||||
|
||||
### Q2: "Kiedy KKT są warunkami dostatecznymi?"
|
||||
**Odpowiedź:** Dla problemów wypukłych (f wypukła, g wypukłe, h liniowe). Wtedy każdy punkt KKT jest globalnym minimum.
|
||||
|
||||
### Q3: "Jaka jest przewaga BFGS nad Newtonem?"
|
||||
**Odpowiedź:** BFGS nie wymaga obliczania hesjanu (tylko gradienty), przybliża hesjan iteracyjnie. O(n²) zamiast O(n³) per iteracja. Bardziej odporny na nieścisłości.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Bez ograniczeń:** $\nabla f = 0$ (konieczny), $H \succ 0$ (dostateczny)
|
||||
2. **Z ograniczeniami:** KKT = stacjonarność + dopuszczalność + komplementarność
|
||||
3. **Regularność:** LICQ, Slater - warunki na poprawność KKT
|
||||
4. **Metody:** Gradient, Newton, BFGS (bez), SQP, Interior Point (z)
|
||||
5. **Wypukłość:** KKT konieczne i dostateczne
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Boyd, Vandenberghe - "Convex Optimization"
|
||||
2. Nocedal, Wright - "Numerical Optimization"
|
||||
3. Bazaraa et al. - "Nonlinear Programming"
|
||||
@ -1,209 +0,0 @@
|
||||
# Pytanie 18: Optymalizacja liniowa i kwadratowa
|
||||
|
||||
## Pytanie
|
||||
**"Omówić metody rozwiązywania zadań liniowych i kwadratowych optymalizacji."**
|
||||
|
||||
Przedmiot: AMO (Analiza i Metody Optymalizacji)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Programowanie liniowe (LP)
|
||||
|
||||
#### Postać standardowa
|
||||
$$\min c^T x$$
|
||||
$$\text{s.t. } Ax = b, \quad x \geq 0$$
|
||||
|
||||
#### Metoda Simplex
|
||||
|
||||
```
|
||||
Idea: Przechodzenie po wierzchołkach wielościanu dopuszczalnego
|
||||
|
||||
c^T x = const
|
||||
↘
|
||||
●───────●
|
||||
/│ /│
|
||||
/ │ / │ Wielościan dopuszczalny
|
||||
●──┼────● │
|
||||
│ ●────┼──●
|
||||
│ / │ /
|
||||
│/ │/
|
||||
●───────● ← optimum (wierzchołek)
|
||||
```
|
||||
|
||||
**Algorytm:**
|
||||
1. Znajdź bazowe rozwiązanie dopuszczalne (BFS)
|
||||
2. Sprawdź optymalność (reduced costs ≥ 0)
|
||||
3. Wybierz zmienną wchodzącą (pivot column)
|
||||
4. Wybierz zmienną wychodzącą (ratio test)
|
||||
5. Wykonaj pivot, powtórz
|
||||
|
||||
**Złożoność:** O(2^n) worst-case, ale praktycznie bardzo szybki
|
||||
|
||||
#### Metoda punktu wewnętrznego (Interior Point)
|
||||
|
||||
```
|
||||
Start wewnątrz wielościanu, zbieżność do optimum przez wnętrze:
|
||||
|
||||
●───────────●
|
||||
/│ /│
|
||||
/ │ ●→●→● / │ Ścieżka centralna
|
||||
●──┼───────● │
|
||||
│ ●───────┼──●
|
||||
│ / │ /
|
||||
│/ │/
|
||||
●──────────● ← optimum
|
||||
```
|
||||
|
||||
**Algorytm Barrier:**
|
||||
$$\min c^T x - \mu \sum_{i} \ln(x_i)$$
|
||||
|
||||
Zmniejszaj μ → 0, rozwiązuj układy Newtona
|
||||
|
||||
**Złożoność:** O(n^3.5 L) - wielomianowa
|
||||
|
||||
#### Porównanie LP
|
||||
|
||||
| Cecha | Simplex | Interior Point |
|
||||
|-------|---------|----------------|
|
||||
| Złożoność teoretyczna | Wykładnicza | Wielomianowa |
|
||||
| Praktyczna wydajność | Bardzo dobra | Dobra dla dużych |
|
||||
| Warm start | Tak | Nie |
|
||||
| Rozwiązanie bazowe | Tak | Nie (wewnętrzne) |
|
||||
|
||||
---
|
||||
|
||||
### 2. Programowanie kwadratowe (QP)
|
||||
|
||||
#### Postać ogólna
|
||||
$$\min \frac{1}{2} x^T Q x + c^T x$$
|
||||
$$\text{s.t. } Ax \leq b, \quad Ex = d$$
|
||||
|
||||
Gdzie Q jest macierzą symetryczną.
|
||||
|
||||
#### Klasyfikacja
|
||||
|
||||
| Q | Typ | Rozwiązywalność |
|
||||
|---|-----|-----------------|
|
||||
| Q ≻ 0 (dodatnio określona) | Wypukły QP | Globalnie jednoznaczne |
|
||||
| Q ⪰ 0 (półdodatnia) | Wypukły QP | Może wiele rozwiązań |
|
||||
| Q nieokreślona | Niewypukły QP | NP-trudny |
|
||||
|
||||
---
|
||||
|
||||
### 3. Metody rozwiązywania QP
|
||||
|
||||
#### Active Set Method
|
||||
|
||||
```
|
||||
Idea: Traktuj aktywne ograniczenia jako równości
|
||||
|
||||
1. Zgadnij zbiór aktywnych ograniczeń W
|
||||
2. Rozwiąż QP z ograniczeniami W jako równości
|
||||
3. Sprawdź:
|
||||
- Czy rozwiązanie dopuszczalne? (jeśli nie: usuń z W)
|
||||
- Czy mnożniki ≥ 0? (jeśli nie: dodaj do W)
|
||||
4. Powtarzaj do zbieżności
|
||||
```
|
||||
|
||||
**Zalety:** Dokładne rozwiązanie, warm start
|
||||
**Wady:** Liczba iteracji zależy od kombinatoryki
|
||||
|
||||
#### Metody punktu wewnętrznego dla QP
|
||||
|
||||
```
|
||||
Barrier problem:
|
||||
min ½x^TQx + c^Tx - μ Σ ln(s_i)
|
||||
s.t. Ax + s = b
|
||||
|
||||
KKT system → rozwiązuj Newton
|
||||
Zmniejszaj μ → 0
|
||||
```
|
||||
|
||||
**Złożoność:** O(n^3) per iteracja, O(√n) iteracji
|
||||
|
||||
#### Gradient Projection Method
|
||||
|
||||
```
|
||||
Dla QP z prostymi ograniczeniami (x ∈ [l, u]):
|
||||
|
||||
1. Kierunek: d = -∇f(x) = -(Qx + c)
|
||||
2. Krok: x_{k+1} = P[x_k + α_k d_k]
|
||||
|
||||
Gdzie P[·] = projekcja na [l, u]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Przypadki szczególne
|
||||
|
||||
#### Least Squares (najmniejsze kwadraty)
|
||||
$$\min \|Ax - b\|_2^2 = \min x^T A^T A x - 2b^T A x + b^T b$$
|
||||
|
||||
**Rozwiązanie:** $(A^T A)x = A^T b$ (równanie normalne)
|
||||
|
||||
#### Support Vector Machine (SVM)
|
||||
$$\min \frac{1}{2}\|w\|^2$$
|
||||
$$\text{s.t. } y_i(w^T x_i + b) \geq 1$$
|
||||
|
||||
→ QP z dodatnio określoną macierzą
|
||||
|
||||
#### Portfolio Optimization (Markowitz)
|
||||
$$\min \frac{1}{2} x^T \Sigma x \quad \text{(ryzyko)}$$
|
||||
$$\text{s.t. } \mu^T x \geq r, \quad \sum x_i = 1, \quad x \geq 0$$
|
||||
|
||||
---
|
||||
|
||||
### 5. Narzędzia
|
||||
|
||||
| Narzędzie | Typ | Metody |
|
||||
|-----------|-----|--------|
|
||||
| **CPLEX** | Komercyjny | Simplex, Barrier, QP |
|
||||
| **Gurobi** | Komercyjny | Simplex, Barrier, QP |
|
||||
| **GLPK** | Open source | Simplex |
|
||||
| **OSQP** | Open source | ADMM dla QP |
|
||||
| **CVXPY** | Python | Interfejs do solverów |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Simplex = Surface walking":
|
||||
Chodzi po wierzchołkach (powierzchni) wielościanu
|
||||
|
||||
### "Interior Point = Inside path":
|
||||
Idzie przez wnętrze do optimum
|
||||
|
||||
### "Q dodatnia = QP wypukły = łatwy":
|
||||
Macierz Q określa trudność problemu
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy Simplex jest lepszy od Interior Point?"
|
||||
**Odpowiedź:** Małe/średnie problemy, warm start (sekwencja podobnych LP), potrzeba rozwiązania bazowego. Interior Point lepszy dla bardzo dużych, rzadkich problemów.
|
||||
|
||||
### Q2: "Co to jest dualność w LP?"
|
||||
**Odpowiedź:** Każdy LP (primal) ma dual. Silna dualność: opt(primal) = opt(dual). Mnożniki Lagrange'a = zmienne dualne. Complementary slackness: x_i > 0 ⟹ ograniczenie dualne aktywne.
|
||||
|
||||
### Q3: "Jak rozwiązać niewypukły QP?"
|
||||
**Odpowiedź:** NP-trudny, metody: Branch & Bound, SDP relaxation, lokalne metody (wiele startów). Brak gwarancji globalnego optimum w czasie wielomianowym.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **LP:** Simplex (wierzchołki), Interior Point (wnętrze)
|
||||
2. **QP wypukły:** Q ⪰ 0, Active Set lub Interior Point
|
||||
3. **QP niewypukły:** NP-trudny
|
||||
4. **Narzędzia:** CPLEX, Gurobi, GLPK, OSQP
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Nocedal, Wright - "Numerical Optimization"
|
||||
2. Boyd, Vandenberghe - "Convex Optimization"
|
||||
3. Bertsimas, Tsitsiklis - "Introduction to Linear Optimization"
|
||||
@ -1,204 +0,0 @@
|
||||
# Pytanie 19: MFCC i LPC - parametryzacja sygnału mowy
|
||||
|
||||
## Pytanie
|
||||
**"Przedstawić metody wyznaczania cech (parametryzacji) sygnału mowy: MFCC (cechy mel-cepstralne) i LPC (cechy według liniowej predykcji)."**
|
||||
|
||||
Przedmiot: EASAR (Elementy Automatycznego Sterowania i Rozpoznawania)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Cel parametryzacji mowy
|
||||
|
||||
- **Redukcja wymiarowości:** 16kHz × 16bit → ~13-40 cech/ramkę
|
||||
- **Ekstrakcja informacji fonetycznej**
|
||||
- **Usunięcie informacji mówcy** (częściowo)
|
||||
- **Reprezentacja kompaktowa** dla modeli (HMM, DNN)
|
||||
|
||||
---
|
||||
|
||||
### 2. MFCC (Mel-Frequency Cepstral Coefficients)
|
||||
|
||||
#### Pipeline MFCC
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Sygnał mowy │
|
||||
│ ↓ │
|
||||
│ [Pre-emphasis] ──→ y[n] = x[n] - α·x[n-1], α ≈ 0.97 │
|
||||
│ ↓ │
|
||||
│ [Ramkowanie] ──→ 20-30ms ramki, 10ms przesunięcie │
|
||||
│ ↓ │
|
||||
│ [Okienkowanie] ──→ Hamming: w[n] = 0.54 - 0.46cos(2πn/N) │
|
||||
│ ↓ │
|
||||
│ [FFT] ──→ Widmo mocy |X(k)|² │
|
||||
│ ↓ │
|
||||
│ [Filtracja Mel] ──→ Bank filtrów trójkątnych (26-40) │
|
||||
│ ↓ │
|
||||
│ [Log] ──→ log(energia w pasmach) │
|
||||
│ ↓ │
|
||||
│ [DCT] ──→ Discrete Cosine Transform │
|
||||
│ ↓ │
|
||||
│ MFCC (12-13 współczynników) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Skala Mel
|
||||
|
||||
```
|
||||
Percepcja częstotliwości przez człowieka jest nieliniowa:
|
||||
|
||||
mel(f) = 2595 · log₁₀(1 + f/700)
|
||||
|
||||
Hz: 0 500 1000 2000 4000 8000
|
||||
Mel: 0 607 1000 1500 2146 2840
|
||||
|
||||
Bank filtrów Mel:
|
||||
╱╲ ╱╲ ╱╲ ╱╲ ╱╲ ╱╲
|
||||
╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲
|
||||
╱ ╳ ╳ ╳ ╳ ╳ ╲
|
||||
──────────────────────────────────→ f
|
||||
0 8000 Hz
|
||||
|
||||
Filtry gęściej w niskich częstotliwościach
|
||||
```
|
||||
|
||||
#### Cechy dynamiczne (Delta, Delta-Delta)
|
||||
|
||||
```
|
||||
Δ MFCC (velocity):
|
||||
Δc[t] = Σ_{n=1}^{N} n·(c[t+n] - c[t-n]) / (2·Σ n²)
|
||||
|
||||
ΔΔ MFCC (acceleration):
|
||||
ΔΔc[t] = Δ(Δc[t])
|
||||
|
||||
Typowy wektor: 13 MFCC + 13 Δ + 13 ΔΔ = 39 cech
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. LPC (Linear Predictive Coding)
|
||||
|
||||
#### Idea
|
||||
|
||||
Model mowy jako filtr pobudzany:
|
||||
- **Dźwięczne:** pobudzenie okresowe (struny głosowe)
|
||||
- **Bezdźwięczne:** pobudzenie szumowe
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ Pobudzenie e[n] Filtr H(z) Sygnał mowy s[n] │
|
||||
│ ┌───┐ ┌─────────┐ │
|
||||
│ ──→ │ G │ ──────→ │ 1/A(z) │ ──────→ │
|
||||
│ └───┘ └─────────┘ │
|
||||
│ │
|
||||
│ gdzie A(z) = 1 - Σ_{k=1}^{p} a_k z^{-k} │
|
||||
│ │
|
||||
│ Predykcja: ŝ[n] = Σ_{k=1}^{p} a_k s[n-k] │
|
||||
│ Błąd: e[n] = s[n] - ŝ[n] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Wyznaczanie współczynników LPC
|
||||
|
||||
**Metoda autokorelacji (Levinson-Durbin):**
|
||||
|
||||
```
|
||||
1. Oblicz autokorelację: R[k] = Σ s[n]·s[n+k]
|
||||
|
||||
2. Algorytm Levinsona-Durbina:
|
||||
E₀ = R[0]
|
||||
for i = 1 to p:
|
||||
k_i = (R[i] - Σ_{j=1}^{i-1} a_{i-1,j}·R[i-j]) / E_{i-1}
|
||||
a_{i,i} = k_i
|
||||
for j = 1 to i-1:
|
||||
a_{i,j} = a_{i-1,j} - k_i·a_{i-1,i-j}
|
||||
E_i = (1 - k_i²)·E_{i-1}
|
||||
|
||||
3. Wynik: współczynniki a₁, a₂, ..., a_p
|
||||
```
|
||||
|
||||
**Typowo:** p = 10-16 dla mowy (8kHz), p = 16-20 (16kHz)
|
||||
|
||||
#### Parametry pochodne LPC
|
||||
|
||||
| Parametr | Opis |
|
||||
|----------|------|
|
||||
| **Współczynniki LPC** | a₁, ..., a_p |
|
||||
| **PARCOR (k)** | Współczynniki odbicia |
|
||||
| **LSF/LSP** | Line Spectral Frequencies |
|
||||
| **Cepstrum LPC** | Transformacja współczynników |
|
||||
|
||||
---
|
||||
|
||||
### 4. Porównanie MFCC vs LPC
|
||||
|
||||
| Cecha | MFCC | LPC |
|
||||
|-------|------|-----|
|
||||
| **Podstawa** | Percepcja słuchowa | Model produkcji mowy |
|
||||
| **Filtracja** | Bank filtrów Mel | Model all-pole |
|
||||
| **Wymiarowość** | 12-13 + delty | 10-20 |
|
||||
| **Zastosowanie** | Rozpoznawanie mowy | Kodowanie, synteza |
|
||||
| **Korelacja** | Niska (DCT dekoreluje) | Wysoka |
|
||||
| **Interpolacja** | Trudna | Łatwa (LSF) |
|
||||
|
||||
---
|
||||
|
||||
### 5. Rozszerzenia
|
||||
|
||||
#### PLP (Perceptual Linear Prediction)
|
||||
Łączy LPC z percepcją słuchową:
|
||||
- Filtracja w skali Bark
|
||||
- Krzywa równej głośności
|
||||
- Kompresja intensity-loudness
|
||||
|
||||
#### Filter Banks (dla DNN)
|
||||
Nowoczesne podejście:
|
||||
- Log Mel filterbanks (bez DCT)
|
||||
- 40-80 filtrów
|
||||
- DNN uczy się własnych cech
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "MFCC = Mel + FFT + Cepstrum":
|
||||
Skala Mel → FFT → Log → DCT
|
||||
|
||||
### "LPC = Linear Prediction Coefficients":
|
||||
Przewiduj próbkę z p poprzednich
|
||||
|
||||
### "39 = 13 + 13 + 13":
|
||||
MFCC + Delta + Delta-Delta
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Dlaczego używamy skali Mel?"
|
||||
**Odpowiedź:** Percepcja częstotliwości przez człowieka jest logarytmiczna. Różnica 100-200Hz jest bardziej słyszalna niż 4000-4100Hz. Mel modeluje tę nieliniowość.
|
||||
|
||||
### Q2: "Co to jest cepstrum?"
|
||||
**Odpowiedź:** "Widmo widma" - IFFT(log(|FFT(x)|)). Rozdziela pobudzenie (pitch) od filtra (formantów). MFCC używa DCT zamiast IFFT dla lepszych właściwości.
|
||||
|
||||
### Q3: "Dlaczego LPC jest używane w kodowaniu mowy (CELP)?"
|
||||
**Odpowiedź:** Kompaktowa reprezentacja (~10 współczynników). Łatwa interpolacja (LSF). Efektywna synteza (filtr IIR). Standard w GSM, VoIP.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **MFCC:** Pre-emphasis → Ramki → FFT → Mel → Log → DCT
|
||||
2. **LPC:** Model all-pole, predykcja liniowa, Levinson-Durbin
|
||||
3. **Wymiary:** MFCC ~39, LPC ~10-20
|
||||
4. **MFCC** dla rozpoznawania, **LPC** dla kodowania/syntezy
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Rabiner, Schafer - "Digital Processing of Speech Signals"
|
||||
2. Huang et al. - "Spoken Language Processing"
|
||||
3. HTK Book - Feature extraction
|
||||
@ -1,221 +0,0 @@
|
||||
# Pytanie 20: Rozpoznawanie mowy - HMM vs Deep Learning
|
||||
|
||||
## Pytanie
|
||||
**"Przedstawić klasyczną metodę rozpoznawania mowy opartą o HMM (Ukryte Modele Markowa). Porównać ją z metodami korzystającymi z głębokich sieci neuronowych."**
|
||||
|
||||
Przedmiot: EASAR (Elementy Automatycznego Sterowania i Rozpoznawania)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. System rozpoznawania mowy - architektura
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Sygnał audio │
|
||||
│ ↓ │
|
||||
│ [Ekstrakcja cech] ──→ MFCC/Filterbanks │
|
||||
│ ↓ │
|
||||
│ [Model akustyczny] ──→ HMM / DNN / Hybrid │
|
||||
│ ↓ │
|
||||
│ [Model językowy] ──→ N-gram / RNN-LM │
|
||||
│ ↓ │
|
||||
│ [Dekoder] ──→ Wyszukiwanie najlepszej hipotezy │
|
||||
│ ↓ │
|
||||
│ Tekst │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. HMM (Hidden Markov Model) - klasyczne podejście
|
||||
|
||||
#### Struktura HMM dla fonemu
|
||||
|
||||
```
|
||||
a₁₂ a₂₃ a₃₄
|
||||
┌────────→ ┌────────→ ┌────────→
|
||||
│ │ │
|
||||
┌─┴─┐ ┌─┴─┐ ┌─┴─┐ ┌───┐
|
||||
│ 1 │ │ 2 │ │ 3 │ │ 4 │
|
||||
│ │ │ │ │ │ │END│
|
||||
└─┬─┘ └─┬─┘ └─┬─┘ └───┘
|
||||
│ │ │
|
||||
└──────────┴──────────┘
|
||||
a₁₁ a₂₂ a₃₃ (self-loops)
|
||||
|
||||
Każdy stan emituje obserwacje (MFCC) według rozkładu GMM:
|
||||
b_j(o) = Σ_m c_{jm} N(o; μ_{jm}, Σ_{jm})
|
||||
```
|
||||
|
||||
#### Parametry HMM
|
||||
|
||||
| Symbol | Opis |
|
||||
|--------|------|
|
||||
| **A** | Macierz przejść (a_ij) |
|
||||
| **B** | Rozkłady emisji (GMM) |
|
||||
| **π** | Rozkład początkowy |
|
||||
|
||||
#### Trzy problemy HMM
|
||||
|
||||
| Problem | Algorytm | Zastosowanie |
|
||||
|---------|----------|--------------|
|
||||
| **Ewaluacja:** P(O\|λ) | Forward-Backward | Scoring |
|
||||
| **Dekodowanie:** argmax P(Q\|O) | Viterbi | Rozpoznawanie |
|
||||
| **Uczenie:** argmax P(O\|λ) | Baum-Welch (EM) | Trening |
|
||||
|
||||
#### Algorytm Viterbi
|
||||
|
||||
```
|
||||
Znajdź najbardziej prawdopodobną sekwencję stanów:
|
||||
|
||||
α_t(j) = max_{i} [α_{t-1}(i) · a_{ij}] · b_j(o_t)
|
||||
|
||||
Backtrace: ψ_t(j) = argmax_{i} [α_{t-1}(i) · a_{ij}]
|
||||
|
||||
t=1 t=2 t=3 t=4
|
||||
s=1 ●──────●──────●──────●
|
||||
│╲ │╲ │╲ │
|
||||
s=2 ●──────●──────●──────●
|
||||
│╲ │╲ │╲ │
|
||||
s=3 ●──────●──────●──────●
|
||||
Viterbi trellis
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Deep Learning w rozpoznawaniu mowy
|
||||
|
||||
#### DNN-HMM Hybrid (2012+)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Klasyczne GMM-HMM: │
|
||||
│ Cechy MFCC → GMM → P(o|stan) → HMM → dekodowanie │
|
||||
│ │
|
||||
│ Hybrid DNN-HMM: │
|
||||
│ Cechy → DNN → P(stan|o) → P(o|stan) = P(stan|o)/P(stan) │
|
||||
│ ↓ │
|
||||
│ HMM → dekodowanie │
|
||||
│ │
|
||||
│ DNN zastępuje GMM jako model emisji! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### End-to-End Models (2014+)
|
||||
|
||||
```
|
||||
CTC (Connectionist Temporal Classification):
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Audio → [LSTM/Transformer] → P(y_t|x) → CTC Loss → Tekst │
|
||||
│ │
|
||||
│ CTC pozwala na różne wyrównania: │
|
||||
│ "h-e-l-l-o" = "hh-ee-ll-lo" = "-h-e-l-l-o-" │
|
||||
│ (blank = '-') │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
|
||||
Attention-based (Seq2Seq):
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Audio → [Encoder] → [Attention] → [Decoder] → Tekst │
|
||||
│ ↓ │
|
||||
│ Wyrównanie uczone │
|
||||
│ │
|
||||
│ Modele: LAS (Listen Attend Spell), Transformer ASR │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Transformer ASR (2020+)
|
||||
|
||||
```
|
||||
Whisper, Wav2Vec 2.0, Conformer:
|
||||
|
||||
Audio waveform
|
||||
↓
|
||||
[CNN Feature Encoder]
|
||||
↓
|
||||
[Transformer Encoder] × N
|
||||
↓
|
||||
[CTC / Attention Decoder]
|
||||
↓
|
||||
Tekst
|
||||
|
||||
Pre-training: Self-supervised na dużych danych
|
||||
Fine-tuning: Supervised na labeled data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Porównanie HMM vs DNN
|
||||
|
||||
| Aspekt | GMM-HMM | DNN-HMM | End-to-End |
|
||||
|--------|---------|---------|------------|
|
||||
| **Model akustyczny** | GMM | DNN | DNN |
|
||||
| **Model czasowy** | HMM | HMM | CTC/Attention |
|
||||
| **Wyrównanie** | Viterbi | Viterbi | Uczone/CTC |
|
||||
| **Trening** | EM (Baum-Welch) | Backprop | Backprop |
|
||||
| **Interpretowalność** | Wysoka | Średnia | Niska |
|
||||
| **Dane treningowe** | Małe | Średnie | Duże |
|
||||
| **WER (Word Error Rate)** | ~15-20% | ~8-12% | ~3-5% |
|
||||
| **Latencja** | Niska | Średnia | Zmienna |
|
||||
|
||||
---
|
||||
|
||||
### 5. Ewolucja wydajności
|
||||
|
||||
```
|
||||
WER na Switchboard (telefon):
|
||||
|
||||
Rok Model WER
|
||||
2010 GMM-HMM ~18%
|
||||
2012 DNN-HMM ~12%
|
||||
2015 LSTM-HMM ~8%
|
||||
2017 LAS (Seq2Seq) ~6%
|
||||
2020 Conformer ~4%
|
||||
2023 Whisper Large ~3%
|
||||
Poziom ludzki ~4%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "HMM = Hidden states + Markov + Model":
|
||||
Ukryte stany, przejścia markowskie, emisje obserwacji
|
||||
|
||||
### "Viterbi = Find best path":
|
||||
Dynamiczne programowanie dla najlepszej ścieżki
|
||||
|
||||
### "CTC = Collapse The Characters":
|
||||
Usuwa powtórzenia i blanki → tekst
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Co to jest forced alignment?"
|
||||
**Odpowiedź:** Viterbi z ograniczeniem do znanej transkrypcji. Wyznacza granice czasowe fonemów/słów. Używane do tworzenia danych treningowych i TTS.
|
||||
|
||||
### Q2: "Dlaczego DNN jest lepszy od GMM?"
|
||||
**Odpowiedź:** DNN może modelować złożone, nieliniowe zależności. GMM zakłada mieszaninę Gaussianów (często niewystarczające). DNN korzysta z kontekstu (wiele ramek na wejściu).
|
||||
|
||||
### Q3: "Co to jest language model fusion?"
|
||||
**Odpowiedź:** Łączenie modelu akustycznego z językowym: P(W|O) ∝ P(O|W)·P(W)^α. Shallow fusion (podczas dekodowania) lub deep fusion (wspólny trening).
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **HMM:** Stany ukryte, GMM emisje, Viterbi dekodowanie
|
||||
2. **DNN-HMM Hybrid:** DNN zastępuje GMM, HMM dla czasu
|
||||
3. **End-to-End:** CTC lub Attention, bez HMM
|
||||
4. **Trend:** Większe modele, więcej danych, mniej inżynierii cech
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Rabiner - "A Tutorial on HMM"
|
||||
2. Hinton et al. - "Deep Neural Networks for Acoustic Modeling" (2012)
|
||||
3. Graves et al. - "CTC" (2006)
|
||||
4. Chan et al. - "LAS" (2016)
|
||||
@ -1,247 +0,0 @@
|
||||
# Pytanie 21: Agent upostaciowiony w specyfikacji sterowników robotów
|
||||
|
||||
## Pytanie
|
||||
**"Jak wykorzystuje się agenta upostaciowionego do specyfikacji sterowników robotów?"**
|
||||
|
||||
Przedmiot: ERPM (Elementy Robotyki i Projektowania Mechatronicznego)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Agent upostaciowiony (Embodied Agent)
|
||||
|
||||
#### Definicja
|
||||
|
||||
**Agent upostaciowiony** = agent posiadający fizyczne ciało, osadzony w rzeczywistym środowisku, zdolny do:
|
||||
- **Percepcji** poprzez sensory
|
||||
- **Działania** poprzez efektory
|
||||
- **Interakcji** ze środowiskiem
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ŚRODOWISKO FIZYCZNE │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────┐ │
|
||||
│ │ ROBOT (Agent upostaciowiony) │ │
|
||||
│ │ │ │
|
||||
│ │ Sensory Sterownik Efektory │ │
|
||||
│ │ ┌─────┐ ┌─────────┐ ┌─────┐ │ │
|
||||
│ │ │Kamera│───────→│ Agent │─────→│Motor│ │ │
|
||||
│ │ │LIDAR │ │ Logic │ │Grip │ │ │
|
||||
│ │ │IMU │ │ (BDI) │ │Servo│ │ │
|
||||
│ │ └─────┘ └─────────┘ └─────┘ │ │
|
||||
│ │ ↑ ↓ │ │
|
||||
│ │ └────────────────────────────────┘ │ │
|
||||
│ │ Sprzężenie zwrotne │ │
|
||||
│ └───────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Specyfikacja sterownika robota
|
||||
|
||||
#### Architektura agentowa sterownika
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WARSTWA DELIBERACYJNA (Agent BDI) │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Beliefs: mapa, pozycja, stan zadania │ │
|
||||
│ │ Desires: cel nawigacji, zadanie manipulacji │ │
|
||||
│ │ Intentions: aktualny plan działania │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ WARSTWA WYKONAWCZA (Reactive behaviors) │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Unikanie kolizji, śledzenie ścieżki, chwytanie │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ WARSTWA SPRZĘTOWA (HAL) │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Sterowniki silników, protokoły sensorów │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Formalny model agenta
|
||||
|
||||
#### Cykl percepcja-akcja
|
||||
|
||||
```
|
||||
Agent: Environment → Action
|
||||
Agent: Percept* → Action (historia percepcji)
|
||||
|
||||
Formalnie:
|
||||
see: E → P (funkcja percepcji)
|
||||
action: P* → A (funkcja decyzyjna)
|
||||
next: E × A → E (funkcja przejścia środowiska)
|
||||
```
|
||||
|
||||
#### Specyfikacja w logice temporalnej
|
||||
|
||||
```
|
||||
Przykład specyfikacji bezpieczeństwa:
|
||||
□(obstacle_detected → ¬move_forward)
|
||||
"Zawsze gdy wykryto przeszkodę, nie jedź do przodu"
|
||||
|
||||
Specyfikacja żywotności:
|
||||
◇(at_goal)
|
||||
"Kiedyś robot dotrze do celu"
|
||||
|
||||
Specyfikacja reaktywności:
|
||||
□(request_pickup → ◇holding_object)
|
||||
"Zawsze gdy jest żądanie podniesienia, kiedyś obiekt będzie trzymany"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Zastosowanie w ROS (Robot Operating System)
|
||||
|
||||
#### Agent jako węzeł ROS
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ROS Architecture │
|
||||
│ │
|
||||
│ /sensor_node ──topic──→ /agent_node ──topic──→ /motor_node │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ [Publikuje] [Subskrybuje & [Wykonuje] │
|
||||
│ /scan Publikuje] /cmd_vel │
|
||||
│ /camera /plan │
|
||||
│ /odom /status │
|
||||
│ │
|
||||
│ Agent node implementuje: │
|
||||
│ - Pętlę kontrolną (control loop) │
|
||||
│ - Stan wewnętrzny (beliefs) │
|
||||
│ - Planowanie (intentions) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Behavior Trees (BT)
|
||||
|
||||
```
|
||||
Nowoczesna specyfikacja zachowań robota:
|
||||
|
||||
[Selector ?]
|
||||
/ | \
|
||||
/ | \
|
||||
[Seq→] [Seq→] [Idle]
|
||||
/ \ |
|
||||
/ \ |
|
||||
[Check] [Pick] [Navigate]
|
||||
|
||||
Węzły:
|
||||
- Sequence (→): wykonaj wszystkie po kolei
|
||||
- Selector (?): wykonaj pierwszy sukces
|
||||
- Action: atomowa akcja
|
||||
- Condition: sprawdzenie warunku
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Hybrydowa architektura 3T
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ THREE-TIER (3T) Architecture │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ PLANNER (deliberation) │ │
|
||||
│ │ - Długoterminowe planowanie │ │
|
||||
│ │ - Rozumowanie symboliczne │ │
|
||||
│ │ Czas: sekundy - minuty │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓↑ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ SEQUENCER (executive) │ │
|
||||
│ │ - Wybór zachowań, nadzór wykonania │ │
|
||||
│ │ - Finite State Machine / Behavior Tree │ │
|
||||
│ │ Czas: 100ms - sekundy │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓↑ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ CONTROLLER (reactive) │ │
|
||||
│ │ - Pętle PID, unikanie kolizji │ │
|
||||
│ │ - Bezpośrednia reakcja sensor → motor │ │
|
||||
│ │ Czas: ms │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Korzyści podejścia agentowego
|
||||
|
||||
| Korzyść | Opis |
|
||||
|---------|------|
|
||||
| **Modularność** | Rozdzielenie percepcji, decyzji, akcji |
|
||||
| **Abstrakcja** | Ukrycie szczegółów sprzętu |
|
||||
| **Autonomia** | Robot sam decyduje o działaniach |
|
||||
| **Reużywalność** | Zachowania przenośne między platformami |
|
||||
| **Weryfikowalność** | Formalna specyfikacja → model checking |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Agent = See-Think-Act":
|
||||
Percepcja → Deliberacja → Akcja
|
||||
|
||||
### "3T = Plan-Sequence-Control":
|
||||
Trzy warstwy od abstrakcji do sprzętu
|
||||
|
||||
### "BDI w robocie":
|
||||
- **B**eliefs = mapa, pozycja
|
||||
- **D**esires = cel nawigacji
|
||||
- **I**ntentions = plan ruchu
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Czym różni się agent reaktywny od deliberatywnego?"
|
||||
**Odpowiedź:** Reaktywny: bezpośrednia reakcja sensor→akcja (np. unikanie kolizji), bez planowania. Deliberatywny: model świata, planowanie, cel. Hybryda łączy oba.
|
||||
|
||||
### Q2: "Co to jest subsumption architecture?"
|
||||
**Odpowiedź:** Architektura Brooksa - warstwy zachowań, wyższe mogą "nadpisać" niższe. Bez centralnego modelu świata. Skuteczna dla prostych robotów mobilnych.
|
||||
|
||||
### Q3: "Jak weryfikować poprawność sterownika agentowego?"
|
||||
**Odpowiedź:** Model checking (SPIN, NuSMV), symulacja (Gazebo), formalna specyfikacja (LTL, CTL), testy jednostkowe zachowań, testy integracyjne w symulacji przed wdrożeniem na sprzęt.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Agent upostaciowiony** = ciało + sensory + efektory + środowisko
|
||||
2. **BDI** dla deliberacji, reaktywność dla bezpieczeństwa
|
||||
3. **3T Architecture:** Planner → Sequencer → Controller
|
||||
4. **Behavior Trees** nowoczesna specyfikacja zachowań➜ utils (main) ✗ git commit -m "feat: more aggressive android script"
|
||||
Running auto-fixers and shell_check before committing...
|
||||
Auto-fixing 3 shell file(s)...
|
||||
→ Running shfmt...
|
||||
✓ Auto-fixes applied and staged
|
||||
Running shell_check validation...
|
||||
|
||||
In scripts/utils/android_guardian/post-fs-data.sh line 5:
|
||||
MODULE_DIR="/data/adb/modules/android_guardian"
|
||||
^--------^ SC2034 (warning): MODULE_DIR appears unused. Verify use (or export if used externally).
|
||||
|
||||
For more information:
|
||||
https://www.shellcheck.net/wiki/SC2034 -- MODULE_DIR appears unused. Verify...
|
||||
|
||||
Commit aborted: shellcheck found issues.
|
||||
Fix the remaining problems and retry the commit.
|
||||
5. **Korzyści:** modularność, abstrakcja, weryfikowalność
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Wooldridge - "Introduction to MultiAgent Systems"
|
||||
2. Siciliano, Khatib - "Springer Handbook of Robotics"
|
||||
3. Gat - "Three-Layer Architectures"
|
||||
4. ROS Documentation - ros.org
|
||||
@ -1,254 +0,0 @@
|
||||
# Pytanie 22: Języki programowania robotów
|
||||
|
||||
## Pytanie
|
||||
**"Omówić specjalizowane języki programowania robotów. Uwypuklić ich klasyfikację."**
|
||||
|
||||
Przedmiot: ERPM (Elementy Robotyki i Projektowania Mechatronicznego)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Klasyfikacja języków programowania robotów
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ JĘZYKI PROGRAMOWANIA ROBOTÓW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ POZIOM ABSTRAKCJI: │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ TASK-LEVEL (Zadaniowy) │ │
|
||||
│ │ "Podnieś obiekt A i połóż na B" │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ ROBOT-LEVEL (Obiektowy) │ │
|
||||
│ │ move_to(position), grasp(), release() │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ MOTION-LEVEL (Ruchowy) │ │
|
||||
│ │ Trajektorie, interpolacja, kinematyka │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ SERVO-LEVEL (Napędowy) │ │
|
||||
│ │ Sterowanie silnikami, PID, momenty │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Klasyfikacja wg metody programowania
|
||||
|
||||
| Metoda | Opis | Przykłady |
|
||||
|--------|------|-----------|
|
||||
| **Online (Teach-in)** | Programowanie przez demonstrację | Pendant, prowadzenie ręczne |
|
||||
| **Offline** | Programowanie bez robota | Symulacja, CAD/CAM |
|
||||
| **Tekstowe** | Kod źródłowy | RAPID, KRL, Karel |
|
||||
| **Graficzne** | Bloki, flowcharty | Blockly, ROBOGUIDE |
|
||||
|
||||
---
|
||||
|
||||
### 3. Języki producentów robotów przemysłowych
|
||||
|
||||
#### RAPID (ABB)
|
||||
|
||||
```rapid
|
||||
MODULE MainModule
|
||||
PROC main()
|
||||
MoveJ pHome, v1000, z50, tool1;
|
||||
MoveL pPick, v500, fine, tool1;
|
||||
GripClose;
|
||||
MoveL pPlace, v500, fine, tool1;
|
||||
GripOpen;
|
||||
ENDPROC
|
||||
ENDMODULE
|
||||
|
||||
! MoveJ = ruch w przestrzeni złączy (Joint)
|
||||
! MoveL = ruch liniowy (Linear)
|
||||
! v500 = prędkość 500 mm/s
|
||||
! fine/z50 = dokładność (fine = dokładnie)
|
||||
```
|
||||
|
||||
#### KRL - KUKA Robot Language
|
||||
|
||||
```krl
|
||||
DEF Pick_and_Place()
|
||||
PTP HOME
|
||||
LIN pPick
|
||||
GripperClose()
|
||||
LIN pPlace
|
||||
GripperOpen()
|
||||
PTP HOME
|
||||
END
|
||||
|
||||
; PTP = Point-to-Point (ruch złączowy)
|
||||
; LIN = ruch liniowy
|
||||
; CIRC = ruch kołowy
|
||||
```
|
||||
|
||||
#### Karel (FANUC)
|
||||
|
||||
```karel
|
||||
PROGRAM pick_place
|
||||
BEGIN
|
||||
MOVE TO home_pos
|
||||
MOVE TO pick_pos
|
||||
CLOSE HAND 1
|
||||
MOVE TO place_pos
|
||||
OPEN HAND 1
|
||||
END pick_place
|
||||
```
|
||||
|
||||
#### PDL2 (Comau)
|
||||
```pdl2
|
||||
PROGRAM main
|
||||
BEGIN
|
||||
MOVE TO home_jnt
|
||||
MOVE LINEAR TO pick_point
|
||||
$DOUT[1] := ON -- gripper
|
||||
MOVE LINEAR TO place_point
|
||||
$DOUT[1] := OFF
|
||||
END main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Porównanie języków producentów
|
||||
|
||||
| Cecha | RAPID (ABB) | KRL (KUKA) | Karel (FANUC) |
|
||||
|-------|-------------|------------|---------------|
|
||||
| **Paradygmat** | Proceduralny | Proceduralny | Proceduralny |
|
||||
| **Typy ruchów** | MoveJ, MoveL, MoveC | PTP, LIN, CIRC | MOVE TO |
|
||||
| **Zmienne** | VAR, PERS, CONST | DECL | VAR |
|
||||
| **I/O** | SetDO, WaitDI | $OUT[], $IN[] | DOUT[], DIN[] |
|
||||
| **Wielozadaniowość** | Tak (TASK) | Tak (SUBMIT) | Tak (TASK) |
|
||||
|
||||
---
|
||||
|
||||
### 5. Języki uniwersalne i frameworki
|
||||
|
||||
#### ROS (Robot Operating System)
|
||||
|
||||
```python
|
||||
# Python + rospy
|
||||
import rospy
|
||||
from geometry_msgs.msg import Twist
|
||||
|
||||
rospy.init_node('robot_controller')
|
||||
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
|
||||
|
||||
twist = Twist()
|
||||
twist.linear.x = 0.5
|
||||
twist.angular.z = 0.1
|
||||
pub.publish(twist)
|
||||
```
|
||||
|
||||
#### MoveIt (ROS)
|
||||
|
||||
```python
|
||||
# Planowanie ruchu manipulatora
|
||||
import moveit_commander
|
||||
|
||||
move_group = moveit_commander.MoveGroupCommander("arm")
|
||||
move_group.set_pose_target(target_pose)
|
||||
plan = move_group.go(wait=True)
|
||||
```
|
||||
|
||||
#### Orocos / RTT
|
||||
|
||||
```cpp
|
||||
// Real-Time Toolkit - C++
|
||||
class MyComponent : public RTT::TaskContext {
|
||||
void updateHook() {
|
||||
// Pętla sterowania (deterministyczna)
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Języki graficzne
|
||||
|
||||
| Narzędzie | Producent | Opis |
|
||||
|-----------|-----------|------|
|
||||
| **RobotStudio** | ABB | RAPID + symulacja 3D |
|
||||
| **KUKA.Sim** | KUKA | KRL + symulacja |
|
||||
| **ROBOGUIDE** | FANUC | Karel + symulacja |
|
||||
| **Blockly** | Google | Programowanie wizualne (edukacja) |
|
||||
| **Scratch for Robots** | MIT | Edukacja, LEGO, mBot |
|
||||
|
||||
---
|
||||
|
||||
### 7. Klasyfikacja wg poziomu abstrakcji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Task-Level: │
|
||||
│ "Złóż produkt X z części A, B, C" │
|
||||
│ → Planowanie automatyczne, AI │
|
||||
│ Przykłady: STRIPS, PDDL, Behavior Trees │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Robot-Level: │
|
||||
│ move_to(), pick(), place(), wait() │
|
||||
│ → RAPID, KRL, Karel, Python+ROS │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Motion-Level: │
|
||||
│ Trajektorie, splajny, kinematyka odwrotna │
|
||||
│ → MoveIt, OMPL, IKFast │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Servo-Level: │
|
||||
│ PID, sterowanie momentem, prądem │
|
||||
│ → C/C++, FPGA, PLC (Ladder, ST) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "RAPID = Robot Application Programming in Data":
|
||||
Język ABB - MoveJ, MoveL, MoveC
|
||||
|
||||
### "KRL = KUKA Robot Language":
|
||||
PTP, LIN, CIRC
|
||||
|
||||
### "ROS = Robot Operating System":
|
||||
Middleware - topics, services, actions
|
||||
|
||||
### "Od zadania do serwa: T-R-M-S":
|
||||
Task → Robot → Motion → Servo
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Czym różni się ruch PTP od LIN?"
|
||||
**Odpowiedź:** PTP (Point-to-Point) = ruch w przestrzeni złączy, najszybszy ale trajektoria TCP nieprzewidywalna. LIN (Linear) = ruch liniowy TCP, wolniejszy ale precyzyjna ścieżka. LIN wymaga rozwiązania kinematyki odwrotnej w każdym punkcie.
|
||||
|
||||
### Q2: "Dlaczego każdy producent ma własny język?"
|
||||
**Odpowiedź:** Historyczne (lata 80-90), integracja ze sterownikiem, optymalizacja dla konkretnego sprzętu, vendor lock-in. ROS próbuje to ujednolicić, ale nie dla real-time.
|
||||
|
||||
### Q3: "Co to jest Teach Pendant?"
|
||||
**Odpowiedź:** Przenośny panel do programowania online. Przyciski ruchu (jog), zapis punktów, edycja programu. Tryb manualny (bezpieczny) vs automatyczny.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Klasyfikacja:** Online/Offline, Task/Robot/Motion/Servo level
|
||||
2. **Producenci:** RAPID (ABB), KRL (KUKA), Karel (FANUC)
|
||||
3. **Uniwersalne:** ROS + Python/C++, MoveIt
|
||||
4. **Graficzne:** RobotStudio, ROBOGUIDE, Blockly
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Siciliano, Khatib - "Springer Handbook of Robotics"
|
||||
2. ABB RAPID Reference Manual
|
||||
3. KUKA KRL Documentation
|
||||
4. ROS Wiki - ros.org
|
||||
@ -1,248 +0,0 @@
|
||||
# Pytanie 23: Zegary logiczne i wektory stempli czasowych
|
||||
|
||||
## Pytanie
|
||||
**"Przedstawić koncepcję i przeznaczenie zegarów logicznych i wektorów stempli czasowych."**
|
||||
|
||||
Przedmiot: ERSMS (Elementy Rozproszonych Systemów i Middleware'u Sieciowego)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Problem czasu w systemach rozproszonych
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Brak globalnego zegara: │
|
||||
│ │
|
||||
│ Node A: ──●────────●────────●──→ czas lokalny A │
|
||||
│ e1 e2 e3 │
|
||||
│ │↘ │
|
||||
│ │ ↘ msg │
|
||||
│ │ ↘ │
|
||||
│ Node B: ────●─────────────●───→ czas lokalny B │
|
||||
│ e4 e5 │
|
||||
│ │
|
||||
│ Pytanie: Czy e2 było przed e5, czy po? │
|
||||
│ Zegary fizyczne: drift, synchronizacja niedokładna │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Problem:** Nie możemy polegać na zegarach fizycznych - drift, opóźnienia sieciowe, brak atomowej synchronizacji.
|
||||
|
||||
---
|
||||
|
||||
### 2. Relacja "happened-before" (Lamport)
|
||||
|
||||
#### Definicja (→)
|
||||
|
||||
Zdarzenie **a** happened-before **b** (a → b) jeśli:
|
||||
1. **a** i **b** są w tym samym procesie i **a** występuje przed **b**
|
||||
2. **a** to wysłanie wiadomości, **b** to jej odbiór
|
||||
3. Przechodniość: a → c ∧ c → b ⟹ a → b
|
||||
|
||||
```
|
||||
P1: ─●─────●─────────●───→
|
||||
a b d
|
||||
│↘
|
||||
│ ↘ m1
|
||||
│ ↘
|
||||
P2: ───────────●─────●───→
|
||||
c e
|
||||
|
||||
a → b (ten sam proces)
|
||||
b → c (wysłanie → odbiór)
|
||||
a → c (przechodniość)
|
||||
c → e (ten sam proces)
|
||||
```
|
||||
|
||||
#### Zdarzenia współbieżne
|
||||
|
||||
Jeśli ¬(a → b) ∧ ¬(b → a), to **a || b** (współbieżne).
|
||||
|
||||
---
|
||||
|
||||
### 3. Zegar Lamporta (Scalar Clock)
|
||||
|
||||
#### Algorytm
|
||||
|
||||
```
|
||||
Każdy proces P_i ma licznik C_i:
|
||||
|
||||
1. Przed każdym zdarzeniem lokalnym:
|
||||
C_i := C_i + 1
|
||||
|
||||
2. Wysyłając wiadomość m:
|
||||
C_i := C_i + 1
|
||||
Dołącz timestamp(m) = C_i
|
||||
|
||||
3. Odbierając wiadomość m z timestamp t:
|
||||
C_i := max(C_i, t) + 1
|
||||
```
|
||||
|
||||
#### Przykład
|
||||
|
||||
```
|
||||
P1: C=0 ──●(1)────●(2)─────────●(5)──→
|
||||
a b d
|
||||
│↘
|
||||
│ ↘ m(2)
|
||||
│ ↘
|
||||
P2: C=0 ────●(1)───────●(3)────●(4)──→
|
||||
x c e
|
||||
|
||||
Zdarzenia: a=1, b=2, x=1, c=3, e=4, d=5
|
||||
```
|
||||
|
||||
#### Właściwości
|
||||
|
||||
| Właściwość | Zegar Lamporta |
|
||||
|------------|----------------|
|
||||
| a → b ⟹ C(a) < C(b) | ✅ TAK |
|
||||
| C(a) < C(b) ⟹ a → b | ❌ NIE |
|
||||
|
||||
**Ograniczenie:** C(a) < C(b) nie oznacza, że a → b (mogą być współbieżne).
|
||||
|
||||
---
|
||||
|
||||
### 4. Zegary wektorowe (Vector Clocks)
|
||||
|
||||
#### Algorytm
|
||||
|
||||
```
|
||||
Każdy z N procesów ma wektor V[1..N]:
|
||||
|
||||
1. Przed każdym zdarzeniem lokalnym:
|
||||
V_i[i] := V_i[i] + 1
|
||||
|
||||
2. Wysyłając wiadomość m:
|
||||
V_i[i] := V_i[i] + 1
|
||||
Dołącz timestamp(m) = V_i
|
||||
|
||||
3. Odbierając wiadomość m z timestamp T:
|
||||
V_i[j] := max(V_i[j], T[j]) dla każdego j
|
||||
V_i[i] := V_i[i] + 1
|
||||
```
|
||||
|
||||
#### Przykład
|
||||
|
||||
```
|
||||
P1: [0,0,0] ──●[1,0,0]────●[2,0,0]─────────●[3,2,0]──→
|
||||
a b d
|
||||
│↘
|
||||
│ ↘ m[2,0,0]
|
||||
│ ↘
|
||||
P2: [0,0,0] ────●[0,1,0]─────────●[2,2,0]────●[2,3,0]──→
|
||||
x c e
|
||||
```
|
||||
|
||||
#### Porównanie wektorów
|
||||
|
||||
```
|
||||
V ≤ W ⟺ ∀i: V[i] ≤ W[i]
|
||||
V < W ⟺ V ≤ W ∧ V ≠ W
|
||||
V || W ⟺ ¬(V ≤ W) ∧ ¬(W ≤ V)
|
||||
|
||||
Przykład:
|
||||
[2,3,1] < [2,4,1] (happened-before)
|
||||
[2,3,1] || [1,4,2] (współbieżne)
|
||||
```
|
||||
|
||||
#### Właściwości
|
||||
|
||||
| Właściwość | Zegar wektorowy |
|
||||
|------------|-----------------|
|
||||
| a → b ⟺ V(a) < V(b) | ✅ TAK |
|
||||
| Wykrycie współbieżności | ✅ TAK |
|
||||
|
||||
**Zegary wektorowe charakteryzują dokładnie relację happened-before!**
|
||||
|
||||
---
|
||||
|
||||
### 5. Porównanie
|
||||
|
||||
| Cecha | Lamport | Vector Clock |
|
||||
|-------|---------|--------------|
|
||||
| **Rozmiar** | O(1) | O(N) |
|
||||
| **a → b ⟹ C(a) < C(b)** | ✅ | ✅ |
|
||||
| **C(a) < C(b) ⟹ a → b** | ❌ | ✅ |
|
||||
| **Wykrycie współbieżności** | ❌ | ✅ |
|
||||
| **Zastosowanie** | Uporządkowanie | Wykrywanie konfliktów |
|
||||
|
||||
---
|
||||
|
||||
### 6. Zastosowania
|
||||
|
||||
| Zastosowanie | Typ zegara | Cel |
|
||||
|--------------|------------|-----|
|
||||
| **Mutual exclusion** | Lamport | Uporządkowanie żądań |
|
||||
| **Causal broadcast** | Vector | Dostarczanie w kolejności przyczynowej |
|
||||
| **Conflict detection** | Vector | Wykrycie współbieżnych zapisów |
|
||||
| **Distributed debugging** | Vector | Odtworzenie kolejności zdarzeń |
|
||||
| **Version vectors (Dynamo)** | Vector | Wykrycie konfliktów w replikacji |
|
||||
|
||||
#### Przykład: Dynamo/Riak
|
||||
|
||||
```
|
||||
Put(key, value) z vector clock:
|
||||
|
||||
Client → Server A: put("x", "v1", [A:1])
|
||||
Client → Server B: put("x", "v2", [B:1])
|
||||
|
||||
Konflikt wykryty: [A:1] || [B:1]
|
||||
Oba wartości przechowane, klient rozwiązuje
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Warianty i rozszerzenia
|
||||
|
||||
| Wariant | Opis |
|
||||
|---------|------|
|
||||
| **Interval Tree Clocks** | Dynamiczna liczba procesów |
|
||||
| **Bloom Clocks** | Probabilistyczne, kompaktowe |
|
||||
| **Hybrid Logical Clocks** | Lamport + czas fizyczny |
|
||||
| **Matrix Clocks** | Wiedza o wiedzy innych |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Lamport = Licznik skalarny":
|
||||
Jedna liczba, nie wykrywa współbieżności
|
||||
|
||||
### "Vector = Każdy wie o każdym":
|
||||
V[i] = ile zdarzeń widział proces i
|
||||
|
||||
### "< oznacza →, || oznacza współbieżność":
|
||||
Porównanie wektorów = relacja przyczynowa
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Dlaczego nie używać NTP zamiast zegarów logicznych?"
|
||||
**Odpowiedź:** NTP ma błąd ~ms (LAN) do ~100ms (WAN). Dla zdarzeń szybszych niż błąd synchronizacji, kolejność fizyczna jest nieznana. Zegary logiczne dają gwarancje przyczynowe bez względu na drift.
|
||||
|
||||
### Q2: "Co to jest causal consistency?"
|
||||
**Odpowiedź:** Model spójności gdzie zapisy przyczynowo zależne są widziane w tej samej kolejności przez wszystkich. Wymaga vector clocks. Słabszy niż sequential consistency, silniejszy niż eventual.
|
||||
|
||||
### Q3: "Problem skalowalności vector clocks?"
|
||||
**Odpowiedź:** O(N) rozmiar dla N procesów. Rozwiązania: przycinanie (Dynamo), Interval Tree Clocks (dynamiczne ID), Bloom clocks (probabilistyczne).
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Problem:** Brak globalnego zegara w systemach rozproszonych
|
||||
2. **Lamport:** Skalarny, a → b ⟹ C(a) < C(b), nie odwrotnie
|
||||
3. **Vector:** a → b ⟺ V(a) < V(b), wykrywa współbieżność
|
||||
4. **Zastosowania:** Replikacja, debugging, causal broadcast
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Lamport - "Time, Clocks, and the Ordering of Events" (1978)
|
||||
2. Fidge, Mattern - "Vector Clocks" (1988)
|
||||
3. DeCandia et al. - "Dynamo" (Amazon, 2007)
|
||||
@ -1,271 +0,0 @@
|
||||
# Pytanie 24: Modele spójności danych w systemach rozproszonych
|
||||
|
||||
## Pytanie
|
||||
**"Omówić silne i słabe modele spójności danych w środowisku rozproszonym."**
|
||||
|
||||
Przedmiot: ERSMS (Elementy Rozproszonych Systemów i Middleware'u Sieciowego)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Problem spójności w systemach rozproszonych
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Repliki danych: │
|
||||
│ │
|
||||
│ Client A Client B │
|
||||
│ │ write(x=1) │ read(x)=? │
|
||||
│ ↓ ↓ │
|
||||
│ ┌───────┐ ┌───────┐ │
|
||||
│ │Replica│──sync?──→│Replica│ │
|
||||
│ │ 1 │ │ 2 │ │
|
||||
│ │ x=1 │ │ x=0? │ │
|
||||
│ └───────┘ └───────┘ │
|
||||
│ │
|
||||
│ Pytanie: Co zwróci read(x)? │
|
||||
│ Odpowiedź zależy od modelu spójności! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Spektrum modeli spójności
|
||||
|
||||
```
|
||||
Silne ←─────────────────────────────────────────→ Słabe
|
||||
|
||||
Linearizability Eventual
|
||||
│ Consistency
|
||||
↓ ↑
|
||||
Sequential Causal
|
||||
Consistency Consistency
|
||||
│ ↑
|
||||
↓ Session
|
||||
Causal+ Guarantees
|
||||
│
|
||||
↓
|
||||
PRAM
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Silne modele spójności
|
||||
|
||||
#### Linearizability (Linearyzacja)
|
||||
|
||||
```
|
||||
Definicja: Każda operacja wygląda jakby wykonała się atomowo
|
||||
w pewnym momencie między wywołaniem a odpowiedzią.
|
||||
|
||||
Timeline:
|
||||
Client A: ─────[write(x=1)]─────────────────────→
|
||||
Client B: ───────────[read(x)]──────────────────→
|
||||
↓
|
||||
Musi zwrócić 1!
|
||||
|
||||
Właściwości:
|
||||
- Najsilniejsza gwarancja
|
||||
- "Globalny porządek rzeczywisty"
|
||||
- Kosztowna (wymaga koordynacji)
|
||||
```
|
||||
|
||||
**Implementacja:** Consensus (Paxos, Raft), single leader
|
||||
|
||||
#### Sequential Consistency
|
||||
|
||||
```
|
||||
Definicja: Istnieje globalny porządek operacji zgodny
|
||||
z porządkiem programu każdego procesu.
|
||||
|
||||
Client A: write(x=1) ──────────────────→
|
||||
Client B: ──────────── write(x=2) ─────→
|
||||
Client C: read(x)=? ── read(x)=? ──────→
|
||||
|
||||
Dozwolone: C widzi [1,2] lub [2,1]
|
||||
(byle konsystentnie z innymi)
|
||||
|
||||
Różnica od linearyzacji:
|
||||
- Nie wymaga zgodności z czasem rzeczywistym
|
||||
- Wystarczy spójny porządek
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Słabe modele spójności
|
||||
|
||||
#### Eventual Consistency
|
||||
|
||||
```
|
||||
Definicja: Jeśli nie ma nowych zapisów, ostatecznie
|
||||
wszystkie odczyty zwrócą tę samą wartość.
|
||||
|
||||
Timeline:
|
||||
write(x=1) @ Replica A
|
||||
↓ (propagacja)
|
||||
↓
|
||||
↓ ... czas ...
|
||||
↓
|
||||
read(x)=1 @ Replica B (eventually)
|
||||
|
||||
Gwarancje:
|
||||
✅ Dostępność (AP w CAP)
|
||||
✅ Niska latencja
|
||||
❌ Stare dane przez jakiś czas
|
||||
❌ Możliwe konflikty
|
||||
```
|
||||
|
||||
**Implementacja:** DNS, Dynamo, Cassandra
|
||||
|
||||
#### Causal Consistency
|
||||
|
||||
```
|
||||
Definicja: Operacje przyczynowo zależne widziane
|
||||
w tej samej kolejności przez wszystkich.
|
||||
|
||||
P1: write(x=1) ─────────────────────────→
|
||||
↓ (read x)
|
||||
P2: ──────────── write(y=2) ────────────→
|
||||
|
||||
P3 widzi: x=1 przed y=2 (zawsze!)
|
||||
(bo y=2 zależy przyczynowo od x=1)
|
||||
|
||||
Niezależne zapisy mogą być widziane w różnej kolejności.
|
||||
```
|
||||
|
||||
**Implementacja:** Vector clocks, COPS
|
||||
|
||||
#### Session Guarantees
|
||||
|
||||
| Gwarancja | Opis |
|
||||
|-----------|------|
|
||||
| **Read Your Writes** | Odczyt widzi własne wcześniejsze zapisy |
|
||||
| **Monotonic Reads** | Raz widziana wartość nie "cofa się" |
|
||||
| **Monotonic Writes** | Zapisy aplikowane w kolejności sesji |
|
||||
| **Writes Follow Reads** | Zapis po odczycie widzi ten odczyt |
|
||||
|
||||
```
|
||||
Read Your Writes:
|
||||
Session: write(x=5) ──── read(x)=? ────→
|
||||
Musi być 5!
|
||||
|
||||
Monotonic Reads:
|
||||
Session: read(x)=5 ──── read(x)=? ────→
|
||||
Musi być ≥ 5!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. CAP Theorem
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ CAP Theorem │
|
||||
│ │
|
||||
│ Consistency (C) │
|
||||
│ /\ │
|
||||
│ / \ │
|
||||
│ / \ │
|
||||
│ / CA \ │
|
||||
│ / \ │
|
||||
│ / CP \ │
|
||||
│ Availability (A) ──────────── Partition Tolerance (P) │
|
||||
│ AP │
|
||||
│ │
|
||||
│ W obecności partycji sieci (P): wybierz C lub A │
|
||||
│ │
|
||||
│ CP: Spójne, ale niedostępne (Zookeeper, etcd) │
|
||||
│ AP: Dostępne, ale niespójne (Dynamo, Cassandra) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Porównanie modeli
|
||||
|
||||
| Model | Gwarancje | Wydajność | Przykłady |
|
||||
|-------|-----------|-----------|-----------|
|
||||
| **Linearizable** | Najsilniejsze | Niska | Spanner, CockroachDB |
|
||||
| **Sequential** | Silne | Średnia | Zookeeper |
|
||||
| **Causal** | Przyczynowe | Dobra | COPS, MongoDB |
|
||||
| **Session** | Per-sesja | Dobra | Dynamo sessions |
|
||||
| **Eventual** | Najsłabsze | Najwyższa | DNS, Cassandra |
|
||||
|
||||
---
|
||||
|
||||
### 7. Strategie rozwiązywania konfliktów
|
||||
|
||||
#### Last-Writer-Wins (LWW)
|
||||
```
|
||||
Konflikt: write(x=1) || write(x=2)
|
||||
Rozwiązanie: Większy timestamp wygrywa
|
||||
Problem: Utrata danych!
|
||||
```
|
||||
|
||||
#### Multi-Value (Siblings)
|
||||
```
|
||||
Konflikt: write(x=1) || write(x=2)
|
||||
Rozwiązanie: Przechowaj oba: x=[1,2]
|
||||
Klient rozwiązuje przy odczycie (Riak)
|
||||
```
|
||||
|
||||
#### CRDTs (Conflict-free Replicated Data Types)
|
||||
```
|
||||
Struktury automatycznie łączące się:
|
||||
- G-Counter (grow-only counter)
|
||||
- OR-Set (observed-remove set)
|
||||
- LWW-Register
|
||||
|
||||
Merge jest łączny, przemienny, idempotentny
|
||||
→ Zawsze zbieżność!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Linearizable = Real-time + Atomic":
|
||||
Widoczne natychmiast, atomowo
|
||||
|
||||
### "Eventual = Eventually, trust me":
|
||||
Kiedyś będzie spójne (bez gwarancji kiedy)
|
||||
|
||||
### "CAP = Choose 2 of 3":
|
||||
Partition → wybierz Consistency lub Availability
|
||||
|
||||
### "CRDT = Conflict-free":
|
||||
Matematyczna gwarancja zbieżności
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Czym różni się linearizability od serializability?"
|
||||
**Odpowiedź:** Linearizability = dla pojedynczych operacji, real-time ordering. Serializability = dla transakcji, jakiś serial order. Strict serializability = oba razem.
|
||||
|
||||
### Q2: "Kiedy wybrać eventual consistency?"
|
||||
**Odpowiedź:** Wysoka dostępność ważniejsza niż spójność, tolerancja na stale reads, możliwość rozwiązania konfliktów (shopping cart, likes counter, DNS).
|
||||
|
||||
### Q3: "Co to jest Quorum?"
|
||||
**Odpowiedź:** W = write quorum, R = read quorum, N = repliki. W + R > N gwarantuje odczyt najnowszej wartości. Dynamo: N=3, W=2, R=2.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Linearizable:** Najsilniejszy, atomowy, kosztowny
|
||||
2. **Sequential:** Globalny porządek, bez real-time
|
||||
3. **Causal:** Przyczynowo zależne w kolejności
|
||||
4. **Eventual:** Ostatecznie spójne, najszybszy
|
||||
5. **CAP:** Partition → C xor A
|
||||
6. **CRDTs:** Automatyczne rozwiązywanie konfliktów
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Herlihy, Wing - "Linearizability" (1990)
|
||||
2. Vogels - "Eventually Consistent" (Amazon CTO)
|
||||
3. Gilbert, Lynch - "CAP Theorem" (2002)
|
||||
4. Shapiro et al. - "CRDTs" (2011)
|
||||
@ -1,269 +0,0 @@
|
||||
# Pytanie 25: Programowanie całkowitoliczbowe (MIP)
|
||||
|
||||
## Pytanie
|
||||
**"Gdzie znajdują zastosowania zadania programowania matematycznego całkowitoliczbowego i jak można je rozwiązywać? Omówić wybraną metodę dokładną, wyjaśnić dla jakich praktycznych problemów ma ona zastosowanie i co może wpływać na jej efektywność."**
|
||||
|
||||
Przedmiot: MOD (Metody Optymalizacji Dyskretnej)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Definicja MIP (Mixed Integer Programming)
|
||||
|
||||
```
|
||||
Programowanie całkowitoliczbowe:
|
||||
|
||||
min c^T x
|
||||
s.t. Ax ≤ b
|
||||
x_i ∈ Z dla i ∈ I (zmienne całkowite)
|
||||
x_j ∈ R dla j ∈ J (zmienne ciągłe)
|
||||
x ≥ 0
|
||||
|
||||
Przypadki szczególne:
|
||||
- IP (Integer Programming): wszystkie zmienne całkowite
|
||||
- BIP (Binary IP): x_i ∈ {0,1}
|
||||
- MIP (Mixed IP): część całkowite, część ciągłe
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Zastosowania
|
||||
|
||||
| Dziedzina | Problem | Zmienne binarne |
|
||||
|-----------|---------|-----------------|
|
||||
| **Logistyka** | Vehicle Routing (VRP) | x_ij = czy trasa i→j |
|
||||
| **Produkcja** | Scheduling, Lot sizing | y_t = czy produkować w t |
|
||||
| **Transport** | Facility Location | y_i = czy otworzyć magazyn i |
|
||||
| **Telekomunikacja** | Network Design | x_e = czy użyć krawędzi e |
|
||||
| **Finanse** | Portfolio (min transakcji) | y_i = czy inwestować w i |
|
||||
| **Energia** | Unit Commitment | y_t = czy uruchomić generator |
|
||||
|
||||
### Przykład: Problem plecakowy (Knapsack)
|
||||
|
||||
```
|
||||
max Σ v_i x_i (wartość)
|
||||
s.t. Σ w_i x_i ≤ C (pojemność)
|
||||
x_i ∈ {0,1} (brać lub nie)
|
||||
|
||||
Przedmioty: (wartość, waga)
|
||||
Item 1: (60, 10)
|
||||
Item 2: (100, 20)
|
||||
Item 3: (120, 30)
|
||||
Pojemność: C = 50
|
||||
|
||||
Optymalne: x = [1,1,1] niemożliwe (waga=60)
|
||||
x = [1,0,1] wartość=180, waga=40 ✓
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Metody rozwiązywania
|
||||
|
||||
| Metoda | Typ | Gwarancja optimum |
|
||||
|--------|-----|-------------------|
|
||||
| **Branch and Bound** | Dokładna | ✅ |
|
||||
| **Branch and Cut** | Dokładna | ✅ |
|
||||
| **Branch and Price** | Dokładna | ✅ |
|
||||
| **Cutting Planes** | Dokładna | ✅ |
|
||||
| **Heurystyki** | Przybliżona | ❌ |
|
||||
| **Metaheurystyki** | Przybliżona | ❌ |
|
||||
|
||||
---
|
||||
|
||||
### 4. Branch and Bound (B&B) - metoda dokładna
|
||||
|
||||
#### Idea
|
||||
|
||||
```
|
||||
1. Relaksacja LP: rozwiąż bez ograniczeń całkowitoliczbowych
|
||||
2. Jeśli rozwiązanie całkowite → gotowe
|
||||
3. Jeśli nie → rozgałęź (branch) na zmiennej niecałkowitej
|
||||
4. Przycinaj (bound) gdy dolne ograniczenie ≥ najlepsze znane
|
||||
|
||||
LP relaxation
|
||||
x* = 2.7
|
||||
/\
|
||||
/ \
|
||||
x ≤ 2 x ≥ 3
|
||||
/ \
|
||||
LP: z=10 LP: z=8
|
||||
/ \
|
||||
(dalej) (przycinaj jeśli
|
||||
najlepsze ≥ 8)
|
||||
```
|
||||
|
||||
#### Algorytm szczegółowy
|
||||
|
||||
```
|
||||
BranchAndBound(P):
|
||||
Q = {P} // kolejka podproblemów
|
||||
best = -∞ // najlepsze rozwiązanie
|
||||
best_x = null
|
||||
|
||||
while Q not empty:
|
||||
P' = select(Q) // wybierz podproblem
|
||||
z, x = LP_relax(P') // rozwiąż relaksację
|
||||
|
||||
if z ≤ best: // BOUND: przycięcie
|
||||
continue
|
||||
|
||||
if x is integer: // rozwiązanie całkowite
|
||||
if z > best:
|
||||
best = z
|
||||
best_x = x
|
||||
else: // BRANCH: rozgałęzienie
|
||||
i = fractional_var(x) // wybierz zmienną
|
||||
P1 = P' + {x_i ≤ floor(x_i)}
|
||||
P2 = P' + {x_i ≥ ceil(x_i)}
|
||||
Q.add(P1, P2)
|
||||
|
||||
return best_x
|
||||
```
|
||||
|
||||
#### Przykład: Max 3x + 2y, x + y ≤ 4, x,y ∈ Z+
|
||||
|
||||
```
|
||||
Root: LP opt
|
||||
x=4, y=0, z=12
|
||||
(całkowite!) → DONE
|
||||
|
||||
Bardziej interesujący przykład:
|
||||
max 5x + 8y
|
||||
x + y ≤ 6
|
||||
5x + 9y ≤ 45
|
||||
x, y ≥ 0, integer
|
||||
|
||||
LP: x=2.25, y=3.75, z=41.25
|
||||
│
|
||||
┌───────┴───────┐
|
||||
y ≤ 3 y ≥ 4
|
||||
│ │
|
||||
x=3, y=3 x=1.8, y=4
|
||||
z=39 (int!) z=41
|
||||
│ │
|
||||
incumbent=39 ┌───┴───┐
|
||||
x≤1 x≥2
|
||||
│ │
|
||||
z=40 infeas.
|
||||
x=1,y=4
|
||||
(int!)
|
||||
|
||||
Optimum: x=1, y=4, z=40
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Czynniki wpływające na efektywność B&B
|
||||
|
||||
| Czynnik | Wpływ | Strategie |
|
||||
|---------|-------|-----------|
|
||||
| **Jakość relaksacji** | Lepsza → mniej węzłów | Silne formulacje, cutting planes |
|
||||
| **Wybór zmiennej do branch** | Balans drzewa | Most fractional, strong branching |
|
||||
| **Wybór węzła** | DFS vs BFS | Best-first (best bound) |
|
||||
| **Przerywanie** | Jakość incumbent | Heurystyki, warm start |
|
||||
| **Symetria** | Wiele równoważnych rozw. | Symmetry breaking constraints |
|
||||
|
||||
#### Strategie wyboru zmiennej (branching)
|
||||
|
||||
| Strategia | Opis |
|
||||
|-----------|------|
|
||||
| **Most fractional** | x_i najbliżej 0.5 |
|
||||
| **First fractional** | Pierwsza niecałkowita |
|
||||
| **Strong branching** | Testuj kandydatów przez LP |
|
||||
| **Pseudocost** | Historia wpływu na bound |
|
||||
|
||||
#### Strategie wyboru węzła
|
||||
|
||||
| Strategia | Właściwości |
|
||||
|-----------|-------------|
|
||||
| **Best-first** | Najlepszy bound → mniej węzłów |
|
||||
| **Depth-first** | Szybko znajduje rozwiązania |
|
||||
| **Best-estimate** | Kombinacja bound + estimate |
|
||||
|
||||
---
|
||||
|
||||
### 6. Ulepszenia: Branch and Cut
|
||||
|
||||
```
|
||||
Branch and Bound + Cutting Planes:
|
||||
|
||||
W każdym węźle:
|
||||
1. Rozwiąż LP relaksację
|
||||
2. Jeśli rozwiązanie niecałkowite:
|
||||
- Generuj cięcia (Gomory, Cover, Clique...)
|
||||
- Dodaj cięcia do LP
|
||||
- Powtórz do limitu
|
||||
3. Jeśli nadal niecałkowite → branch
|
||||
|
||||
Cięcia zacieśniają relaksację LP bez odcinania
|
||||
rozwiązań całkowitoliczbowych!
|
||||
|
||||
┌─────────────────────┐
|
||||
│ Politop LP │
|
||||
│ ╱─────╲ │
|
||||
│ ╱ ╲ cięcie │
|
||||
│ ●─────────● │
|
||||
│ │ ● ● │ │
|
||||
│ │ ● ● │ rozw. │
|
||||
│ │ ● ● │ całk. │
|
||||
│ ●─────────● │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Narzędzia
|
||||
|
||||
| Solver | Typ | Licencja |
|
||||
|--------|-----|----------|
|
||||
| **CPLEX** | Komercyjny | IBM |
|
||||
| **Gurobi** | Komercyjny | Academic free |
|
||||
| **SCIP** | Open source | ZIB |
|
||||
| **CBC** | Open source | COIN-OR |
|
||||
| **OR-Tools** | Open source | Google |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "B&B = Branch by variable, Bound by LP":
|
||||
Rozgałęziaj na zmiennej, przycinaj przez relaksację
|
||||
|
||||
### "MIP = Mix of Integer and continuous":
|
||||
Część zmiennych całkowita, część ciągła
|
||||
|
||||
### "Tight LP = Fast B&B":
|
||||
Lepsza relaksacja → mniej węzłów do sprawdzenia
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Co to jest integrality gap?"
|
||||
**Odpowiedź:** Różnica między optimum LP (relaksacja) a optimum IP. Mała luka = silna formulacja = szybki B&B. Gap = (LP_opt - IP_opt) / IP_opt.
|
||||
|
||||
### Q2: "Kiedy B&B jest nieefektywny?"
|
||||
**Odpowiedź:** Słaba relaksacja (duży gap), dużo symetrii, wiele prawie równoważnych rozwiązań. Wtedy: miliony węzłów, długi czas. Rozwiązanie: silniejsze formulacje, symmetry breaking, heurystyki.
|
||||
|
||||
### Q3: "Co to jest cięcie Gomory'ego?"
|
||||
**Odpowiedź:** Automatycznie generowane cięcie z tablicy simplex. Odcina aktualne rozwiązanie LP bez odcinania punktów całkowitych. Słabe dla dużych problemów, lepsze: cover cuts, clique cuts dla konkretnych struktur.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **MIP:** Optymalizacja ze zmiennymi całkowitymi (NP-trudna)
|
||||
2. **Zastosowania:** Scheduling, routing, facility location
|
||||
3. **B&B:** Relaksacja LP + branching + bounding
|
||||
4. **Efektywność:** Jakość relaksacji, strategia branching, cięcia
|
||||
5. **Narzędzia:** CPLEX, Gurobi, SCIP, CBC
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Wolsey - "Integer Programming"
|
||||
2. Nemhauser, Wolsey - "Integer and Combinatorial Optimization"
|
||||
3. CPLEX User Manual
|
||||
4. Achterberg - "SCIP: Solving Constraint Integer Programs"
|
||||
@ -1,272 +0,0 @@
|
||||
# Pytanie 26: Narzędzia optymalizacji dyskretnej
|
||||
|
||||
## Pytanie
|
||||
**"Scharakteryzować informatyczne narzędzia optymalizacji dyskretnej. Jakie są warunki i wymagania, jakie możliwości oraz trudności wiążą się ze stosowaniem gotowych narzędzi."**
|
||||
|
||||
Przedmiot: MOD (Metody Optymalizacji Dyskretnej)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Kategorie narzędzi
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ NARZĘDZIA OPTYMALIZACJI DYSKRETNEJ │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ SOLVERY MIP │ SOLVERY CP │ METAHEURYSTYKI │
|
||||
│ (Mixed Integer │ (Constraint │ │
|
||||
│ Programming) │ Programming) │ │
|
||||
│ ───────────────── │ ────────────── │ ────────────── │
|
||||
│ CPLEX, Gurobi │ CP-SAT (Google) │ LocalSolver │
|
||||
│ SCIP, CBC │ Chuffed, Gecode │ OptaPlanner │
|
||||
│ │ MiniZinc │ OR-Tools │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ JĘZYKI MODELOWANIA │ SAT/SMT SOLVERY │ FRAMEWORKI │
|
||||
│ ───────────────── │ ────────────── │ ────────────── │
|
||||
│ AMPL, GAMS │ Z3, CVC5 │ PuLP (Python) │
|
||||
│ Pyomo, JuMP │ MiniSat, Glucose │ CVXPY │
|
||||
│ MiniZinc │ │ OR-Tools │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Solvery MIP
|
||||
|
||||
| Solver | Licencja | Cechy |
|
||||
|--------|----------|-------|
|
||||
| **CPLEX** | Komercyjny (IBM) | Najszybszy dla dużych MIP |
|
||||
| **Gurobi** | Komercyjny (academic free) | Bardzo szybki, dobry API |
|
||||
| **SCIP** | Open source (ZIB) | Framework extensible |
|
||||
| **CBC** | Open source (COIN-OR) | Dobry darmowy solver |
|
||||
| **HiGHS** | Open source | Nowoczesny, szybki LP/MIP |
|
||||
| **GLPK** | Open source | Prosty, portable |
|
||||
|
||||
### Porównanie wydajności (benchmark)
|
||||
|
||||
```
|
||||
Typowe czasy dla problemów MIPLIB (średnie):
|
||||
|
||||
CPLEX ████████████████████████████ 100%
|
||||
Gurobi ███████████████████████████ 98%
|
||||
SCIP ████████████████ 60%
|
||||
CBC ████████████ 45%
|
||||
GLPK ████████ 30%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Solvery Constraint Programming
|
||||
|
||||
| Solver | Język | Cechy |
|
||||
|--------|-------|-------|
|
||||
| **CP-SAT** | Python/C++ | Google, bardzo szybki |
|
||||
| **Gecode** | C++ | Akademicki, elastyczny |
|
||||
| **Chuffed** | MiniZinc | Lazy clause generation |
|
||||
| **OR-Tools** | Multi | Google, CP + routing + MIP |
|
||||
|
||||
### Kiedy CP vs MIP?
|
||||
|
||||
| Aspekt | MIP | CP |
|
||||
|--------|-----|-----|
|
||||
| **Ograniczenia globalne** | Słabo | Świetnie (alldiff, cumulative) |
|
||||
| **Relaksacja** | LP (silna) | Słabsza |
|
||||
| **Scheduling** | Średnio | Świetnie |
|
||||
| **Kombinatoryczne** | Dobrze | Bardzo dobrze |
|
||||
|
||||
---
|
||||
|
||||
### 4. Języki modelowania
|
||||
|
||||
#### AMPL
|
||||
```ampl
|
||||
set PRODUCTS;
|
||||
param profit{PRODUCTS};
|
||||
param capacity;
|
||||
|
||||
var produce{PRODUCTS} >= 0 integer;
|
||||
|
||||
maximize total_profit:
|
||||
sum{p in PRODUCTS} profit[p] * produce[p];
|
||||
|
||||
subject to capacity_limit:
|
||||
sum{p in PRODUCTS} produce[p] <= capacity;
|
||||
```
|
||||
|
||||
#### Pyomo (Python)
|
||||
```python
|
||||
from pyomo.environ import *
|
||||
|
||||
model = ConcreteModel()
|
||||
model.x = Var([1,2,3], domain=NonNegativeIntegers)
|
||||
model.obj = Objective(expr=sum(model.x[i] for i in [1,2,3]),
|
||||
sense=maximize)
|
||||
model.con = Constraint(expr=model.x[1] + model.x[2] <= 10)
|
||||
|
||||
solver = SolverFactory('gurobi')
|
||||
solver.solve(model)
|
||||
```
|
||||
|
||||
#### OR-Tools (Python)
|
||||
```python
|
||||
from ortools.linear_solver import pywraplp
|
||||
|
||||
solver = pywraplp.Solver.CreateSolver('SCIP')
|
||||
x = solver.IntVar(0, 10, 'x')
|
||||
y = solver.IntVar(0, 10, 'y')
|
||||
solver.Add(x + y <= 15)
|
||||
solver.Maximize(3*x + 4*y)
|
||||
solver.Solve()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Warunki i wymagania
|
||||
|
||||
| Wymaganie | Opis |
|
||||
|-----------|------|
|
||||
| **Licencja** | Komercyjne (CPLEX, Gurobi) vs Open source |
|
||||
| **API/Język** | Python, C++, Java, Julia |
|
||||
| **Format modelu** | MPS, LP, AMPL, własny |
|
||||
| **Pamięć** | Duże modele = duże wymagania RAM |
|
||||
| **Wielowątkowość** | Parallel B&B, concurrent LP |
|
||||
|
||||
### Typowe wymagania sprzętowe
|
||||
|
||||
```
|
||||
Mały problem (< 1000 zmiennych):
|
||||
- RAM: 4 GB
|
||||
- CPU: dowolny
|
||||
- Czas: sekundy
|
||||
|
||||
Średni problem (1000-100k zmiennych):
|
||||
- RAM: 16-32 GB
|
||||
- CPU: multi-core
|
||||
- Czas: minuty-godziny
|
||||
|
||||
Duży problem (> 100k zmiennych):
|
||||
- RAM: 64+ GB
|
||||
- CPU: wiele rdzeni
|
||||
- Czas: godziny-dni
|
||||
- Czasem: cluster computing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Możliwości
|
||||
|
||||
| Możliwość | Opis |
|
||||
|-----------|------|
|
||||
| **Gwarancja optimum** | Metody dokładne (B&B, B&C) |
|
||||
| **Gap tracking** | Śledzenie jakości rozwiązania |
|
||||
| **Callbacks** | Własne cięcia, heurystyki, lazy constraints |
|
||||
| **Warm start** | Start od znanego rozwiązania |
|
||||
| **Tuning** | Automatyczne dostrajanie parametrów |
|
||||
| **Solution pool** | Wiele rozwiązań (k-best) |
|
||||
|
||||
---
|
||||
|
||||
### 7. Trudności
|
||||
|
||||
| Trudność | Opis | Rozwiązanie |
|
||||
|----------|------|-------------|
|
||||
| **Czas obliczeń** | NP-trudność | Heurystyki, time limit |
|
||||
| **Słaba formulacja** | Duży integrality gap | Silniejsze modele, cięcia |
|
||||
| **Symetria** | Wiele równoważnych rozw. | Symmetry breaking |
|
||||
| **Numeryka** | Błędy zaokrągleń | Tolerancje, scaling |
|
||||
| **Pamięć** | Duże drzewa B&B | Limity węzłów, DFS |
|
||||
| **Debugowanie** | Infeasible/unbounded | IIS (Irreducible Infeasible Set) |
|
||||
|
||||
### Diagnostyka problemów
|
||||
|
||||
```
|
||||
Problem: Model INFEASIBLE
|
||||
|
||||
Diagnoza:
|
||||
1. solver.computeIIS() # znajdź konflikt
|
||||
2. Sprawdź constraints
|
||||
3. Poluzuj ograniczenia
|
||||
|
||||
Problem: Zbyt długi czas
|
||||
|
||||
Diagnoza:
|
||||
1. Gap się nie zmniejsza → słaba formulacja
|
||||
2. Dużo węzłów B&B → symetria
|
||||
3. LP wolne → presolve, scaling
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. Best practices
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 1. FORMULACJA │
|
||||
│ - Unikaj big-M (słaba relaksacja) │
|
||||
│ - Używaj wskaźnikowych (indicator constraints) │
|
||||
│ - Tight bounds na zmienne │
|
||||
│ │
|
||||
│ 2. PREPROCESSING │
|
||||
│ - Presolve (solver robi automatycznie) │
|
||||
│ - Agregacja zmiennych │
|
||||
│ - Eliminacja redundancji │
|
||||
│ │
|
||||
│ 3. PARAMETRY SOLVERA │
|
||||
│ - MIPGap: akceptowalny gap (np. 1%) │
|
||||
│ - TimeLimit: maksymalny czas │
|
||||
│ - Threads: liczba wątków │
|
||||
│ - Emphasis: feasibility vs optimality │
|
||||
│ │
|
||||
│ 4. DEBUGGING │
|
||||
│ - Zacznij od małej instancji │
|
||||
│ - Sprawdź relaxację LP │
|
||||
│ - Użyj IIS dla infeasible │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "CPLEX/Gurobi = Commercial Power":
|
||||
Najszybsze, ale płatne (academic free)
|
||||
|
||||
### "SCIP = Swiss army knife":
|
||||
Open source, extensible, framework
|
||||
|
||||
### "CP for Scheduling, MIP for Planning":
|
||||
CP świetny dla harmonogramowania
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy używać metaheurystyk zamiast solverów?"
|
||||
**Odpowiedź:** Bardzo duże instancje (miliony zmiennych), brak dobrej formulacji MIP, potrzeba szybkiego "dobrego" rozwiązania bez gwarancji, problemy z wieloma celami, problemy dynamiczne.
|
||||
|
||||
### Q2: "Co to jest callback w solverze MIP?"
|
||||
**Odpowiedź:** Funkcja wywoływana przez solver w trakcie B&B. Typy: lazy constraints (dodaj ograniczenie gdy naruszone), user cuts (wzmocnij relaksację), heuristic (znajdź rozwiązanie), branching (własna strategia).
|
||||
|
||||
### Q3: "Jak poprawić słabą formulację?"
|
||||
**Odpowiedź:** Dodaj valid inequalities (cięcia), zastąp big-M przez indicator constraints, wprowadź dodatkowe zmienne (extended formulation), użyj disaggregation.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **MIP solvery:** CPLEX, Gurobi (komercyjne), SCIP, CBC (open source)
|
||||
2. **CP solvery:** CP-SAT, Gecode - dobre dla scheduling
|
||||
3. **Języki:** AMPL, Pyomo, OR-Tools
|
||||
4. **Trudności:** Czas, słaba formulacja, symetria
|
||||
5. **Best practice:** Tight formulation, callbacks, proper tuning
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. CPLEX User Manual
|
||||
2. Gurobi Reference Manual
|
||||
3. Williams - "Model Building in Mathematical Programming"
|
||||
4. OR-Tools documentation - developers.google.com/optimization
|
||||
@ -1,236 +0,0 @@
|
||||
# Pytanie 27: Jakość modelu danych w projekcie informatycznym
|
||||
|
||||
## Pytanie
|
||||
**"Dlaczego jakość modelu danych jest krytycznie ważnym czynnikiem jakości projektu informatycznego?"**
|
||||
|
||||
Przedmiot: MODA (Modelowanie Danych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Model danych jako fundament systemu
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ARCHITEKTURA SYSTEMU │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ UI │ │ Logika │ │ Integracje │ │
|
||||
│ │ │ │ biznesowa │ │ │ │
|
||||
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
||||
│ │ │ │ │
|
||||
│ └────────────┬────┴────────────────┘ │
|
||||
│ │ │
|
||||
│ ↓ │
|
||||
│ ╔════════════════════════════════╗ │
|
||||
│ ║ MODEL DANYCH ║ ← FUNDAMENT │
|
||||
│ ║ (schemat bazy, encje, ║ │
|
||||
│ ║ relacje, ograniczenia) ║ │
|
||||
│ ╚════════════════════════════════╝ │
|
||||
│ │
|
||||
│ Zmiana modelu danych → kaskadowe zmiany w całym systemie! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Konsekwencje złego modelu danych
|
||||
|
||||
| Problem | Konsekwencje |
|
||||
|---------|--------------|
|
||||
| **Redundancja** | Anomalie (insert, update, delete), niespójność |
|
||||
| **Brak normalizacji** | Duplikacja, trudna aktualizacja |
|
||||
| **Nadmierna normalizacja** | Wolne zapytania (wiele JOIN) |
|
||||
| **Złe typy danych** | Błędy konwersji, utrata precyzji |
|
||||
| **Brak ograniczeń** | Nieprawidłowe dane w bazie |
|
||||
| **Słaba dokumentacja** | Niezrozumiały schemat |
|
||||
|
||||
### Przykład: Anomalie przy braku normalizacji
|
||||
|
||||
```
|
||||
Tabela nienormalizowana (zamówienia):
|
||||
┌────────┬─────────┬─────────────┬───────────┬─────────┐
|
||||
│OrderID │Customer │CustomerAddr │ Product │ Price │
|
||||
├────────┼─────────┼─────────────┼───────────┼─────────┤
|
||||
│ 1 │ Jan │ Warszawa │ Laptop │ 3000 │
|
||||
│ 2 │ Jan │ Warszawa │ Mysz │ 50 │
|
||||
│ 3 │ Anna │ Kraków │ Laptop │ 3000 │
|
||||
└────────┴─────────┴─────────────┴───────────┴─────────┘
|
||||
|
||||
Problemy:
|
||||
❌ UPDATE: Jan zmienia adres → aktualizuj wiele wierszy
|
||||
❌ DELETE: Usunięcie zamówienia 3 → tracimy info o Annie
|
||||
❌ INSERT: Nowy klient bez zamówienia → nie można dodać
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Wpływ na różne aspekty projektu
|
||||
|
||||
#### Wydajność
|
||||
|
||||
```
|
||||
Zły model:
|
||||
SELECT * FROM orders
|
||||
JOIN customers ON orders.customer_name = customers.name -- string comparison!
|
||||
JOIN products ON orders.product_name = products.name
|
||||
WHERE customers.city = 'Warszawa';
|
||||
→ Full table scans, wolne JOIN na stringach
|
||||
|
||||
Dobry model:
|
||||
SELECT * FROM orders o
|
||||
JOIN customers c ON o.customer_id = c.id -- integer FK
|
||||
JOIN products p ON o.product_id = p.id
|
||||
WHERE c.city_id = 1; -- indexed lookup
|
||||
→ Index scans, szybkie JOIN na integer PK/FK
|
||||
```
|
||||
|
||||
#### Skalowalność
|
||||
|
||||
| Model | Skalowalność |
|
||||
|-------|--------------|
|
||||
| **Denormalizowany (złe)** | Ogromne tabele, trudne sharding |
|
||||
| **Nadmiernie znormalizowany** | Wiele JOIN, complex queries |
|
||||
| **Zbalansowany** | Optymalne partycjonowanie, cache-friendly |
|
||||
|
||||
#### Utrzymywalność
|
||||
|
||||
```
|
||||
Zły model:
|
||||
- Pole "data" typu VARCHAR przechowuje JSON, XML, CSV...
|
||||
- Brak dokumentacji co oznaczają kody (status=1,2,3?)
|
||||
- Nazwy kolumn: col1, col2, temp_field, test123
|
||||
|
||||
Dobry model:
|
||||
- Dedykowane tabele i kolumny z opisowymi nazwami
|
||||
- ENUM lub tabela słownikowa dla statusów
|
||||
- Komentarze w schemacie, dokumentacja ERD
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Koszty naprawy złego modelu
|
||||
|
||||
```
|
||||
Koszt zmiany modelu danych w czasie:
|
||||
|
||||
Koszt
|
||||
↑
|
||||
│ ████
|
||||
│ ████████████
|
||||
│ ████████████████████
|
||||
│ ████████████████████████████
|
||||
│ ████████████████████████████████████
|
||||
│ ████████████████████████████████████████████
|
||||
│████████████████████████████████████████████████████
|
||||
└────────────────────────────────────────────────────→ Czas
|
||||
Projekt Dev Test Prod 2 lata 5 lat
|
||||
|
||||
Migracja w produkcji: downtime, ryzyko utraty danych,
|
||||
koordynacja z aplikacjami, rollback plan
|
||||
```
|
||||
|
||||
**Reguła 1:10:100:**
|
||||
- Naprawa w fazie projektowania: 1x
|
||||
- Naprawa w fazie developmentu: 10x
|
||||
- Naprawa w produkcji: 100x
|
||||
|
||||
---
|
||||
|
||||
### 5. Cechy dobrego modelu danych
|
||||
|
||||
| Cecha | Opis |
|
||||
|-------|------|
|
||||
| **Poprawność** | Odzwierciedla dziedzinę biznesową |
|
||||
| **Kompletność** | Wszystkie wymagane dane |
|
||||
| **Spójność** | Brak sprzeczności, integralność |
|
||||
| **Minimalizm** | Brak zbędnej redundancji |
|
||||
| **Elastyczność** | Możliwość rozszerzenia |
|
||||
| **Wydajność** | Odpowiednia denormalizacja gdzie potrzeba |
|
||||
| **Dokumentacja** | ERD, słownik danych |
|
||||
|
||||
---
|
||||
|
||||
### 6. Wpływ na jakość danych (GIGO)
|
||||
|
||||
```
|
||||
Garbage In, Garbage Out:
|
||||
|
||||
┌──────────────────┐
|
||||
│ Złe dane wejść. │ → Zły model → Złe decyzje biznesowe
|
||||
│ (brak walidacji) │
|
||||
└──────────────────┘
|
||||
|
||||
Dobry model wymusza jakość:
|
||||
- NOT NULL gdzie wymagane
|
||||
- CHECK constraints (age > 0)
|
||||
- FOREIGN KEY (referential integrity)
|
||||
- UNIQUE (brak duplikatów)
|
||||
- Trigger dla złożonej walidacji
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Model danych a architektura aplikacji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Model danych wpływa na: │
|
||||
│ │
|
||||
│ • ORM mapping (Entity classes) │
|
||||
│ • API endpoints (REST resources) │
|
||||
│ • UI forms (pola formularzy) │
|
||||
│ • Validation rules │
|
||||
│ • Business logic │
|
||||
│ • Reports & Analytics │
|
||||
│ • Data warehouse schema │
|
||||
│ • Integration contracts │
|
||||
│ │
|
||||
│ Zmiana w modelu → propagacja do WSZYSTKICH warstw! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Model = Fundament domu":
|
||||
Zły fundament → dom się zawali (kosztowna przebudowa)
|
||||
|
||||
### "GIGO = Garbage In, Garbage Out":
|
||||
Zły model → złe dane → złe decyzje
|
||||
|
||||
### "1:10:100 = Koszt naprawy rośnie":
|
||||
Im później naprawa, tym drożej
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jak mierzyć jakość modelu danych?"
|
||||
**Odpowiedź:** Metryki: liczba anomalii, poziom normalizacji, pokrycie constraints, liczba orphan records, czas wykonania typowych zapytań, coupling między tabelami, dokumentacja coverage.
|
||||
|
||||
### Q2: "Kiedy denormalizacja jest uzasadniona?"
|
||||
**Odpowiedź:** Read-heavy systemy (raportowanie), krytyczne zapytania wymagające wielu JOIN, cache/materialized views, data warehouse (star schema), gdy koszt UPDATE < koszt JOIN.
|
||||
|
||||
### Q3: "Jak ewoluować model w produkcji?"
|
||||
**Odpowiedź:** Migracje (Flyway, Liquibase), blue-green deployment, feature flags, backward compatible changes (add column, nie remove), expand-contract pattern.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Fundament:** Model danych = podstawa całego systemu
|
||||
2. **Kaskada:** Zmiana modelu → zmiany wszędzie
|
||||
3. **Koszt:** 1:10:100 - wczesne poprawki tańsze
|
||||
4. **Jakość:** Constraints wymuszają poprawność danych
|
||||
5. **Dokumentacja:** ERD, słownik danych niezbędne
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Date - "An Introduction to Database Systems"
|
||||
2. Fowler - "Patterns of Enterprise Application Architecture"
|
||||
3. Ambler - "Agile Database Techniques"
|
||||
@ -1,296 +0,0 @@
|
||||
# Pytanie 28: Fazy ewolucji modelu danych
|
||||
|
||||
## Pytanie
|
||||
**"Omówić typowe fazy ewolucji modelu danych i pożądane cechy modelu w każdej z faz."**
|
||||
|
||||
Przedmiot: MODA (Modelowanie Danych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Przegląd faz ewolucji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FAZY EWOLUCJI MODELU DANYCH │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ KONCEPTUALNY │ → │ LOGICZNY │ → │ FIZYCZNY │ │
|
||||
│ │ (CDM) │ │ (LDM) │ │ (PDM) │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ CO przechowujemy JAK strukturyzujemy JAK implementujemy │
|
||||
│ (biznes) (logika) (technologia) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Model konceptualny (Conceptual Data Model)
|
||||
|
||||
#### Cel
|
||||
- Zrozumienie dziedziny biznesowej
|
||||
- Komunikacja z interesariuszami (nietechnicznymi)
|
||||
- Identyfikacja głównych encji i relacji
|
||||
|
||||
#### Cechy pożądane
|
||||
|
||||
| Cecha | Opis |
|
||||
|-------|------|
|
||||
| **Prostota** | Zrozumiały dla biznesu |
|
||||
| **Abstrakcja** | Brak szczegółów technicznych |
|
||||
| **Kompletność** | Wszystkie koncepcje biznesowe |
|
||||
| **Poprawność** | Zgodność z rzeczywistością biznesową |
|
||||
|
||||
#### Notacja i narzędzia
|
||||
|
||||
```
|
||||
Diagram ERD (Entity-Relationship) - uproszczony:
|
||||
|
||||
┌──────────┐ ┌──────────┐
|
||||
│ KLIENT │ składa │ZAMÓWIENIE│
|
||||
│ │ 1────M │ │
|
||||
└──────────┘ └──────────┘
|
||||
│
|
||||
│ zawiera
|
||||
│ M
|
||||
│
|
||||
┌──────────┐
|
||||
│ PRODUKT │
|
||||
│ │
|
||||
└──────────┘
|
||||
|
||||
Brak typów danych, kluczy, atrybutów szczegółowych!
|
||||
Tylko encje i relacje (z krotnością).
|
||||
```
|
||||
|
||||
#### Przykład
|
||||
|
||||
```
|
||||
Model konceptualny dla e-commerce:
|
||||
|
||||
Encje: Klient, Zamówienie, Produkt, Kategoria, Dostawca, Płatność
|
||||
|
||||
Relacje:
|
||||
- Klient składa Zamówienia (1:N)
|
||||
- Zamówienie zawiera Produkty (M:N)
|
||||
- Produkt należy do Kategorii (N:1)
|
||||
- Dostawca dostarcza Produkty (M:N)
|
||||
- Zamówienie ma Płatność (1:1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Model logiczny (Logical Data Model)
|
||||
|
||||
#### Cel
|
||||
- Szczegółowa struktura danych
|
||||
- Normalizacja
|
||||
- Definicja atrybutów i kluczy
|
||||
- Niezależność od DBMS
|
||||
|
||||
#### Cechy pożądane
|
||||
|
||||
| Cecha | Opis |
|
||||
|-------|------|
|
||||
| **Normalizacja** | Minimum 3NF, często BCNF |
|
||||
| **Integralność** | PK, FK, constraints |
|
||||
| **Kompletność atrybutów** | Wszystkie pola z typami logicznymi |
|
||||
| **Dokumentacja** | Słownik danych |
|
||||
| **Niezależność** | Bez szczegółów implementacji |
|
||||
|
||||
#### Notacja
|
||||
|
||||
```
|
||||
ERD szczegółowy (np. Crow's Foot):
|
||||
|
||||
┌────────────────────────┐ ┌────────────────────────┐
|
||||
│ KLIENT │ │ ZAMÓWIENIE │
|
||||
├────────────────────────┤ ├────────────────────────┤
|
||||
│ PK klient_id │───┐ │ PK zamowienie_id │
|
||||
│ imie │ │ │ FK klient_id │──┐
|
||||
│ nazwisko │ └──<│ data_zamowienia │ │
|
||||
│ email (UNIQUE) │ │ status │ │
|
||||
│ data_rejestracji │ │ suma │ │
|
||||
└────────────────────────┘ └────────────────────────┘ │
|
||||
│ │
|
||||
│ 1 │
|
||||
│ │
|
||||
┌────────────────────────┐ │
|
||||
│ POZYCJA_ZAMOWIENIA │ │
|
||||
├────────────────────────┤ │
|
||||
│ PK pozycja_id │ │
|
||||
│ FK zamowienie_id │──┘
|
||||
│ FK produkt_id │
|
||||
│ ilosc │
|
||||
│ cena_jednostkowa │
|
||||
└────────────────────────┘
|
||||
```
|
||||
|
||||
#### Normalizacja
|
||||
|
||||
```
|
||||
1NF: Atomowe wartości, brak powtarzających się grup
|
||||
2NF: 1NF + brak częściowych zależności od PK
|
||||
3NF: 2NF + brak zależności przechodnich
|
||||
BCNF: Każdy determinant jest kluczem kandydującym
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Model fizyczny (Physical Data Model)
|
||||
|
||||
#### Cel
|
||||
- Implementacja w konkretnym DBMS
|
||||
- Optymalizacja wydajności
|
||||
- Definicja indeksów, partycji, storage
|
||||
|
||||
#### Cechy pożądane
|
||||
|
||||
| Cecha | Opis |
|
||||
|-------|------|
|
||||
| **Wydajność** | Indeksy, denormalizacja gdzie potrzeba |
|
||||
| **Specyfika DBMS** | Typy danych, funkcje specyficzne |
|
||||
| **Skalowalność** | Partycjonowanie, sharding |
|
||||
| **Bezpieczeństwo** | Uprawnienia, szyfrowanie |
|
||||
| **Backup/Recovery** | Strategia archiwizacji |
|
||||
|
||||
#### Przykład DDL (PostgreSQL)
|
||||
|
||||
```sql
|
||||
CREATE TABLE klient (
|
||||
klient_id SERIAL PRIMARY KEY,
|
||||
imie VARCHAR(50) NOT NULL,
|
||||
nazwisko VARCHAR(50) NOT NULL,
|
||||
email VARCHAR(100) UNIQUE NOT NULL,
|
||||
data_rejestracji TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
status klient_status DEFAULT 'aktywny'
|
||||
);
|
||||
|
||||
CREATE INDEX idx_klient_email ON klient(email);
|
||||
CREATE INDEX idx_klient_nazwisko ON klient(nazwisko);
|
||||
|
||||
CREATE TABLE zamowienie (
|
||||
zamowienie_id SERIAL PRIMARY KEY,
|
||||
klient_id INTEGER NOT NULL REFERENCES klient(klient_id),
|
||||
data_zamowienia TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
status zamowienie_status DEFAULT 'nowe',
|
||||
suma DECIMAL(10,2) NOT NULL CHECK (suma >= 0)
|
||||
) PARTITION BY RANGE (data_zamowienia);
|
||||
|
||||
CREATE TABLE zamowienie_2024 PARTITION OF zamowienie
|
||||
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
|
||||
```
|
||||
|
||||
#### Optymalizacje fizyczne
|
||||
|
||||
| Technika | Zastosowanie |
|
||||
|----------|--------------|
|
||||
| **Indeksy** | B-tree, Hash, GIN, GiST |
|
||||
| **Partycjonowanie** | Range, List, Hash |
|
||||
| **Denormalizacja** | Materialized views, redundancja |
|
||||
| **Kompresja** | Kolumnowe storage |
|
||||
| **Clustering** | Fizyczne uporządkowanie |
|
||||
|
||||
---
|
||||
|
||||
### 5. Porównanie faz
|
||||
|
||||
| Aspekt | Konceptualny | Logiczny | Fizyczny |
|
||||
|--------|--------------|----------|----------|
|
||||
| **Odbiorcy** | Biznes | Analitycy, projektanci | DBA, developerzy |
|
||||
| **Abstrakcja** | Wysoka | Średnia | Niska |
|
||||
| **DBMS** | Niezależny | Niezależny | Specyficzny |
|
||||
| **Typy danych** | Brak | Logiczne | Natywne DBMS |
|
||||
| **Indeksy** | Brak | Brak | Tak |
|
||||
| **Normalizacja** | Nie | Tak (3NF+) | Może być denorm. |
|
||||
|
||||
---
|
||||
|
||||
### 6. Transformacje między fazami
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ Konceptualny → Logiczny: │
|
||||
│ • Encje → Tabele │
|
||||
│ • Atrybuty → Kolumny │
|
||||
│ • Relacje M:N → Tabele asocjacyjne │
|
||||
│ • Generalizacja → Opcje: single table, class table, concrete │
|
||||
│ • Normalizacja do 3NF/BCNF │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Logiczny → Fizyczny: │
|
||||
│ • Typy logiczne → Typy DBMS (VARCHAR, INTEGER, TIMESTAMP...) │
|
||||
│ • Dodanie indeksów (na FK, WHERE, ORDER BY) │
|
||||
│ • Partycjonowanie dużych tabel │
|
||||
│ • Kontrolowana denormalizacja (wydajność) │
|
||||
│ • Tablespace, storage parameters │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Ewolucja w czasie (produkcja)
|
||||
|
||||
```
|
||||
Wersja 1.0 → 1.1 → 2.0 → ...
|
||||
|
||||
Narzędzia migracji:
|
||||
- Flyway
|
||||
- Liquibase
|
||||
- Django migrations
|
||||
- Alembic (SQLAlchemy)
|
||||
|
||||
Zasady:
|
||||
✓ Backward compatible (add, nie remove)
|
||||
✓ Expand-Contract pattern
|
||||
✓ Zero-downtime migrations
|
||||
✓ Rollback plan
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "C-L-F = Concept, Logic, Physical":
|
||||
Trzy fazy ewolucji modelu
|
||||
|
||||
### "Konceptualny = CO, Logiczny = JAK, Fizyczny = GDZIE":
|
||||
- CO przechowujemy (biznes)
|
||||
- JAK strukturyzujemy (normalizacja)
|
||||
- GDZIE i jak wydajnie (DBMS)
|
||||
|
||||
### "3NF w logicznym, denorm w fizycznym":
|
||||
Normalizuj w logicznym, optymalizuj w fizycznym
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy pominąć fazę konceptualną?"
|
||||
**Odpowiedź:** Małe projekty, proste dziedziny, doświadczony zespół znający domenę. Ale ryzyko: brak wspólnego zrozumienia z biznesem, pominięte wymagania.
|
||||
|
||||
### Q2: "Jak dokumentować model danych?"
|
||||
**Odpowiedź:** ERD (draw.io, Lucidchart, dbdiagram.io), słownik danych (Data Dictionary), komentarze w DDL, wiki z opisem biznesowym, generowana dokumentacja (SchemaSpy).
|
||||
|
||||
### Q3: "Co to jest reverse engineering modelu?"
|
||||
**Odpowiedź:** Generowanie modelu logicznego/konceptualnego z istniejącej bazy (fizycznej). Narzędzia: ERwin, PowerDesigner, DBeaver. Przydatne dla legacy systems.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Konceptualny:** Biznes, encje, relacje, bez technologii
|
||||
2. **Logiczny:** Normalizacja, PK/FK, typy logiczne
|
||||
3. **Fizyczny:** DBMS-specific, indeksy, partycje
|
||||
4. **Transformacja:** Konceptualny → Logiczny → Fizyczny
|
||||
5. **Ewolucja:** Migracje, backward compatibility
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Teorey et al. - "Database Modeling and Design"
|
||||
2. Silberschatz - "Database System Concepts"
|
||||
3. Ambler - "Agile Database Techniques"
|
||||
@ -1,268 +0,0 @@
|
||||
# Pytanie 29: Prawo Amdahla - przyśpieszenie programów równoległych
|
||||
|
||||
## Pytanie
|
||||
**"Oszacować ilościowo przyśpieszenie wykonania programu sekwencyjnego z fragmentami równoległymi na maszynie wielordzeniowej. Co osłabia to ograniczenie?"**
|
||||
|
||||
Przedmiot: PORR (Programowanie Równoległe i Rozproszone)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Prawo Amdahla
|
||||
|
||||
#### Formuła
|
||||
|
||||
$$S(n) = \frac{1}{(1-p) + \frac{p}{n}}$$
|
||||
|
||||
Gdzie:
|
||||
- $S(n)$ = przyśpieszenie (speedup)
|
||||
- $p$ = część programu, która może być zrównoleglona (0 ≤ p ≤ 1)
|
||||
- $n$ = liczba procesorów/rdzeni
|
||||
- $(1-p)$ = część sekwencyjna
|
||||
|
||||
#### Interpretacja graficzna
|
||||
|
||||
```
|
||||
Czas wykonania:
|
||||
|
||||
Sekwencyjny (1 procesor):
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ Sekwencyjna (1-p) │ Równoległa (p) │
|
||||
│ 20% │ 80% │
|
||||
├────────────────────────────┴────────────────────────────────────┤
|
||||
T₁ = 100%
|
||||
|
||||
Równoległy (4 procesory):
|
||||
├────────────────────────────┬────────────────────┤
|
||||
│ Sekwencyjna (1-p) │ Równoległa (p/n) │
|
||||
│ 20% │ 80%/4 = 20% │
|
||||
├────────────────────────────┴────────────────────┤
|
||||
T₄ = 40%
|
||||
|
||||
Speedup = T₁/T₄ = 100/40 = 2.5x
|
||||
```
|
||||
|
||||
#### Przykłady liczbowe
|
||||
|
||||
| p (równoległa) | n=2 | n=4 | n=8 | n=∞ |
|
||||
|----------------|-----|-----|-----|-----|
|
||||
| 50% | 1.33 | 1.60 | 1.78 | 2.00 |
|
||||
| 75% | 1.60 | 2.29 | 3.20 | 4.00 |
|
||||
| 90% | 1.82 | 3.08 | 4.71 | 10.00 |
|
||||
| 95% | 1.90 | 3.48 | 5.93 | 20.00 |
|
||||
| 99% | 1.98 | 3.88 | 7.48 | 100.00 |
|
||||
|
||||
#### Maksymalne przyśpieszenie (n → ∞)
|
||||
|
||||
$$S_{max} = \lim_{n \to \infty} S(n) = \frac{1}{1-p}$$
|
||||
|
||||
```
|
||||
Dla p = 90% (10% sekwencyjnej):
|
||||
S_max = 1/0.1 = 10x
|
||||
|
||||
Nawet z nieskończoną liczbą procesorów,
|
||||
10% kodu sekwencyjnego limituje speedup do 10x!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Wizualizacja ograniczenia
|
||||
|
||||
```
|
||||
Speedup
|
||||
↑
|
||||
20 ┤ ........... p=99%
|
||||
│ ......
|
||||
│ ......
|
||||
15 ┤ .....
|
||||
│ .....
|
||||
│ .... ______ p=95%
|
||||
10 ┤ .... _____/
|
||||
│ ... _____/
|
||||
│ .. ______/ _____ p=90%
|
||||
5 ┤ . _____/ _____/
|
||||
│. _____/ _____/
|
||||
│ ____/ _____/ ____ p=75%
|
||||
2 ┼/ ________/_______________/____
|
||||
1 ┼────────────────────────────────────────────→ Procesory (n)
|
||||
1 4 8 16 32 64 128 256
|
||||
```
|
||||
|
||||
**Obserwacja:** Krzywe szybko się spłaszczają - dodawanie procesorów daje coraz mniejszy zysk.
|
||||
|
||||
---
|
||||
|
||||
### 3. Co osłabia ograniczenie Amdahla?
|
||||
|
||||
#### 3.1 Prawo Gustafsona-Barsisa (Scaled Speedup)
|
||||
|
||||
```
|
||||
Amdahl: Stały problem, więcej procesorów
|
||||
Gustafson: Większy problem, stały czas
|
||||
|
||||
S_scaled(n) = n - (1-p)(n-1) = 1 - p + p·n
|
||||
|
||||
Dla p = 90%, n = 100:
|
||||
S_scaled = 1 - 0.9 + 0.9·100 = 90.1x (vs Amdahl: ~10x)
|
||||
|
||||
Zastosowanie: Symulacje, rendering, ML training
|
||||
- Większy dataset
|
||||
- Więcej iteracji
|
||||
- Wyższa rozdzielczość
|
||||
```
|
||||
|
||||
#### 3.2 Techniki zmniejszania części sekwencyjnej
|
||||
|
||||
| Technika | Opis |
|
||||
|----------|------|
|
||||
| **Algorytmy równoległe** | Zamiana algorytmu sekwencyjnego na równoległy |
|
||||
| **Lock-free structures** | Unikanie synchronizacji blokującej |
|
||||
| **Pipelining** | Nakładanie faz obliczeń |
|
||||
| **Speculative execution** | Równoległe wykonanie alternatyw |
|
||||
| **Data parallelism** | Podział danych zamiast zadań |
|
||||
|
||||
#### 3.3 Ukrywanie latencji
|
||||
|
||||
```
|
||||
Sekwencyjne I/O:
|
||||
CPU: ────compute────│wait│────compute────│wait│────
|
||||
↑ I/O ↑ I/O
|
||||
|
||||
Overlapping (prefetching, async I/O):
|
||||
CPU: ────compute────────compute────────compute────
|
||||
I/O: └──fetch──┘ └──fetch──┘ └──fetch──┘
|
||||
|
||||
Efektywnie zmniejsza (1-p)!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Czynniki zmniejszające rzeczywiste przyśpieszenie
|
||||
|
||||
```
|
||||
S_real < S_Amdahl ze względu na:
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 1. OVERHEAD SYNCHRONIZACJI │
|
||||
│ - Mutex, semaphore contention │
|
||||
│ - Barrier wait time │
|
||||
│ - Lock granularity (coarse vs fine) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 2. KOMUNIKACJA │
|
||||
│ - Przesyłanie danych między wątkami/procesami │
|
||||
│ - Bandwidth limitations │
|
||||
│ - Latency (szczególnie distributed) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 3. LOAD IMBALANCE │
|
||||
│ - Nierówny podział pracy │
|
||||
│ - Różne czasy wykonania task'ów │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 4. CACHE EFFECTS │
|
||||
│ - False sharing │
|
||||
│ - Cache coherency traffic │
|
||||
│ - NUMA effects │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 5. THREAD MANAGEMENT │
|
||||
│ - Tworzenie/niszczenie wątków │
|
||||
│ - Context switching │
|
||||
│ - Thread pool overhead │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### False Sharing
|
||||
|
||||
```c
|
||||
// Zły kod - false sharing
|
||||
struct Counter {
|
||||
int count; // Te pola są w tej samej linii cache!
|
||||
} counters[NUM_THREADS];
|
||||
|
||||
// Thread i:
|
||||
counters[i].count++; // Invaliduje cache innych wątków!
|
||||
|
||||
// Dobry kod - padding
|
||||
struct Counter {
|
||||
int count;
|
||||
char padding[60]; // Separacja na osobne linie cache
|
||||
} counters[NUM_THREADS];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Efektywność równoległa
|
||||
|
||||
$$E(n) = \frac{S(n)}{n} = \frac{1}{n \cdot (1-p) + p}$$
|
||||
|
||||
| p | n=4 | n=16 | n=64 |
|
||||
|---|-----|------|------|
|
||||
| 90% | 77% | 36% | 13% |
|
||||
| 95% | 87% | 55% | 24% |
|
||||
| 99% | 97% | 86% | 61% |
|
||||
|
||||
**Wniosek:** Efektywność spada z liczbą procesorów. Trzeba zwiększać problem (Gustafson) lub zmniejszać (1-p).
|
||||
|
||||
---
|
||||
|
||||
### 6. Rozszerzone prawo Amdahla (z overhead)
|
||||
|
||||
$$S(n) = \frac{1}{(1-p) + \frac{p}{n} + O(n)}$$
|
||||
|
||||
Gdzie $O(n)$ = overhead zależny od n (komunikacja, synchronizacja).
|
||||
|
||||
```
|
||||
Przykład: O(n) = 0.001·n (liniowy overhead)
|
||||
|
||||
n=10: S = 1/(0.1 + 0.09 + 0.01) = 5.0
|
||||
n=100: S = 1/(0.1 + 0.009 + 0.1) = 4.8
|
||||
n=1000: S = 1/(0.1 + 0.0009 + 1) = 0.9 (slowdown!)
|
||||
|
||||
Punkt optymalny: istnieje n* maksymalizujące S!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Amdahl = Sequential is the limit":
|
||||
Część sekwencyjna limituje maksymalne przyśpieszenie
|
||||
|
||||
### "S_max = 1/(1-p)":
|
||||
10% sekwencyjnej → max 10x speedup
|
||||
|
||||
### "Gustafson = Scale the problem":
|
||||
Większy problem → lepsze wykorzystanie procesorów
|
||||
|
||||
### "FLOP = False sharing, Load imbalance, Overhead, Poor locality":
|
||||
Główne przyczyny sublinearnego speedup
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy Gustafson jest lepszy od Amdahla?"
|
||||
**Odpowiedź:** Gdy problem można skalować (więcej danych, iteracji). Symulacje fizyczne, rendering, ML training. Amdahl zakłada stały problem - pesymistyczny dla HPC.
|
||||
|
||||
### Q2: "Jak zmierzyć rzeczywiste p?"
|
||||
**Odpowiedź:** Profilowanie (perf, VTune). Zmierz czas sekwencyjny vs równoległy. p ≈ 1 - T_seq/T_total. Uwaga: p może zależeć od danych wejściowych.
|
||||
|
||||
### Q3: "Co to jest strong vs weak scaling?"
|
||||
**Odpowiedź:** Strong: stały problem, więcej proc. (Amdahl). Weak: problem rośnie proporcjonalnie do proc. (Gustafson). Weak scaling łatwiejsze do osiągnięcia.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Amdahl:** $S = 1/((1-p) + p/n)$, max = $1/(1-p)$
|
||||
2. **Sekwencyjna część limituje** - 10% seq → max 10x
|
||||
3. **Gustafson:** Skaluj problem, nie procesory
|
||||
4. **Overhead:** Sync, komunikacja, cache, load imbalance
|
||||
5. **Efektywność spada** z liczbą procesorów
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Amdahl - "Validity of the Single Processor Approach" (1967)
|
||||
2. Gustafson - "Reevaluating Amdahl's Law" (1988)
|
||||
3. Hennessy, Patterson - "Computer Architecture"
|
||||
@ -1,282 +0,0 @@
|
||||
# Pytanie 30: Modelowanie matematyczne dla problemów decyzyjnych
|
||||
|
||||
## Pytanie
|
||||
**"Omówić metody oraz typowe problemy w modelowaniu matematycznym dla problemów decyzyjnych i optymalizacyjnych."**
|
||||
|
||||
Przedmiot: MOM (Metody Optymalizacji Matematycznej)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Struktura modelu matematycznego
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ MODEL OPTYMALIZACYJNY │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ min/max f(x) ← Funkcja celu │
|
||||
│ │
|
||||
│ subject to: │
|
||||
│ g_i(x) ≤ 0 ← Ograniczenia nierównościowe │
|
||||
│ h_j(x) = 0 ← Ograniczenia równościowe │
|
||||
│ x ∈ X ← Dziedzina zmiennych │
|
||||
│ │
|
||||
│ gdzie x = (x₁, x₂, ..., xₙ) ∈ ℝⁿ (lub ℤⁿ, {0,1}ⁿ) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Metody modelowania
|
||||
|
||||
#### 2.1 Etapy tworzenia modelu
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ PROBLEM │ → │ MODEL │ → │ ROZWIĄZANIE│ → │ WALIDACJA │
|
||||
│ RZECZYWISTY│ │ MATEMATYCZNY│ │ OPTYMALNE │ │ I WDROŻENIE│
|
||||
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
||||
│ │ │ │
|
||||
↓ ↓ ↓ ↓
|
||||
Analiza Zmienne, Solver, Interpretacja,
|
||||
wymagań funkcja celu, algorytm analiza wrażliwości
|
||||
ograniczenia
|
||||
```
|
||||
|
||||
#### 2.2 Typy modeli
|
||||
|
||||
| Typ | Charakterystyka | Przykład |
|
||||
|-----|-----------------|----------|
|
||||
| **LP** (Linear Programming) | Liniowa f(x), liniowe g, h | Transport, alokacja |
|
||||
| **QP** (Quadratic) | Kwadratowa f(x), liniowe ograniczenia | Portfolio |
|
||||
| **NLP** (Nonlinear) | Nieliniowe f, g lub h | Engineering design |
|
||||
| **MIP** (Mixed Integer) | Zmienne ciągłe + całkowite | Scheduling, routing |
|
||||
| **MINLP** | Całkowitoliczbowe + nieliniowe | Najtrudniejsze |
|
||||
|
||||
---
|
||||
|
||||
### 3. Typowe problemy w modelowaniu
|
||||
|
||||
#### 3.1 Wybór zmiennych decyzyjnych
|
||||
|
||||
```
|
||||
Problem: Ile zmiennych? Jakie typy?
|
||||
|
||||
Przykład - planowanie produkcji:
|
||||
|
||||
Źle: x = "plan produkcji" (zbyt ogólne)
|
||||
|
||||
Dobrze:
|
||||
x_it = ilość produktu i w okresie t (ciągła)
|
||||
y_it = czy produkujemy i w t (binarna)
|
||||
z_ijt = transport z i do j w t (całkowita)
|
||||
|
||||
Zasady:
|
||||
✓ Zmienne muszą być mierzalne
|
||||
✓ Zmienne muszą być kontrolowalne
|
||||
✓ Minimalna liczba dla pełnego opisu
|
||||
```
|
||||
|
||||
#### 3.2 Problem Big-M
|
||||
|
||||
```
|
||||
Modelowanie implikacji: y=1 → x ≤ 5
|
||||
|
||||
Zła formulacja (słaba relaksacja):
|
||||
x ≤ 5 + M(1-y), gdzie M = 10^6
|
||||
|
||||
Lepsza formulacja:
|
||||
x ≤ 5 + (UB_x - 5)(1-y), gdzie UB_x = upper bound na x
|
||||
|
||||
Indicator constraints (jeśli solver wspiera):
|
||||
y = 1 → x ≤ 5 (bezpośrednio)
|
||||
|
||||
Problem: Duże M → słaba LP relaxation → wolny B&B
|
||||
```
|
||||
|
||||
#### 3.3 Symetria
|
||||
|
||||
```
|
||||
Problem: Wiele równoważnych rozwiązań optymalnych
|
||||
|
||||
Przykład - bin packing:
|
||||
Bin 1: {A, B}, Bin 2: {C}
|
||||
Bin 1: {C}, Bin 2: {A, B} ← ta sama wartość!
|
||||
|
||||
Rozwiązanie - symmetry breaking:
|
||||
x[i][1] ≥ x[i][2] ≥ x[i][3] ... (lexicographic ordering)
|
||||
|
||||
Lub: użyj indeksu pierwszego użycia pojemnika
|
||||
```
|
||||
|
||||
#### 3.4 Walidacja modelu
|
||||
|
||||
| Test | Opis |
|
||||
|------|------|
|
||||
| **Extreme cases** | Czy model działa dla skrajnych danych? |
|
||||
| **Known solutions** | Czy odtwarza znane rozwiązania? |
|
||||
| **Dimensional analysis** | Czy jednostki się zgadzają? |
|
||||
| **Sensitivity analysis** | Jak rozwiązanie reaguje na zmiany? |
|
||||
| **Infeasibility** | Czy model ma rozwiązanie dopuszczalne? |
|
||||
|
||||
---
|
||||
|
||||
### 4. Techniki modelowania
|
||||
|
||||
#### 4.1 Linearyzacja
|
||||
|
||||
```
|
||||
Problem: xy (iloczyn zmiennych ciągłych)
|
||||
|
||||
McCormick envelopes:
|
||||
w ≥ x·LB_y + y·LB_x - LB_x·LB_y
|
||||
w ≥ x·UB_y + y·UB_x - UB_x·UB_y
|
||||
w ≤ x·LB_y + y·UB_x - LB_y·UB_x
|
||||
w ≤ x·UB_y + y·LB_x - UB_y·LB_x
|
||||
|
||||
Problem: |x| (wartość bezwzględna)
|
||||
|
||||
Modelowanie:
|
||||
min z
|
||||
z ≥ x
|
||||
z ≥ -x
|
||||
```
|
||||
|
||||
#### 4.2 Modelowanie warunków logicznych
|
||||
|
||||
```
|
||||
Alternatywa (OR): x ≤ 5 ∨ y ≤ 3
|
||||
|
||||
x ≤ 5 + M(1-z)
|
||||
y ≤ 3 + Mz
|
||||
z ∈ {0,1}
|
||||
|
||||
Koniunkcja (AND): x ≤ 5 ∧ y ≤ 3
|
||||
|
||||
x ≤ 5
|
||||
y ≤ 3 (po prostu oba ograniczenia)
|
||||
```
|
||||
|
||||
#### 4.3 Piece-wise linear functions
|
||||
|
||||
```
|
||||
f(x) = różne liniowe segmenty
|
||||
|
||||
f(x)
|
||||
↑
|
||||
│ /
|
||||
│ /
|
||||
│ /
|
||||
│ /____
|
||||
│/
|
||||
└────────→ x
|
||||
|
||||
Modelowanie SOS2 (Special Ordered Set type 2):
|
||||
f(x) = Σ λ_i · f(breakpoint_i)
|
||||
x = Σ λ_i · breakpoint_i
|
||||
Σ λ_i = 1
|
||||
λ ≥ 0, max 2 sąsiednie λ_i > 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Wielokryterialne podejmowanie decyzji
|
||||
|
||||
```
|
||||
min f₁(x), f₂(x), ..., f_k(x) ← konfliktujące cele
|
||||
|
||||
Metody:
|
||||
|
||||
1. WEIGHTED SUM:
|
||||
min Σ w_i · f_i(x)
|
||||
Problem: nie znajduje wszystkich Pareto-optymalnych
|
||||
|
||||
2. ε-CONSTRAINT:
|
||||
min f₁(x)
|
||||
s.t. f_i(x) ≤ ε_i, i=2..k
|
||||
|
||||
3. GOAL PROGRAMMING:
|
||||
min Σ |f_i(x) - target_i|
|
||||
|
||||
4. PARETO FRONT:
|
||||
Znajdź wszystkie niezdominowane rozwiązania
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Analiza wrażliwości
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Co się zmieni gdy zmienią się dane wejściowe? │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Shadow price (dual variable): │
|
||||
│ - Ile warta jest jednostka zasobu? │
|
||||
│ - Δf = λ · Δb (dla małych zmian RHS) │
|
||||
│ │
|
||||
│ Reduced cost: │
|
||||
│ - O ile musi się zmienić c_j żeby x_j wszedł do bazy? │
|
||||
│ │
|
||||
│ Range analysis: │
|
||||
│ - Przedział zmian parametrów bez zmiany optymalnej bazy │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Częste błędy
|
||||
|
||||
| Błąd | Konsekwencja | Rozwiązanie |
|
||||
|------|--------------|-------------|
|
||||
| **Brak bounds** | Unbounded lub słaba relaxation | Zawsze definiuj LB, UB |
|
||||
| **Za duże M** | Numerical issues, wolne | Tight big-M |
|
||||
| **Redundantne ograniczenia** | Wolniejsze, confusion | Minimalizuj |
|
||||
| **Zła skala** | Numerical instability | Scaling, rescaling |
|
||||
| **Over-modeling** | Za złożone, wolne | Simplify, aggregate |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "VCO = Variables, Constraints, Objective":
|
||||
Trzy elementy modelu matematycznego
|
||||
|
||||
### "Big-M = Big Mistake (jeśli źle użyte)":
|
||||
Unikaj dużych M, tight bounds
|
||||
|
||||
### "PASS = Pareto, Analysis, Sensitivity, Symmetry":
|
||||
Kluczowe zagadnienia zaawansowane
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jak sprawdzić czy model jest poprawny?"
|
||||
**Odpowiedź:** Testy na znanych instancjach, extreme cases, dimensional analysis, sprawdzenie czy relaksacja LP daje sensowne wyniki, analiza IIS dla infeasible.
|
||||
|
||||
### Q2: "Kiedy linearyzować a kiedy użyć NLP?"
|
||||
**Odpowiedź:** Linearyzuj gdy: nieliniowość jest "miękka", solver MIP szybszy niż NLP, potrzebujesz gwarancji optimum. NLP gdy: silna nieliniowość, ciągłe zmienne, akceptowalny local optimum.
|
||||
|
||||
### Q3: "Jak obsłużyć niepewność w modelu?"
|
||||
**Odpowiedź:** Stochastic programming (scenariusze), robust optimization (worst-case), chance constraints, sensitivity analysis. Wybór zależy od charakteru niepewności.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Model:** Zmienne + funkcja celu + ograniczenia
|
||||
2. **Big-M:** Unikaj dużych M, tight formulation
|
||||
3. **Symetria:** Symmetry breaking constraints
|
||||
4. **Walidacja:** Extreme cases, known solutions
|
||||
5. **Wrażliwość:** Shadow prices, reduced costs
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Williams - "Model Building in Mathematical Programming"
|
||||
2. Wolsey - "Integer Programming"
|
||||
3. Nemhauser, Wolsey - "Integer and Combinatorial Optimization"
|
||||
@ -1,317 +0,0 @@
|
||||
# Pytanie 31: Wypukłość i nieliniowość w systemach decyzyjnych
|
||||
|
||||
## Pytanie
|
||||
**"Wyjaśnić główne zagadnienia modelowania matematycznego w systemach decyzyjnych z wykorzystaniem pojęć (nie)wypukłości i (nie)liniowości."**
|
||||
|
||||
Przedmiot: MOM (Metody Optymalizacji Matematycznej)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Klasyfikacja problemów optymalizacyjnych
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ KLASYFIKACJA PROBLEMÓW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ LINIOWE NIELINIOWE │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ LP │ │ NLP │ │
|
||||
│ │ Simplex, │ │ Gradient, │ │
|
||||
│ │ Interior │ │ Newton, │ │
|
||||
│ │ Point │ │ SQP │ │
|
||||
│ └─────────────┘ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────┴───────────┐ │
|
||||
│ │ │ │
|
||||
│ WYPUKŁE NIEWYPUKŁE │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Convex NLP │ │ Non-convex │ │
|
||||
│ │ Global opt │ │ Local opt │ │
|
||||
│ │ gwarantowane│ │ NP-trudne │ │
|
||||
│ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Definicje kluczowe
|
||||
|
||||
#### Zbiór wypukły
|
||||
|
||||
$$S \text{ wypukły} \Leftrightarrow \forall x,y \in S, \forall \lambda \in [0,1]: \lambda x + (1-\lambda)y \in S$$
|
||||
|
||||
```
|
||||
WYPUKŁY: NIEWYPUKŁY:
|
||||
●───────● ●───────●
|
||||
/ \ / ↗ \
|
||||
/ \ / / \
|
||||
/ \ /___/ \
|
||||
● ● ● ●
|
||||
Każdy odcinek Odcinek wychodzi
|
||||
wewnątrz zbioru poza zbiór
|
||||
```
|
||||
|
||||
#### Funkcja wypukła
|
||||
|
||||
$$f \text{ wypukła} \Leftrightarrow f(\lambda x + (1-\lambda)y) \leq \lambda f(x) + (1-\lambda) f(y)$$
|
||||
|
||||
```
|
||||
f(x)
|
||||
↑
|
||||
│ Funkcja wypukła
|
||||
│ /\
|
||||
│ / \
|
||||
│ / \ Cięciwa zawsze
|
||||
│ /──────\ powyżej wykresu
|
||||
│ / \
|
||||
│ / \
|
||||
└────────────────→ x
|
||||
|
||||
f(x)
|
||||
↑ Funkcja wklęsła (concave)
|
||||
│ ________
|
||||
│ / \
|
||||
│ / \ Cięciwa zawsze
|
||||
│ /────────────\ poniżej wykresu
|
||||
│/ \
|
||||
└────────────────→ x
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Znaczenie wypukłości
|
||||
|
||||
#### Własności problemów wypukłych
|
||||
|
||||
| Własność | Opis |
|
||||
|----------|------|
|
||||
| **Global = Local** | Każde minimum lokalne jest globalne |
|
||||
| **Jednoznaczność** | Zbiór optymalnych jest wypukły |
|
||||
| **Efektywność** | Algorytmy wielomianowe (interior point) |
|
||||
| **Dualność** | Silna dualność (zero duality gap) |
|
||||
| **Warunki KKT** | Wystarczające dla optimum |
|
||||
|
||||
#### Porównanie złożoności
|
||||
|
||||
```
|
||||
Problem │ Złożoność │ Gwarancja
|
||||
─────────────────┼────────────────┼──────────────
|
||||
LP │ Wielomianowa │ Globalne opt.
|
||||
Convex QP │ Wielomianowa │ Globalne opt.
|
||||
Convex NLP │ Wielomianowa │ Globalne opt.
|
||||
Non-convex NLP │ NP-trudna │ Lokalne opt.
|
||||
MINLP │ NP-trudna │ (zależy)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Liniowość vs nieliniowość
|
||||
|
||||
#### Programowanie liniowe (LP)
|
||||
|
||||
$$\min c^T x \quad \text{s.t.} \quad Ax \leq b, \quad x \geq 0$$
|
||||
|
||||
```
|
||||
Cechy LP:
|
||||
✓ Optimum w wierzchołku (jeśli istnieje)
|
||||
✓ Simplex: pivotuje między wierzchołkami
|
||||
✓ Interior Point: przez wnętrze
|
||||
✓ Zawsze wypukłe
|
||||
✓ Silna dualność
|
||||
```
|
||||
|
||||
#### Programowanie nieliniowe (NLP)
|
||||
|
||||
$$\min f(x) \quad \text{s.t.} \quad g_i(x) \leq 0, \quad h_j(x) = 0$$
|
||||
|
||||
```
|
||||
Typy nieliniowości:
|
||||
|
||||
1. Kwadratowa (QP):
|
||||
min x'Qx + c'x s.t. Ax ≤ b
|
||||
|
||||
Q ≻ 0 (dodatnio określona) → wypukłe
|
||||
Q ma ujemne eigenvalues → niewypukłe
|
||||
|
||||
2. Ogólna nieliniowa:
|
||||
min sin(x) + x²·y
|
||||
s.t. x² + y² ≤ 1
|
||||
|
||||
Może być wypukła lub nie
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Testowanie wypukłości
|
||||
|
||||
#### Dla funkcji
|
||||
|
||||
```
|
||||
f(x) jest wypukła jeśli:
|
||||
|
||||
1. HESJAN: H = ∇²f(x) ≽ 0 (dodatnio półokreślony) dla wszystkich x
|
||||
|
||||
2. Kompozycja:
|
||||
- Suma wypukłych → wypukła
|
||||
- max(f, g) gdzie f, g wypukłe → wypukła
|
||||
- f(Ax+b) gdzie f wypukła → wypukła
|
||||
|
||||
3. Znane funkcje wypukłe:
|
||||
- x², eˣ, -log(x), |x|, max(x,0)
|
||||
- Normy: ||x||₁, ||x||₂
|
||||
```
|
||||
|
||||
#### Dla zbiorów
|
||||
|
||||
```
|
||||
Zbiór S jest wypukły jeśli:
|
||||
|
||||
1. Przekrój wypukłych → wypukły
|
||||
2. {x: Ax ≤ b} → wielościan (wypukły)
|
||||
3. {x: ||x||₂ ≤ r} → kula (wypukła)
|
||||
4. {x: f(x) ≤ α} gdzie f wypukła → sublevel set (wypukły)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Problemy niewypukłe
|
||||
|
||||
#### Konsekwencje
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PROBLEM NIEWYPUKŁY: │
|
||||
│ │
|
||||
│ f(x) │
|
||||
│ ↑ ● │
|
||||
│ │ / \ ● ← lokalne minimum │
|
||||
│ │ / \ /│\ │
|
||||
│ │ / \ / │ \ │
|
||||
│ │ / \/ │ \ │
|
||||
│ │ / ● │ \ ● ← globalne minimum │
|
||||
│ │ / local │ \ / │
|
||||
│ │ / min │ \/ │
|
||||
│ └────────────────────────→ x │
|
||||
│ │
|
||||
│ Algorytmy gradientowe znajdą LOKALNE minimum! │
|
||||
│ Nie ma gwarancji znalezienia globalnego. │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Strategie dla niewypukłych
|
||||
|
||||
| Strategia | Opis |
|
||||
|-----------|------|
|
||||
| **Multi-start** | Wiele punktów startowych |
|
||||
| **Global solvers** | BARON, Couenne, SCIP |
|
||||
| **Relaxation** | Convex relaxation + B&B |
|
||||
| **Metaheurystyki** | GA, SA, PSO |
|
||||
| **Reformulation** | Przeformułuj na wypukły |
|
||||
|
||||
---
|
||||
|
||||
### 7. Przykłady praktyczne
|
||||
|
||||
#### Wypukły - Portfolio optimization
|
||||
|
||||
```
|
||||
Markowitz:
|
||||
min x'Σx (wariancja, Q = Σ ≻ 0 → wypukłe!)
|
||||
s.t. μ'x ≥ r (minimalny zwrot)
|
||||
Σx_i = 1 (pełna inwestycja)
|
||||
x ≥ 0 (brak short selling)
|
||||
|
||||
Jest WYPUKŁY → globalne optimum gwarantowane
|
||||
```
|
||||
|
||||
#### Niewypukły - Pooling problem
|
||||
|
||||
```
|
||||
Mieszanie strumieni o różnych jakościach:
|
||||
|
||||
q_out = Σ(q_i · flow_i) / Σ flow_i
|
||||
|
||||
Zawiera ILOCZYN zmiennych (bilinear) → NIEWYPUKŁY
|
||||
Tylko lokalne optimum gwarantowane (chyba że global solver)
|
||||
```
|
||||
|
||||
#### Granica - SVM
|
||||
|
||||
```
|
||||
Hard margin SVM (separowalne dane):
|
||||
min ||w||²
|
||||
s.t. y_i(w·x_i + b) ≥ 1
|
||||
|
||||
Jest WYPUKŁY (QP z liniowymi ograniczeniami)
|
||||
|
||||
Kernel SVM - nadal wypukły w przestrzeni dualnej!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. Dualność
|
||||
|
||||
```
|
||||
Primal (P): Dual (D):
|
||||
min f(x) max L(λ, μ)
|
||||
s.t. g(x) ≤ 0 s.t. λ ≥ 0
|
||||
h(x) = 0
|
||||
|
||||
Lagrangian: L(x,λ,μ) = f(x) + λᵀg(x) + μᵀh(x)
|
||||
|
||||
SŁABA DUALNOŚĆ (zawsze):
|
||||
d* ≤ p* (dual ≤ primal)
|
||||
|
||||
SILNA DUALNOŚĆ (dla wypukłych + constraint qualification):
|
||||
d* = p* (zero duality gap)
|
||||
|
||||
Duality gap dla niewypukłych może być > 0!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Convex = Global Local":
|
||||
Dla wypukłych: każde lokalne = globalne
|
||||
|
||||
### "Hesjan ≻ 0 = wypukłe":
|
||||
Dodatnio określona macierz drugich pochodnych
|
||||
|
||||
### "LP ⊂ QP ⊂ Convex NLP":
|
||||
Każdy LP jest QP, każdy QP (z Q≥0) jest Convex NLP
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jak rozpoznać czy problem jest wypukły?"
|
||||
**Odpowiedź:** Sprawdź: (1) czy f celu ma Hesjan ≥ 0, (2) czy ograniczenia nierównościowe g_i są wypukłe, (3) czy ograniczenia równościowe h_j są liniowe. Jeśli wszystkie TAK → wypukły.
|
||||
|
||||
### Q2: "Co zrobić gdy problem jest niewypukły?"
|
||||
**Odpowiedź:** Multi-start, global solvers (BARON), convex relaxation, reformulation (np. SDP relaxation dla QCQP), metaheurystyki, decomposition methods.
|
||||
|
||||
### Q3: "Czy MILP jest wypukły?"
|
||||
**Odpowiedź:** Nie w klasycznym sensie (zmienne dyskretne). Ale LP relaxation jest wypukła. Branch & Bound wykorzystuje wypukłość relaksacji do pruning.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Wypukłość:** Global = Local, efektywne algorytmy
|
||||
2. **Niewypukłość:** Wiele minimów lokalnych, NP-trudne
|
||||
3. **Hesjan:** ∇²f ≥ 0 → funkcja wypukła
|
||||
4. **LP zawsze wypukły**, QP zależy od Q
|
||||
5. **Silna dualność** dla wypukłych
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Boyd, Vandenberghe - "Convex Optimization"
|
||||
2. Nocedal, Wright - "Numerical Optimization"
|
||||
3. Bazaraa et al. - "Nonlinear Programming"
|
||||
@ -1,309 +0,0 @@
|
||||
# Pytanie 32: Komunikacja synchroniczna/asynchroniczna, blokująca/nieblokująca
|
||||
|
||||
## Pytanie
|
||||
**"Podać definicję komunikacji synchronicznej i asynchronicznej oraz blokującej i nieblokującej. Jak uniknąć zakleszczenia, gdy dwa symetryczne procesy (np. realizujące algorytm iteracyjny Jacobiego) mają w kodzie następujące po sobie wywołania funkcji wysyłającej komunikat do partnera i odbierającej komunikat wysłany przez niego?"**
|
||||
|
||||
Przedmiot: PORR (Programowanie Równoległe i Rozproszone)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Definicje podstawowe
|
||||
|
||||
#### Synchroniczna vs Asynchroniczna
|
||||
|
||||
```
|
||||
KOMUNIKACJA SYNCHRONICZNA:
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Nadawca i odbiorca synchronizują się w momencie przekazania │
|
||||
│ │
|
||||
│ Proces A Proces B │
|
||||
│ │ │ │
|
||||
│ │ send() ──────────────────> recv() │
|
||||
│ │ [czeka aż B odbierze] [odbiera] │
|
||||
│ │ [kontynuuje] │ │
|
||||
│ │
|
||||
│ Gwarancja: Po powrocie z send() wiadomość została odebrana │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
KOMUNIKACJA ASYNCHRONICZNA:
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Nadawca nie czeka na odbiorcę │
|
||||
│ │
|
||||
│ Proces A Proces B │
|
||||
│ │ │ │
|
||||
│ │ send() ─────────> [bufor] ───> recv() │
|
||||
│ │ [kontynuuje │ (później) │
|
||||
│ │ natychmiast] │ │
|
||||
│ │
|
||||
│ Gwarancja: Wiadomość trafiła do bufora (nie do odbiorcy!) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Blokująca vs Nieblokująca
|
||||
|
||||
```
|
||||
OPERACJA BLOKUJĄCA:
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Wywołanie nie zwraca kontroli do wołającego dopóki operacja │
|
||||
│ nie zostanie zakończona (lub warunek spełniony) │
|
||||
│ │
|
||||
│ Proces: send() │
|
||||
│ ├─────────────────────┤ │
|
||||
│ │ BLOKADA │ │
|
||||
│ │ (czeka na coś) │ │
|
||||
│ └─────────────────────┘ │
|
||||
│ return │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
OPERACJA NIEBLOKUJĄCA:
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Wywołanie zwraca natychmiast, operacja wykonuje się w tle │
|
||||
│ │
|
||||
│ Proces: isend() → return immediately │
|
||||
│ │ │
|
||||
│ │ (inne obliczenia) │
|
||||
│ │ │
|
||||
│ wait() lub test() ← sprawdź czy zakończone │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Kombinacje w MPI
|
||||
|
||||
| Funkcja MPI | Blokująca? | Synchroniczna? | Opis |
|
||||
|-------------|------------|----------------|------|
|
||||
| `MPI_Send` | Blokująca | Zależne od impl. | Standard send |
|
||||
| `MPI_Ssend` | Blokująca | Synchroniczna | Czeka na recv |
|
||||
| `MPI_Bsend` | Blokująca | Asynchroniczna | Buforowana |
|
||||
| `MPI_Rsend` | Blokująca | - | Ready (recv musi czekać) |
|
||||
| `MPI_Isend` | Nieblokująca | Asynchroniczna | Immediate |
|
||||
| `MPI_Recv` | Blokująca | - | Standard recv |
|
||||
| `MPI_Irecv` | Nieblokująca | - | Immediate recv |
|
||||
|
||||
---
|
||||
|
||||
### 3. Problem zakleszczenia (Deadlock)
|
||||
|
||||
#### Scenariusz: Algorytm Jacobiego
|
||||
|
||||
```c
|
||||
// DEADLOCK! - oba procesy czekają na siebie nawzajem
|
||||
|
||||
// Proces 0: // Proces 1:
|
||||
MPI_Send(to=1, data); MPI_Send(to=0, data);
|
||||
MPI_Recv(from=1, data); MPI_Recv(from=0, data);
|
||||
|
||||
Przebieg:
|
||||
┌──────────────────┬──────────────────┐
|
||||
│ PROCES 0 │ PROCES 1 │
|
||||
├──────────────────┼──────────────────┤
|
||||
│ Send(to=1) │ Send(to=0) │
|
||||
│ [BLOKUJE - czeka │ [BLOKUJE - czeka │
|
||||
│ aż 1 odbierze] │ aż 0 odbierze] │
|
||||
│ ↓ │ ↓ │
|
||||
│ DEADLOCK! │ DEADLOCK! │
|
||||
│ (nikt nie robi │ (nikt nie robi │
|
||||
│ Recv) │ Recv) │
|
||||
└──────────────────┴──────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Rozwiązania problemu zakleszczenia
|
||||
|
||||
#### 4.1 Zmiana kolejności operacji
|
||||
|
||||
```c
|
||||
// Proces 0: // Proces 1:
|
||||
MPI_Send(to=1, data); MPI_Recv(from=0, data); // ← zmiana!
|
||||
MPI_Recv(from=1, data); MPI_Send(to=0, data);
|
||||
|
||||
Przebieg:
|
||||
┌──────────────────┬──────────────────┐
|
||||
│ PROCES 0 │ PROCES 1 │
|
||||
├──────────────────┼──────────────────┤
|
||||
│ Send(to=1) ──────│──→ Recv(from=0) │
|
||||
│ [zakończone] │ [zakończone] │
|
||||
│ Recv(from=1) ←───│─── Send(to=0) │
|
||||
│ [zakończone] │ [zakończone] │
|
||||
└──────────────────┴──────────────────┘
|
||||
✓ Brak deadlocka!
|
||||
```
|
||||
|
||||
#### 4.2 Nieblokujące operacje
|
||||
|
||||
```c
|
||||
// Oba procesy:
|
||||
MPI_Request req_send, req_recv;
|
||||
|
||||
MPI_Irecv(from=partner, data_in, &req_recv); // Nieblokujące recv
|
||||
MPI_Isend(to=partner, data_out, &req_send); // Nieblokujące send
|
||||
MPI_Wait(&req_recv, &status); // Czekaj na recv
|
||||
MPI_Wait(&req_send, &status); // Czekaj na send
|
||||
|
||||
Przebieg:
|
||||
┌──────────────────┬──────────────────┐
|
||||
│ PROCES 0 │ PROCES 1 │
|
||||
├──────────────────┼──────────────────┤
|
||||
│ Irecv (posted) │ Irecv (posted) │
|
||||
│ Isend (posted) │ Isend (posted) │
|
||||
│ ↓ ↓ │ ↓ ↓ │
|
||||
│ [operacje w tle] │ [operacje w tle] │
|
||||
│ Wait (recv done) │ Wait (recv done) │
|
||||
│ Wait (send done) │ Wait (send done) │
|
||||
└──────────────────┴──────────────────┘
|
||||
✓ Brak deadlocka!
|
||||
```
|
||||
|
||||
#### 4.3 MPI_Sendrecv
|
||||
|
||||
```c
|
||||
// Oba procesy (najczystsze rozwiązanie):
|
||||
MPI_Sendrecv(
|
||||
send_buf, send_count, type, dest, send_tag,
|
||||
recv_buf, recv_count, type, source, recv_tag,
|
||||
comm, &status
|
||||
);
|
||||
|
||||
// Wewnętrznie implementuje bezpieczną wymianę
|
||||
// Unika deadlocka automatycznie
|
||||
```
|
||||
|
||||
#### 4.4 Buforowane wysyłanie
|
||||
|
||||
```c
|
||||
// Attach buffer
|
||||
char buffer[BUFFER_SIZE];
|
||||
MPI_Buffer_attach(buffer, BUFFER_SIZE);
|
||||
|
||||
// Oba procesy:
|
||||
MPI_Bsend(to=partner, data); // Kopiuje do bufora i wraca
|
||||
MPI_Recv(from=partner, data); // Teraz może odebrać
|
||||
|
||||
MPI_Buffer_detach(&buffer, &size);
|
||||
|
||||
// Działa gdy bufor wystarczająco duży
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Porównanie rozwiązań
|
||||
|
||||
| Rozwiązanie | Zalety | Wady |
|
||||
|-------------|--------|------|
|
||||
| **Zmiana kolejności** | Proste, brak overhead | Wymaga asymetrii kodu |
|
||||
| **Isend/Irecv** | Elastyczne, overlap | Złożoność kodu |
|
||||
| **Sendrecv** | Proste, bezpieczne | Mniej elastyczne |
|
||||
| **Bsend** | Podobne do standardowego | Wymaga bufora, memory |
|
||||
|
||||
---
|
||||
|
||||
### 6. Algorytm Jacobiego - pełny przykład
|
||||
|
||||
```c
|
||||
// Iteracyjne rozwiązanie równania Laplace'a
|
||||
// Grid podzielony między procesy
|
||||
|
||||
for (int iter = 0; iter < MAX_ITER; iter++) {
|
||||
// Wymiana granic z sąsiadami
|
||||
|
||||
// Bezpieczna wymiana z lewym sąsiadem
|
||||
if (rank > 0) {
|
||||
MPI_Sendrecv(
|
||||
&u[1], 1, MPI_DOUBLE, rank-1, 0, // wyślij lewą granicę
|
||||
&u[0], 1, MPI_DOUBLE, rank-1, 0, // odbierz od lewego
|
||||
MPI_COMM_WORLD, &status
|
||||
);
|
||||
}
|
||||
|
||||
// Bezpieczna wymiana z prawym sąsiadem
|
||||
if (rank < size-1) {
|
||||
MPI_Sendrecv(
|
||||
&u[n-2], 1, MPI_DOUBLE, rank+1, 0, // wyślij prawą granicę
|
||||
&u[n-1], 1, MPI_DOUBLE, rank+1, 0, // odbierz od prawego
|
||||
MPI_COMM_WORLD, &status
|
||||
);
|
||||
}
|
||||
|
||||
// Obliczenia Jacobiego
|
||||
for (int i = 1; i < n-1; i++) {
|
||||
u_new[i] = 0.5 * (u[i-1] + u[i+1]);
|
||||
}
|
||||
|
||||
swap(&u, &u_new);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Wzorce komunikacji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ RING (pierścień) - każdy z sąsiadami: │
|
||||
│ │
|
||||
│ ┌───→ P0 ───→ P1 ───→ P2 ───→ P3 ───┐ │
|
||||
│ └──────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Bezpieczne: Sendrecv w jednym kierunku │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ALL-TO-ALL - każdy z każdym: │
|
||||
│ │
|
||||
│ P0 ←→ P1 │
|
||||
│ P0 ←→ P2 │
|
||||
│ P1 ←→ P2 │
|
||||
│ ... │
|
||||
│ │
|
||||
│ Rozwiązanie: MPI_Alltoall lub ordered pairwise exchange │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "S-B Matrix":
|
||||
| | Sync | Async |
|
||||
|---|---|---|
|
||||
| **Block** | Ssend | Send/Bsend |
|
||||
| **Non-block** | - | Isend |
|
||||
|
||||
### "I = Immediate = Non-blocking":
|
||||
MPI_Isend, MPI_Irecv - nieblokujące (I na początku)
|
||||
|
||||
### "Sendrecv = Safe exchange":
|
||||
Jedna funkcja, zero deadlocków
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Czy MPI_Send jest synchroniczne?"
|
||||
**Odpowiedź:** Zależy od implementacji i rozmiaru! Małe wiadomości często buforowane (async), duże mogą być sync. MPI_Ssend zawsze sync, MPI_Bsend zawsze async (buforowane).
|
||||
|
||||
### Q2: "Jak wykryć potencjalny deadlock?"
|
||||
**Odpowiedź:** Analiza statyczna grafu zależności send/recv. Narzędzia: MUST, Marmot. Runtime: timeouty, watchdog. Zasada: unikaj cykli w grafie oczekiwań.
|
||||
|
||||
### Q3: "Co to jest eager vs rendezvous protocol?"
|
||||
**Odpowiedź:** Eager: małe msg kopiowane do bufora natychmiast (async). Rendezvous: duże msg - handshake send/recv przed transferem (sync). Threshold zależy od implementacji MPI.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Synchroniczna:** Nadawca czeka na odbiorcę
|
||||
2. **Blokująca:** Funkcja nie wraca do zakończenia
|
||||
3. **Deadlock:** Cykliczne oczekiwanie (Send-Send)
|
||||
4. **Rozwiązania:** Sendrecv, Isend/Irecv, zmiana kolejności
|
||||
5. **MPI_I*** = nieblokujące (Immediate)
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. MPI Standard (mpi-forum.org)
|
||||
2. Gropp et al. - "Using MPI"
|
||||
3. Pacheco - "Parallel Programming with MPI"
|
||||
@ -1,334 +0,0 @@
|
||||
# Pytanie 33: Model publikuj-subskrybuj (Pub/Sub)
|
||||
|
||||
## Pytanie
|
||||
**"Scharakteryzować model przesyłania komunikatów publikuj-subskrybuj oraz przykładowe rozwiązania techniczne wykorzystujące ten model."**
|
||||
|
||||
Przedmiot: PSD (Przetwarzanie Strumieniowe Danych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Definicja modelu Pub/Sub
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ MODEL PUBLISH-SUBSCRIBE │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ PUBLISHERS BROKER SUBSCRIBERS │
|
||||
│ (nadawcy) (pośrednik) (odbiorcy) │
|
||||
│ │
|
||||
│ ┌─────┐ ┌─────────┐ ┌─────┐ │
|
||||
│ │ P1 │ ──publish──→ │ │ ──────→ │ S1 │ │
|
||||
│ └─────┘ topic:A │ │ topic:A └─────┘ │
|
||||
│ │ MESSAGE │ │
|
||||
│ ┌─────┐ │ BROKER │ ┌─────┐ │
|
||||
│ │ P2 │ ──publish──→ │ │ ──────→ │ S2 │ │
|
||||
│ └─────┘ topic:B │ (router)│ topic:A └─────┘ │
|
||||
│ │ │ topic:B │
|
||||
│ ┌─────┐ │ │ ┌─────┐ │
|
||||
│ │ P3 │ ──publish──→ │ │ ──────→ │ S3 │ │
|
||||
│ └─────┘ topic:A └─────────┘ topic:B └─────┘ │
|
||||
│ │
|
||||
│ Cechy: │
|
||||
│ • Luźne powiązanie (publisher nie zna subscriberów) │
|
||||
│ • Asynchroniczność │
|
||||
│ • Skalowalność (1:N, N:M) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Typy subskrypcji
|
||||
|
||||
| Typ | Opis | Przykład |
|
||||
|-----|------|----------|
|
||||
| **Topic-based** | Subskrypcja na nazwany temat | `subscribe("orders")` |
|
||||
| **Content-based** | Filtrowanie po zawartości | `price > 100 AND category = "electronics"` |
|
||||
| **Type-based** | Na podstawie typu wiadomości | `subscribe(OrderEvent.class)` |
|
||||
| **Hierarchical** | Tematy zagnieżdżone | `sport/football/+` (wildcard) |
|
||||
|
||||
### Wildcardy (MQTT)
|
||||
|
||||
```
|
||||
Hierarchia tematów:
|
||||
home/living-room/temperature
|
||||
home/living-room/humidity
|
||||
home/bedroom/temperature
|
||||
home/kitchen/temperature
|
||||
|
||||
Subskrypcje:
|
||||
home/living-room/# → wszystko z living-room
|
||||
home/+/temperature → temperatura ze wszystkich pomieszczeń
|
||||
home/# → wszystko z home
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Gwarancje dostarczenia
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ QoS (Quality of Service) levels: │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ QoS 0: AT MOST ONCE (fire and forget) │
|
||||
│ Publisher ──msg──→ Broker ──msg──→ Subscriber │
|
||||
│ • Brak potwierdzenia │
|
||||
│ • Możliwa utrata │
|
||||
│ • Najszybsze │
|
||||
│ │
|
||||
│ QoS 1: AT LEAST ONCE │
|
||||
│ Publisher ──msg──→ Broker ──ack──→ Publisher │
|
||||
│ • Potwierdzenie dostarczenia │
|
||||
│ • Możliwe duplikaty │
|
||||
│ │
|
||||
│ QoS 2: EXACTLY ONCE │
|
||||
│ Publisher ←──handshake──→ Broker │
|
||||
│ • 4-way handshake │
|
||||
│ • Brak duplikatów, brak utraty │
|
||||
│ • Najwolniejsze │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Rozwiązania techniczne
|
||||
|
||||
#### 4.1 Apache Kafka
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ APACHE KAFKA │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Topic: "orders" │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Partition 0: [msg1][msg2][msg3][msg4]... │ │
|
||||
│ │ Partition 1: [msg5][msg6][msg7]... │ │
|
||||
│ │ Partition 2: [msg8][msg9]... │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Consumer Groups: │
|
||||
│ Group A: Consumer1 → Part0, Consumer2 → Part1,2 │
|
||||
│ Group B: Consumer3 → Part0,1,2 (wszystkie) │
|
||||
│ │
|
||||
│ Cechy: │
|
||||
│ • Distributed, fault-tolerant │
|
||||
│ • Persisted log (retention) │
|
||||
│ • High throughput (millions msg/s) │
|
||||
│ • Pull model (consumer kontroluje tempo) │
|
||||
│ • Exactly-once semantics (transactions) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
// Producer
|
||||
producer.send(new ProducerRecord<>("orders", key, value));
|
||||
|
||||
// Consumer
|
||||
consumer.subscribe(Arrays.asList("orders"));
|
||||
while (true) {
|
||||
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
process(record);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2 RabbitMQ
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ RABBITMQ │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Publisher → Exchange → Queue → Consumer │
|
||||
│ │
|
||||
│ Exchange types: │
|
||||
│ • Direct: routing_key exact match │
|
||||
│ • Topic: routing_key pattern (*.error, logs.#) │
|
||||
│ • Fanout: broadcast to all queues │
|
||||
│ • Headers: match on headers │
|
||||
│ │
|
||||
│ [P] ─→ [Exchange] ─┬─→ [Queue1] ─→ [C1] │
|
||||
│ (topic) │ │
|
||||
│ └─→ [Queue2] ─→ [C2] │
|
||||
│ │
|
||||
│ Cechy: │
|
||||
│ • AMQP protocol │
|
||||
│ • Flexible routing │
|
||||
│ • Push model (broker wysyła do consumera) │
|
||||
│ • Acknowledgments, dead letter queues │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
// Python - pika
|
||||
channel.exchange_declare(exchange='logs', exchange_type='fanout')
|
||||
channel.basic_publish(exchange='logs', routing_key='', body=message)
|
||||
|
||||
channel.queue_bind(exchange='logs', queue=queue_name)
|
||||
channel.basic_consume(queue=queue_name, on_message_callback=callback)
|
||||
```
|
||||
|
||||
#### 4.3 MQTT (Message Queuing Telemetry Transport)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ MQTT │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Lightweight protocol for IoT │
|
||||
│ │
|
||||
│ [Sensor] ──publish──→ [Broker] ──deliver──→ [Dashboard] │
|
||||
│ topic: (Mosquitto, │
|
||||
│ "home/temp" HiveMQ) │
|
||||
│ │
|
||||
│ Cechy: │
|
||||
│ • Minimal overhead (2 byte header) │
|
||||
│ • QoS 0, 1, 2 │
|
||||
│ • Retained messages │
|
||||
│ • Last Will and Testament (LWT) │
|
||||
│ • Ideal for constrained devices │
|
||||
│ │
|
||||
│ Brokers: Mosquitto, HiveMQ, EMQ X, AWS IoT Core │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
// Python - paho-mqtt
|
||||
client.publish("home/temperature", payload="22.5")
|
||||
client.subscribe("home/#")
|
||||
```
|
||||
|
||||
#### 4.4 Redis Pub/Sub
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ REDIS PUB/SUB │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Prosty pub/sub w Redis │
|
||||
│ │
|
||||
│ PUBLISH channel message │
|
||||
│ SUBSCRIBE channel │
|
||||
│ PSUBSCRIBE pattern (np. news.*) │
|
||||
│ │
|
||||
│ Cechy: │
|
||||
│ • Fire-and-forget (brak persistence) │
|
||||
│ • Very fast │
|
||||
│ • Brak consumer groups (podstawowy) │
|
||||
│ │
|
||||
│ Redis Streams (nowsze): │
|
||||
│ • Persistent log (jak Kafka) │
|
||||
│ • Consumer groups │
|
||||
│ • XADD, XREAD, XGROUP │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
# Publisher
|
||||
redis-cli PUBLISH news "Breaking: ..."
|
||||
|
||||
# Subscriber
|
||||
redis-cli SUBSCRIBE news
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Porównanie rozwiązań
|
||||
|
||||
| Cecha | Kafka | RabbitMQ | MQTT | Redis Pub/Sub |
|
||||
|-------|-------|----------|------|---------------|
|
||||
| **Model** | Pull (log) | Push (queue) | Push | Push |
|
||||
| **Persistence** | Tak (log) | Opcjonalne | Retained only | Nie (Streams: tak) |
|
||||
| **Throughput** | Bardzo wysoki | Wysoki | Niski-średni | Wysoki |
|
||||
| **Routing** | Topic/partition | Flexible | Topic hierarchy | Channel/pattern |
|
||||
| **Use case** | Event streaming | Task queues | IoT | Real-time simple |
|
||||
| **Protocol** | Własny | AMQP | MQTT | RESP |
|
||||
|
||||
---
|
||||
|
||||
### 6. Zalety i wady Pub/Sub
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZALETY: │
|
||||
│ ✓ Luźne powiązanie (decoupling) │
|
||||
│ ✓ Skalowalność (dodawanie subskrybentów bez zmian publishera) │
|
||||
│ ✓ Asynchroniczność (brak blokowania) │
|
||||
│ ✓ Broadcast (1:N) │
|
||||
│ ✓ Filtrowanie (content-based, topics) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ WADY: │
|
||||
│ ✗ Brak gwarancji dostarczenia (zależy od QoS) │
|
||||
│ ✗ Ordering challenges (zwłaszcza z partycjami) │
|
||||
│ ✗ Debugging trudniejsze (brak bezpośredniego połączenia) │
|
||||
│ ✗ Broker = single point of failure (wymaga HA) │
|
||||
│ ✗ Message loss jeśli subscriber offline (bez persistence) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Wzorce użycia
|
||||
|
||||
```
|
||||
1. EVENT SOURCING:
|
||||
[Service] ─publish─→ [Kafka] ←─consume─ [Projections]
|
||||
Wszystkie zmiany jako events, rebuild state z log
|
||||
|
||||
2. CQRS (Command Query Responsibility Segregation):
|
||||
[Write Model] ─events─→ [Event Bus] ─→ [Read Model]
|
||||
Oddzielne modele do zapisu i odczytu
|
||||
|
||||
3. MICROSERVICES COMMUNICATION:
|
||||
[Order Service] ─"OrderCreated"─→ [Message Broker]
|
||||
│
|
||||
┌────────────────────┼────────────────────┐
|
||||
↓ ↓ ↓
|
||||
[Inventory] [Shipping] [Notification]
|
||||
|
||||
4. IoT DATA COLLECTION:
|
||||
[Sensors] ─MQTT─→ [Broker] ─→ [Data Pipeline] ─→ [Analytics]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "Pub/Sub = Radio broadcast":
|
||||
Publisher nadaje, kto chce słucha (subscribe)
|
||||
|
||||
### "Kafka = Log, RabbitMQ = Queue":
|
||||
Kafka przechowuje log, RabbitMQ to klasyczna kolejka
|
||||
|
||||
### "QoS 0-1-2 = Fire-AtLeast-Exactly":
|
||||
0 = fire&forget, 1 = at least once, 2 = exactly once
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy Kafka a kiedy RabbitMQ?"
|
||||
**Odpowiedź:** Kafka: event streaming, log retention, replay, high throughput, analytics. RabbitMQ: task queues, complex routing, request-reply, legacy AMQP integration.
|
||||
|
||||
### Q2: "Co to jest consumer group w Kafce?"
|
||||
**Odpowiedź:** Grupa consumerów gdzie każda partycja jest przypisana do jednego consumera w grupie. Umożliwia parallel processing i load balancing. Różne grupy otrzymują wszystkie wiadomości niezależnie.
|
||||
|
||||
### Q3: "Jak zapewnić ordering w pub/sub?"
|
||||
**Odpowiedź:** Kafka: ordering per partition (użyj tego samego klucza). RabbitMQ: single queue, single consumer. MQTT: QoS 2 dla pojedynczego topicu. Globalny ordering wymaga single partition/queue.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Pub/Sub:** Luźne powiązanie, asynchroniczność, 1:N
|
||||
2. **Kafka:** Distributed log, high throughput, persistence
|
||||
3. **RabbitMQ:** AMQP, flexible routing, push model
|
||||
4. **MQTT:** IoT, lightweight, QoS levels
|
||||
5. **Gwarancje:** At most/least/exactly once
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Kafka Documentation - kafka.apache.org
|
||||
2. RabbitMQ Tutorials - rabbitmq.com
|
||||
3. MQTT Specification - mqtt.org
|
||||
4. Kleppmann - "Designing Data-Intensive Applications"
|
||||
@ -1,331 +0,0 @@
|
||||
# Pytanie 34: Analityka danych strumieniowych
|
||||
|
||||
## Pytanie
|
||||
**"Scharakteryzować rozwiązania analityczne działające na danych o charakterze strumieniowym."**
|
||||
|
||||
Przedmiot: PSD (Przetwarzanie Strumieniowe Danych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Charakterystyka danych strumieniowych
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DANE STRUMIENIOWE vs BATCH │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ BATCH: │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ Dane statyczne │ → Przetwarzanie → Wynik │
|
||||
│ │ (cały zbiór) │ (jednorazowe) │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
│ STREAMING: │
|
||||
│ ─────●────●──●─────●──●────●───────→ (nieskończony strumień) │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ ↓ ↓ ↓ ↓ ↓ ↓ │
|
||||
│ [Przetwarzanie ciągłe] → Wyniki w czasie rzeczywistym │
|
||||
│ │
|
||||
│ Cechy strumieni: │
|
||||
│ • Nieograniczone (unbounded) │
|
||||
│ • Ciągłe napływanie │
|
||||
│ • Brak możliwości przechowania wszystkiego │
|
||||
│ • Wymagana niska latencja │
|
||||
│ • Dane mogą być nieuporządkowane (out-of-order) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Modele przetwarzania
|
||||
|
||||
#### Event Time vs Processing Time
|
||||
|
||||
```
|
||||
Event Time: Kiedy zdarzenie faktycznie nastąpiło
|
||||
Processing Time: Kiedy zdarzenie dotarło do systemu
|
||||
|
||||
Timeline:
|
||||
Event time: ─●─────●───●─────────●───→
|
||||
E1 E2 E3 E4
|
||||
|
||||
Processing: ───●───────●──●──●───────→
|
||||
E1 E3 E2 E4 (różna kolejność!)
|
||||
|
||||
Watermark: znacznik postępu event time
|
||||
"Wszystkie zdarzenia do czasu T już dotarły"
|
||||
```
|
||||
|
||||
#### Windowing (okna czasowe)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ TUMBLING WINDOW (rozłączne): │
|
||||
│ ├────────┤├────────┤├────────┤├────────┤ │
|
||||
│ │ Window1││ Window2││ Window3││ Window4│ │
|
||||
│ │
|
||||
│ SLIDING WINDOW (nakładające się): │
|
||||
│ ├────────────┤ │
|
||||
│ ├────────────┤ │
|
||||
│ ├────────────┤ │
|
||||
│ ├────────────┤ │
|
||||
│ │
|
||||
│ SESSION WINDOW (oparte na aktywności): │
|
||||
│ ├────┤ ├──────────┤ ├───┤ ├─────┤ │
|
||||
│ session1 session2 s3 session4 │
|
||||
│ gap gap gap │
|
||||
│ │
|
||||
│ GLOBAL WINDOW: │
|
||||
│ ├─────────────────────────────────────────────────────→ │
|
||||
│ (jedno okno, trigger decyduje kiedy emitować) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Platformy Stream Processing
|
||||
|
||||
#### Apache Kafka Streams
|
||||
|
||||
```java
|
||||
StreamsBuilder builder = new StreamsBuilder();
|
||||
|
||||
KStream<String, String> source = builder.stream("input-topic");
|
||||
|
||||
KTable<Windowed<String>, Long> counts = source
|
||||
.groupByKey()
|
||||
.windowedBy(TimeWindows.of(Duration.ofMinutes(5)))
|
||||
.count();
|
||||
|
||||
counts.toStream().to("output-topic");
|
||||
|
||||
// Cechy:
|
||||
// • Library (nie cluster)
|
||||
// • Exactly-once semantics
|
||||
// • Stateful processing z RocksDB
|
||||
// • Integracja z Kafka ecosystem
|
||||
```
|
||||
|
||||
#### Apache Flink
|
||||
|
||||
```java
|
||||
DataStream<Event> stream = env.addSource(new FlinkKafkaConsumer<>(...));
|
||||
|
||||
DataStream<Result> result = stream
|
||||
.keyBy(event -> event.getKey())
|
||||
.window(TumblingEventTimeWindows.of(Time.minutes(5)))
|
||||
.aggregate(new MyAggregateFunction())
|
||||
.process(new MyProcessFunction());
|
||||
|
||||
// Cechy:
|
||||
// • True streaming (nie micro-batch)
|
||||
// • Event time processing
|
||||
// • Exactly-once state
|
||||
// • Savepoints & checkpoints
|
||||
// • Complex Event Processing (CEP)
|
||||
```
|
||||
|
||||
#### Apache Spark Structured Streaming
|
||||
|
||||
```python
|
||||
df = spark.readStream \
|
||||
.format("kafka") \
|
||||
.option("subscribe", "events") \
|
||||
.load()
|
||||
|
||||
result = df \
|
||||
.withWatermark("timestamp", "10 minutes") \
|
||||
.groupBy(
|
||||
window("timestamp", "5 minutes"),
|
||||
"userId"
|
||||
) \
|
||||
.count()
|
||||
|
||||
query = result.writeStream \
|
||||
.outputMode("append") \
|
||||
.format("console") \
|
||||
.start()
|
||||
|
||||
# Cechy:
|
||||
# • Micro-batch (domyślnie) lub Continuous
|
||||
# • Unified batch + streaming API
|
||||
# • Catalyst optimizer
|
||||
# • Integracja z Spark ecosystem
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Porównanie platform
|
||||
|
||||
| Cecha | Kafka Streams | Flink | Spark Streaming |
|
||||
|-------|---------------|-------|-----------------|
|
||||
| **Model** | True streaming | True streaming | Micro-batch |
|
||||
| **Deployment** | Library | Cluster | Cluster |
|
||||
| **Latency** | Niska | Bardzo niska | Średnia (~100ms) |
|
||||
| **State** | RocksDB | RocksDB/heap | In-memory/external |
|
||||
| **Exactly-once** | Tak | Tak | Tak |
|
||||
| **SQL** | KSQL | Flink SQL | Spark SQL |
|
||||
| **CEP** | Ograniczone | Tak (FlinkCEP) | Nie natywnie |
|
||||
|
||||
---
|
||||
|
||||
### 5. Algorytmy strumieniowe
|
||||
|
||||
#### Approximate counting - HyperLogLog
|
||||
|
||||
```
|
||||
Problem: Zlicz unikalne elementy w strumieniu
|
||||
(bez przechowywania wszystkich)
|
||||
|
||||
HyperLogLog:
|
||||
• O(1) space (kilka KB)
|
||||
• ~2% error dla 12-bit registers
|
||||
• Używa hash → trailing zeros
|
||||
|
||||
Przykład: Redis PFADD, PFCOUNT
|
||||
```
|
||||
|
||||
#### Frequency estimation - Count-Min Sketch
|
||||
|
||||
```
|
||||
Problem: Estymuj częstość elementów
|
||||
|
||||
Count-Min Sketch:
|
||||
┌─────────────────────────────────┐
|
||||
│ h1: [3][0][2][5][1][0][4][2] │
|
||||
│ h2: [1][2][0][3][4][1][0][2] │
|
||||
│ h3: [2][1][3][0][2][1][3][0] │
|
||||
└─────────────────────────────────┘
|
||||
|
||||
Query(x): min(h1[hash1(x)], h2[hash2(x)], h3[hash3(x)])
|
||||
|
||||
• Overestimates (never underestimates)
|
||||
• Tunable accuracy vs space
|
||||
```
|
||||
|
||||
#### Sampling - Reservoir Sampling
|
||||
|
||||
```
|
||||
Problem: Równomiernie próbkuj k elementów
|
||||
ze strumienia o nieznanej długości
|
||||
|
||||
Algorithm:
|
||||
1. Zachowaj pierwsze k elementów
|
||||
2. Dla i-tego elementu (i > k):
|
||||
- Z prawdopodobieństwem k/i zamień
|
||||
losowy element w reservoir
|
||||
|
||||
Gwarancja: Każdy element ma szansę k/n
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Obsługa opóźnień i Out-of-Order
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WATERMARKS + LATE DATA │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Stream: ─●(t=1)──●(t=5)──●(t=3)──●(t=8)──●(t=2)───→ │
|
||||
│ ↑ ↑ │
|
||||
│ out-of-order late data │
|
||||
│ │
|
||||
│ Watermark: "Prawdopodobnie wszystkie events do t=X dotarły" │
|
||||
│ │
|
||||
│ Strategie dla late data: │
|
||||
│ 1. DROP: Ignoruj spóźnione (najprostsze) │
|
||||
│ 2. RECOMPUTE: Przelicz okno (kosztowne) │
|
||||
│ 3. SIDE OUTPUT: Zapisz do osobnego strumienia │
|
||||
│ 4. ALLOWED LATENESS: Czekaj dodatkowo N czasu │
|
||||
│ │
|
||||
│ Flink: │
|
||||
│ .allowedLateness(Time.minutes(5)) │
|
||||
│ .sideOutputLateData(lateOutputTag) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Exactly-Once Semantics
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ GWARANCJE PRZETWARZANIA: │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AT-MOST-ONCE: │
|
||||
│ Fire-and-forget, możliwa utrata danych │
|
||||
│ │
|
||||
│ AT-LEAST-ONCE: │
|
||||
│ Retry przy failure, możliwe duplikaty │
|
||||
│ │
|
||||
│ EXACTLY-ONCE: │
|
||||
│ Każde zdarzenie przetworzone dokładnie raz │
|
||||
│ │
|
||||
│ Implementacja (Flink/Kafka): │
|
||||
│ • Checkpointing (periodic snapshots) │
|
||||
│ • Transactional sinks (Kafka transactions) │
|
||||
│ • Barrier alignment │
|
||||
│ • Idempotent operations │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. Use Cases
|
||||
|
||||
| Use Case | Technologia | Opis |
|
||||
|----------|-------------|------|
|
||||
| **Fraud detection** | Flink CEP | Pattern matching w czasie rzeczywistym |
|
||||
| **IoT analytics** | Kafka Streams | Agregacja danych z sensorów |
|
||||
| **Real-time dashboards** | Spark + Druid | Metryki biznesowe |
|
||||
| **Log analysis** | ELK + Kafka | Centralizacja logów |
|
||||
| **Recommendations** | Flink | Real-time personalizacja |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "TWSS = Tumbling, Window, Sliding, Session":
|
||||
Cztery typy okien czasowych
|
||||
|
||||
### "Flink = Fast, Spark = Safe":
|
||||
Flink najszybszy (true streaming), Spark bezpieczny (micro-batch)
|
||||
|
||||
### "HLL = Hash, Leading zeros, Log":
|
||||
HyperLogLog do zliczania unikalnych
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy micro-batch a kiedy true streaming?"
|
||||
**Odpowiedź:** True streaming (Flink): ultra-low latency, CEP, event-time critical. Micro-batch (Spark): wyższa przepustowość, łatwiejsza integracja z batch, mniej wrażliwe na anomalie.
|
||||
|
||||
### Q2: "Jak obsłużyć skoki danych (spikes)?"
|
||||
**Odpowiedź:** Backpressure (Flink automatycznie), buffering, auto-scaling (Kubernetes), rate limiting na źródle, spillage to disk.
|
||||
|
||||
### Q3: "Co to jest checkpointing?"
|
||||
**Odpowiedź:** Periodic snapshots stanu (Flink). Przy failure - restart od ostatniego checkpoointu. Barrier synchronizuje snapshot między operatorami. Incremental checkpoints dla dużych stanów.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Streaming:** Unbounded, continuous, low latency
|
||||
2. **Windowing:** Tumbling, Sliding, Session, Global
|
||||
3. **Event time vs Processing time:** Watermarks
|
||||
4. **Platforms:** Flink (true), Spark (micro-batch), Kafka Streams (library)
|
||||
5. **Exactly-once:** Checkpointing + transactions
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Kleppmann - "Designing Data-Intensive Applications"
|
||||
2. Apache Flink Documentation
|
||||
3. Spark Structured Streaming Guide
|
||||
4. Kafka Streams Documentation
|
||||
@ -1,291 +0,0 @@
|
||||
# Pytanie 35: Modelowanie układów cyber-fizycznych
|
||||
|
||||
## Pytanie
|
||||
**"Na czym polega specyfika modelowania matematycznego układów cyber-fizycznych? Podać przykłady współpracy agentów w sieci i problemów w osiąganiu pożądanego zachowania układu."**
|
||||
|
||||
Przedmiot: SIU (Systemy Inteligentne i Uczące się)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Definicja układów cyber-fizycznych (CPS)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ CYBER-PHYSICAL SYSTEM (CPS) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||||
│ │ CYBER │ ←────→ │ PHYSICAL │ │
|
||||
│ │ (computation, │ │ (dynamics, │ │
|
||||
│ │ communication, │ │ physics, │ │
|
||||
│ │ control) │ │ environment) │ │
|
||||
│ └──────────────────┘ └──────────────────┘ │
|
||||
│ ↑ ↑ │
|
||||
│ │ SENSORS │ │
|
||||
│ └────────────────────────────┘ │
|
||||
│ ACTUATORS │
|
||||
│ │
|
||||
│ Przykłady: Autonomiczne pojazdy, smart grid, robotyka, │
|
||||
│ drony, systemy medyczne, Industry 4.0 │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Specyfika modelowania CPS
|
||||
|
||||
#### Hybrid Systems (systemy hybrydowe)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DYNAMIKA CIĄGŁA + DYSKRETNA │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Ciągła (fizyka): ẋ = f(x, u) (równania różniczkowe) │
|
||||
│ Dyskretna (logika): Automat stanów (przełączanie trybów) │
|
||||
│ │
|
||||
│ Przykład - termostat: │
|
||||
│ │
|
||||
│ Mode: OFF Mode: ON │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Ṫ = -α(T-Tₑ)│ ──T<Tₗ───→ │ Ṫ = β - α(T-Tₑ)│ │
|
||||
│ │ │ ←──T>Tₕ─── │ │ │
|
||||
│ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
│ T = temperatura, Tₑ = zewnętrzna, Tₗ/Tₕ = progi │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Modelowanie matematyczne
|
||||
|
||||
| Aspekt | Model | Opis |
|
||||
|--------|-------|------|
|
||||
| **Dynamika ciągła** | ODE/PDE | ẋ = f(x,u,t) |
|
||||
| **Stany dyskretne** | Automaty hybrydowe | Przejścia między trybami |
|
||||
| **Komunikacja** | Grafy, delay | Topologia sieci, opóźnienia |
|
||||
| **Niepewność** | Stochastyczne ODE | Szum, zakłócenia |
|
||||
| **Ograniczenia** | Nierówności | Fizyczne limity |
|
||||
|
||||
---
|
||||
|
||||
### 3. Współpraca agentów w sieci
|
||||
|
||||
#### Consensus (uzgadnianie)
|
||||
|
||||
```
|
||||
Problem: Agenty mają osiągnąć wspólną wartość
|
||||
|
||||
Protokół consensus:
|
||||
ẋᵢ = Σⱼ∈Nᵢ aᵢⱼ(xⱼ - xᵢ)
|
||||
|
||||
gdzie:
|
||||
- xᵢ = stan agenta i
|
||||
- Nᵢ = sąsiedzi agenta i
|
||||
- aᵢⱼ = waga połączenia
|
||||
|
||||
Forma macierzowa:
|
||||
ẋ = -L·x
|
||||
|
||||
L = Laplacian grafu komunikacji
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Przykład: 4 agenty, różne wartości początkowe │
|
||||
│ │
|
||||
│ x(t) │
|
||||
│ ↑ │
|
||||
│ 5 │ ● │
|
||||
│ 4 │ ●───────────────────────────● consensus │
|
||||
│ 3 │ ●───────────────────────● value │
|
||||
│ 2 │ ●───────────────────● │
|
||||
│ 1 │ ●─────────────────────────────● │
|
||||
│ └─────────────────────────────────→ t │
|
||||
│ │
|
||||
│ Wszystkie wartości zbiegają do średniej │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Formation Control (formacje)
|
||||
|
||||
```
|
||||
Problem: Utrzymanie geometrycznej formacji
|
||||
|
||||
Agent i:
|
||||
ẋᵢ = Σⱼ∈Nᵢ aᵢⱼ[(xⱼ - xᵢ) - (dⱼ* - dᵢ*)]
|
||||
|
||||
gdzie dᵢ* = pozycja docelowa agenta i w formacji
|
||||
|
||||
Przykład - formacja trójkąta:
|
||||
|
||||
Start: Cel:
|
||||
● ● ●
|
||||
● ● / \
|
||||
● ●───●
|
||||
```
|
||||
|
||||
#### Flocking (stado)
|
||||
|
||||
```
|
||||
Trzy zasady Reynoldsa:
|
||||
|
||||
1. SEPARATION: Unikaj kolizji z sąsiadami
|
||||
Fₛₑₚ = -Σ (xⱼ - xᵢ)/||xⱼ - xᵢ||²
|
||||
|
||||
2. ALIGNMENT: Dopasuj prędkość do sąsiadów
|
||||
Fₐₗᵢₘ = Σ (vⱼ - vᵢ)
|
||||
|
||||
3. COHESION: Dąż do centrum grupy
|
||||
Fₖₒₕ = (x̄ - xᵢ)
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ●→ │
|
||||
│ ●→ ●→ ●→ │
|
||||
│ ●→ ●→ │
|
||||
│ ●→ ●→ ●→ │
|
||||
│ ●→ ●→ │
|
||||
│ │
|
||||
│ Ptaki/ryby poruszają się jako zorganizowana grupa │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Problemy w osiąganiu pożądanego zachowania
|
||||
|
||||
#### 4.1 Problemy komunikacyjne
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ OPÓŹNIENIA (Delays): │
|
||||
│ │
|
||||
│ ẋᵢ(t) = Σⱼ aᵢⱼ[xⱼ(t - τᵢⱼ) - xᵢ(t)] │
|
||||
│ │
|
||||
│ Duże τ → niestabilność, oscylacje │
|
||||
│ │
|
||||
│ UTRATA PAKIETÓW: │
|
||||
│ │
|
||||
│ Agent nie otrzymuje informacji od sąsiada │
|
||||
│ → Stale dane, błędne decyzje │
|
||||
│ │
|
||||
│ OGRANICZONA PRZEPUSTOWOŚĆ: │
|
||||
│ │
|
||||
│ Kwantyzacja informacji │
|
||||
│ → Błędy zaokrągleń, limit cykli │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 4.2 Problemy topologii
|
||||
|
||||
| Problem | Opis | Skutek |
|
||||
|---------|------|--------|
|
||||
| **Słaba łączność** | Graf niespójny | Brak consensus |
|
||||
| **Zmiana topologii** | Agenty się przemieszczają | Niestabilność |
|
||||
| **Single point of failure** | Kluczowy węzeł pada | Rozpad sieci |
|
||||
| **Partycjonowanie** | Sieć dzieli się | Lokalne consensus |
|
||||
|
||||
```
|
||||
Graf spójny: Graf niespójny:
|
||||
●───● ●───● ●───●
|
||||
│ │ │ │
|
||||
●───● ● ●
|
||||
|
||||
Consensus: TAK Consensus: NIE
|
||||
(dwa osobne clustry)
|
||||
```
|
||||
|
||||
#### 4.3 Problemy dynamiczne
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ HETEROGENICZNOŚĆ: │
|
||||
│ Agenty mają różne dynamiki (szybkie vs wolne) │
|
||||
│ → Różne szybkości zbieżności │
|
||||
│ │
|
||||
│ SATURACJA AKTUATORÓW: │
|
||||
│ |uᵢ| ≤ uₘₐₓ (fizyczne ograniczenia) │
|
||||
│ → Wolniejsza zbieżność, możliwy brak zbieżności │
|
||||
│ │
|
||||
│ ZAKŁÓCENIA: │
|
||||
│ ẋᵢ = f(x) + wᵢ(t) gdzie wᵢ = szum │
|
||||
│ → Błąd steady-state, oscylacje wokół celu │
|
||||
│ │
|
||||
│ ADVERSARIAL AGENTS: │
|
||||
│ Złośliwy agent wysyła fałszywe dane │
|
||||
│ → Consensus na błędnej wartości │
|
||||
│ Rozwiązanie: Byzantine fault tolerance │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Warunki zbieżności consensus
|
||||
|
||||
```
|
||||
Twierdzenie: Protokół consensus ẋ = -Lx zbiega do consensus ⟺
|
||||
Graf komunikacji jest (słabo) spójny
|
||||
|
||||
Szybkość zbieżności ~ λ₂(L) (algebraic connectivity)
|
||||
|
||||
Większe λ₂ → szybsza zbieżność
|
||||
|
||||
Dla grafów skierowanych:
|
||||
- Potrzebny spanning tree
|
||||
- Wartość consensus = ważona średnia
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Przykłady zastosowań
|
||||
|
||||
| Zastosowanie | Agenty | Współpraca |
|
||||
|--------------|--------|------------|
|
||||
| **Swarm robotics** | Roboty | Eksploracja, transport |
|
||||
| **Vehicular platoon** | Pojazdy | Jazda w kolumnie |
|
||||
| **Smart grid** | Generatory | Balansowanie mocy |
|
||||
| **Sensor networks** | Sensory | Distributed estimation |
|
||||
| **UAV coordination** | Drony | Surveillance, delivery |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "CPS = Cyber + Physical + Sensors":
|
||||
Trzy elementy systemu cyber-fizycznego
|
||||
|
||||
### "Consensus = Laplacian = -Lx":
|
||||
Protokół consensus używa Laplacianu grafu
|
||||
|
||||
### "SAC = Separation, Alignment, Cohesion":
|
||||
Trzy zasady flockingu Reynoldsa
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jak modelować opóźnienia w komunikacji?"
|
||||
**Odpowiedź:** Delay differential equations (DDE): ẋ(t) = f(x(t), x(t-τ)). Analiza stabilności: metody Lyapunova-Krasovskiego, analiza wartości własnych z delay. Kompensacja: predyktory Smitha, robust control.
|
||||
|
||||
### Q2: "Co to jest algebraic connectivity?"
|
||||
**Odpowiedź:** Druga najmniejsza wartość własna Laplacianu grafu (λ₂). Mierzy jak dobrze graf jest połączony. λ₂ > 0 ⟺ graf spójny. Większe λ₂ = szybsza zbieżność consensus.
|
||||
|
||||
### Q3: "Jak zapewnić odporność na złośliwe agenty?"
|
||||
**Odpowiedź:** Byzantine fault tolerance: F-local / F-total model, W-MSR algorithm (Weighted Mean-Subsequence-Reduced), redundancja informacji, reputation systems.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **CPS:** Hybrid systems (ciągła + dyskretna dynamika)
|
||||
2. **Consensus:** ẋ = -Lx, zbieżność do wspólnej wartości
|
||||
3. **Flocking:** Separation, Alignment, Cohesion
|
||||
4. **Problemy:** Delays, packet loss, topology changes
|
||||
5. **Warunek:** Graf spójny dla consensus
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Olfati-Saber, Murray - "Consensus Problems in Networks of Agents"
|
||||
2. Mesbahi, Egerstedt - "Graph Theoretic Methods in Multiagent Networks"
|
||||
3. Bullo - "Lectures on Network Systems"
|
||||
@ -1,297 +0,0 @@
|
||||
# Pytanie 36: Uczenie się ze wzmocnieniem (Reinforcement Learning)
|
||||
|
||||
## Pytanie
|
||||
**"Omówić ogólny algorytm, elementy składowe oraz własności uczenia się ze wzmocnieniem."**
|
||||
|
||||
Przedmiot: SIU (Systemy Inteligentne i Uczące się)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Model uczenia ze wzmocnieniem
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ REINFORCEMENT LEARNING LOOP │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ │
|
||||
│ action aₜ │ │ reward rₜ │
|
||||
│ ──────────→ │ ENVIRONMENT │ ──────────→ │
|
||||
│ │ │ │ │ │
|
||||
│ │ └─────────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ state sₜ₊₁ │ │
|
||||
│ │ │ │ │
|
||||
│ │ ↓ ↓ │
|
||||
│ │ ┌─────────────┐ │
|
||||
│ └────────── │ AGENT │ ←─────────┘ │
|
||||
│ │ (policy π) │ │
|
||||
│ └─────────────┘ │
|
||||
│ │
|
||||
│ Cel: Maksymalizacja skumulowanej nagrody E[Σ γᵗrₜ] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Elementy składowe
|
||||
|
||||
| Element | Symbol | Opis |
|
||||
|---------|--------|------|
|
||||
| **State** | s ∈ S | Obserwacja środowiska |
|
||||
| **Action** | a ∈ A | Decyzja agenta |
|
||||
| **Reward** | r ∈ ℝ | Sygnał zwrotny |
|
||||
| **Policy** | π(a\|s) | Strategia wyboru akcji |
|
||||
| **Value function** | V(s), Q(s,a) | Oczekiwana nagroda |
|
||||
| **Discount factor** | γ ∈ [0,1] | Ważność przyszłych nagród |
|
||||
| **Transition** | P(s'\|s,a) | Dynamika środowiska |
|
||||
|
||||
### Markov Decision Process (MDP)
|
||||
|
||||
```
|
||||
MDP = (S, A, P, R, γ)
|
||||
|
||||
S: Zbiór stanów
|
||||
A: Zbiór akcji
|
||||
P: P(s'|s,a) - prawdopodobieństwa przejść
|
||||
R: R(s,a,s') - funkcja nagrody
|
||||
γ: Współczynnik dyskontowania
|
||||
|
||||
Właściwość Markowa:
|
||||
P(sₜ₊₁|s₀,a₀,...,sₜ,aₜ) = P(sₜ₊₁|sₜ,aₜ)
|
||||
|
||||
Przyszłość zależy tylko od obecnego stanu!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Funkcje wartości
|
||||
|
||||
#### State Value Function V(s)
|
||||
|
||||
$$V^\pi(s) = \mathbb{E}_\pi \left[ \sum_{t=0}^{\infty} \gamma^t r_t \mid s_0 = s \right]$$
|
||||
|
||||
#### Action Value Function Q(s,a)
|
||||
|
||||
$$Q^\pi(s,a) = \mathbb{E}_\pi \left[ \sum_{t=0}^{\infty} \gamma^t r_t \mid s_0 = s, a_0 = a \right]$$
|
||||
|
||||
#### Równania Bellmana
|
||||
|
||||
```
|
||||
V*(s) = max_a [R(s,a) + γ Σ_s' P(s'|s,a) V*(s')]
|
||||
|
||||
Q*(s,a) = R(s,a) + γ Σ_s' P(s'|s,a) max_a' Q*(s',a')
|
||||
|
||||
Rekurencyjne równania - podstawa algorytmów DP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Algorytmy
|
||||
|
||||
#### 4.1 Value-based methods
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Q-LEARNING (off-policy, model-free) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Q(s,a) ← Q(s,a) + α[r + γ max_a' Q(s',a') - Q(s,a)] │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ TD target │
|
||||
│ │
|
||||
│ Algorytm: │
|
||||
│ 1. Obserwuj stan s │
|
||||
│ 2. Wybierz akcję a (ε-greedy) │
|
||||
│ 3. Wykonaj a, obserwuj r, s' │
|
||||
│ 4. Zaktualizuj Q(s,a) │
|
||||
│ 5. s ← s', goto 1 │
|
||||
│ │
|
||||
│ ε-greedy: │
|
||||
│ Z prawdop. ε: losowa akcja (exploration) │
|
||||
│ Z prawdop. 1-ε: argmax Q(s,a) (exploitation) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SARSA (on-policy) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Q(s,a) ← Q(s,a) + α[r + γ Q(s',a') - Q(s,a)] │
|
||||
│ ↑ │
|
||||
│ Rzeczywista następna akcja (nie max!) │
|
||||
│ │
|
||||
│ Różnica od Q-learning: │
|
||||
│ - Używa akcji faktycznie wybranej przez policy │
|
||||
│ - Bardziej "ostrożny" (uwzględnia exploration) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 4.2 Deep Q-Network (DQN)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DQN - Q-learning z siecią neuronową │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ State s → [Neural Network] → Q(s,a₁), Q(s,a₂), ..., Q(s,aₙ) │
|
||||
│ │
|
||||
│ Innowacje: │
|
||||
│ 1. Experience Replay: bufor (s,a,r,s'), losowe próbkowanie │
|
||||
│ 2. Target Network: osobna sieć do obliczania targetów │
|
||||
│ (aktualizowana co N kroków) │
|
||||
│ │
|
||||
│ Loss: L = (r + γ max Q_target(s',a') - Q(s,a))² │
|
||||
│ │
|
||||
│ Przełom: Atari games (2015) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 4.3 Policy-based methods
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ POLICY GRADIENT │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Bezpośrednia optymalizacja parametrów θ policy π_θ(a|s) │
|
||||
│ │
|
||||
│ Gradient: │
|
||||
│ ∇_θ J(θ) = E_π [∇_θ log π_θ(a|s) · Q(s,a)] │
|
||||
│ │
|
||||
│ REINFORCE algorithm: │
|
||||
│ 1. Generuj trajektorię τ = (s₀,a₀,r₀,s₁,...) │
|
||||
│ 2. Oblicz return: Gₜ = Σ_{k=0}^{T-t} γᵏ r_{t+k} │
|
||||
│ 3. Update: θ ← θ + α ∇_θ log π_θ(aₜ|sₜ) · Gₜ │
|
||||
│ │
|
||||
│ Zalety: ciągłe akcje, stochastic policies │
|
||||
│ Wady: wysoka wariancja, wolna zbieżność │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 4.4 Actor-Critic
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ACTOR-CRITIC - łączy value-based i policy-based │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ ACTOR │ ←───── │ CRITIC │ │
|
||||
│ │ π_θ(a|s)│ │ V_w(s) │ │
|
||||
│ └────┬────┘ └────┬────┘ │
|
||||
│ │ │ │
|
||||
│ ↓ │ │
|
||||
│ action value estimate │
|
||||
│ │
|
||||
│ Actor: wybiera akcje (policy) │
|
||||
│ Critic: ocenia jak dobre są akcje (value function) │
|
||||
│ │
|
||||
│ Advantage: A(s,a) = Q(s,a) - V(s) │
|
||||
│ Actor update: θ ← θ + α ∇_θ log π_θ(a|s) · A(s,a) │
|
||||
│ Critic update: minimize (r + γV(s') - V(s))² │
|
||||
│ │
|
||||
│ Algorytmy: A2C, A3C, PPO, SAC │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Klasyfikacja algorytmów
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ ┌── Model-based (zna/uczy się P, R) │
|
||||
│ RL Methods ─┤ │
|
||||
│ └── Model-free (nie zna środowiska) │
|
||||
│ │ │
|
||||
│ ├── Value-based (Q-learning, DQN) │
|
||||
│ ├── Policy-based (REINFORCE) │
|
||||
│ └── Actor-Critic (A2C, PPO, SAC) │
|
||||
│ │
|
||||
│ ┌── On-policy (SARSA, A2C) - używa obecnej π │
|
||||
│ RL Methods ─┤ │
|
||||
│ └── Off-policy (Q-learning, DQN) - używa innej π │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Exploration vs Exploitation
|
||||
|
||||
| Strategia | Opis |
|
||||
|-----------|------|
|
||||
| **ε-greedy** | Z prawdop. ε losowa akcja |
|
||||
| **Softmax/Boltzmann** | P(a) ∝ exp(Q(s,a)/τ) |
|
||||
| **UCB** | a = argmax[Q(s,a) + c√(ln N / n(a))] |
|
||||
| **Thompson Sampling** | Próbkowanie z posterior |
|
||||
| **Curiosity-driven** | Bonus za nowość |
|
||||
|
||||
---
|
||||
|
||||
### 7. Własności i wyzwania
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WŁASNOŚCI: │
|
||||
│ ✓ Uczenie przez interakcję (nie supervised) │
|
||||
│ ✓ Delayed rewards (kredyt za sekwencję akcji) │
|
||||
│ ✓ Generalizacja (do nowych stanów) │
|
||||
│ ✓ Online learning (ciągłe doskonalenie) │
|
||||
│ │
|
||||
│ WYZWANIA: │
|
||||
│ ✗ Sample inefficiency (wymaga wielu interakcji) │
|
||||
│ ✗ Credit assignment (która akcja odpowiada za reward?) │
|
||||
│ ✗ Exploration-exploitation tradeoff │
|
||||
│ ✗ Partial observability (POMDP) │
|
||||
│ ✗ Non-stationarity (środowisko się zmienia) │
|
||||
│ ✗ Reward shaping (sparse rewards problem) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "SARSA = State Action Reward State Action":
|
||||
Sekwencja w algorytmie SARSA
|
||||
|
||||
### "Q = Quality of action":
|
||||
Q(s,a) mierzy jakość akcji a w stanie s
|
||||
|
||||
### "Actor-Critic = Action + Advice":
|
||||
Actor wybiera akcje, Critic doradza (ocenia)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jaka jest różnica między Q-learning a SARSA?"
|
||||
**Odpowiedź:** Q-learning (off-policy): używa max Q(s',a') - optymistyczne. SARSA (on-policy): używa Q(s',a') gdzie a' to rzeczywista następna akcja - bardziej ostrożne, uwzględnia policy exploration.
|
||||
|
||||
### Q2: "Po co Experience Replay w DQN?"
|
||||
**Odpowiedź:** Łamie korelację między kolejnymi próbkami (iid requirement), efektywniejsze wykorzystanie danych (wielokrotne uczenie z jednej próbki), stabilizuje trening.
|
||||
|
||||
### Q3: "Kiedy model-based jest lepszy?"
|
||||
**Odpowiedź:** Gdy środowisko jest przewidywalne, samples są drogie (robotyka), potrzebne planowanie. Model-free lepszy gdy środowisko złożone, trudne do modelowania, dużo samples dostępnych.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **MDP:** (S, A, P, R, γ) - formalizacja problemu
|
||||
2. **Bellman:** V*(s) = max[R + γ·ΣP·V*]
|
||||
3. **Q-learning:** off-policy, max Q update
|
||||
4. **Policy Gradient:** ∇J = E[∇log π · Q]
|
||||
5. **Actor-Critic:** policy + value function
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Sutton, Barto - "Reinforcement Learning: An Introduction"
|
||||
2. Silver - DeepMind RL lectures
|
||||
3. Mnih et al. - "Playing Atari with Deep RL" (2015)
|
||||
@ -1,296 +0,0 @@
|
||||
# Pytanie 37: Modele sieci złożonych
|
||||
|
||||
## Pytanie
|
||||
**"Porównać podstawowe modele sieci złożonych. Jak odpowiadają one własnościom rzeczywistych sieci?"**
|
||||
|
||||
Przedmiot: TASS (Technologie i Algorytmy dla Sieci Społecznościowych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Właściwości rzeczywistych sieci
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ TYPOWE CECHY SIECI RZECZYWISTYCH │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. SMALL-WORLD EFFECT: │
|
||||
│ "Six degrees of separation" │
|
||||
│ Średnia ścieżka ~ log(N) │
|
||||
│ │
|
||||
│ 2. HIGH CLUSTERING: │
|
||||
│ "Znajomi moich znajomych są znajomymi" │
|
||||
│ Współczynnik grupowania C >> C_random │
|
||||
│ │
|
||||
│ 3. SCALE-FREE (Power-law degree distribution): │
|
||||
│ P(k) ~ k^(-γ), gdzie γ ∈ [2, 3] │
|
||||
│ Kilka hubów, wiele węzłów o małym stopniu │
|
||||
│ │
|
||||
│ 4. COMMUNITY STRUCTURE: │
|
||||
│ Gęste grupy połączone rzadkimi mostami │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Model Erdős-Rényi (Random Graph)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ G(n, p) - Graf losowy │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Konstrukcja: │
|
||||
│ - n węzłów │
|
||||
│ - Każda krawędź z prawdopodobieństwem p │
|
||||
│ │
|
||||
│ Właściwości: │
|
||||
│ ┌─────────────────────────────────────────┐ │
|
||||
│ │ Średni stopień: <k> = p(n-1) │ │
|
||||
│ │ Rozkład stopni: Poisson (dla dużych n)│ │
|
||||
│ │ Clustering: C = p (niski!) │ │
|
||||
│ │ Średnia ścieżka: L ~ log(n)/log(<k>) │ │
|
||||
│ │ Giant component: istnieje gdy <k> > 1 │ │
|
||||
│ └─────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Rozkład stopni P(k): │
|
||||
│ │
|
||||
│ P(k) │
|
||||
│ ↑ ● │
|
||||
│ │ ●●● │
|
||||
│ │ ●●●●●● Rozkład Poissona │
|
||||
│ │ ●●●●●●●● (symetryczny, wąski) │
|
||||
│ │ ●●●●●●●●●● │
|
||||
│ └────────────────→ k │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Porównanie z rzeczywistością
|
||||
|
||||
| Cecha | ER Model | Rzeczywiste sieci |
|
||||
|-------|----------|-------------------|
|
||||
| **Clustering** | C = p (niski) | C >> p (wysoki) ❌ |
|
||||
| **Średnia ścieżka** | L ~ log(n) ✓ | L ~ log(n) ✓ |
|
||||
| **Rozkład stopni** | Poisson | Power-law ❌ |
|
||||
| **Huby** | Brak | Istnieją ❌ |
|
||||
|
||||
---
|
||||
|
||||
### 3. Model Watts-Strogatz (Small-World)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SMALL-WORLD MODEL │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Konstrukcja: │
|
||||
│ 1. Zacznij od regularnej kratki (ring lattice) │
|
||||
│ 2. Każda krawędź przepinana z prawdop. p │
|
||||
│ │
|
||||
│ p=0 (regular) p~0.01 p=1 (random) │
|
||||
│ │
|
||||
│ ●───●───● ●───●───● ● ● ● │
|
||||
│ /│ │ │\ /│ \ │ │\ /│\ /│\ /│\ │
|
||||
│ ● │ │ │ ● ● │ │ │ ● ● │ X │ X │ ● │
|
||||
│ \│ │ │/ \│ │ / │/ \│/ \│/ \│/ │
|
||||
│ ●───●───● ●───●───● ● ● ● │
|
||||
│ │
|
||||
│ C: high C: high C: low │
|
||||
│ L: high L: low L: low │
|
||||
│ ↑ │
|
||||
│ SMALL-WORLD │
|
||||
│ (best of both!) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Właściwości
|
||||
|
||||
```
|
||||
Dla małych p (np. p = 0.01):
|
||||
|
||||
L(p) C(p)
|
||||
↑ ↑
|
||||
│● │●●●●●●●●●●●●●●●●●
|
||||
│ ● │ ●
|
||||
│ ●● │ ●●
|
||||
│ ●●●●│ ●●●●●
|
||||
└────────→ p └────────────────→ p
|
||||
|
||||
L spada szybko przy małych p (shortcuts)
|
||||
C pozostaje wysoki do większych p
|
||||
```
|
||||
|
||||
### Porównanie z rzeczywistością
|
||||
|
||||
| Cecha | WS Model | Rzeczywiste sieci |
|
||||
|-------|----------|-------------------|
|
||||
| **Clustering** | Wysoki ✓ | Wysoki ✓ |
|
||||
| **Średnia ścieżka** | L ~ log(n) ✓ | L ~ log(n) ✓ |
|
||||
| **Rozkład stopni** | Wąski (quasi-regular) | Power-law ❌ |
|
||||
| **Huby** | Brak | Istnieją ❌ |
|
||||
|
||||
---
|
||||
|
||||
### 4. Model Barabási-Albert (Scale-Free)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PREFERENTIAL ATTACHMENT MODEL │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Konstrukcja: │
|
||||
│ 1. Zacznij od małego grafu (m₀ węzłów) │
|
||||
│ 2. Dodawaj węzły jeden po drugim │
|
||||
│ 3. Nowy węzeł łączy się z m istniejącymi │
|
||||
│ 4. Prawdopodobieństwo połączenia z węzłem i: │
|
||||
│ │
|
||||
│ kᵢ │
|
||||
│ Π(i) = ───────── "Rich get richer" │
|
||||
│ Σⱼ kⱼ │
|
||||
│ │
|
||||
│ Rozkład stopni P(k): │
|
||||
│ │
|
||||
│ log P(k) │
|
||||
│ ↑ ● │
|
||||
│ │ ● │
|
||||
│ │ ● Power-law: │
|
||||
│ │ ● P(k) ~ k^(-3) │
|
||||
│ │ ●● │
|
||||
│ │ ●●● │
|
||||
│ │ ●●●●●●●● │
|
||||
│ └───────────────────→ log k │
|
||||
│ │
|
||||
│ Huby (węzły o wysokim stopniu) pojawiają się naturalnie! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Właściwości
|
||||
|
||||
| Właściwość | Wartość |
|
||||
|------------|---------|
|
||||
| **Rozkład stopni** | P(k) ~ k^(-γ), γ = 3 |
|
||||
| **Średnia ścieżka** | L ~ log(n)/log(log(n)) (ultra-small) |
|
||||
| **Clustering** | C ~ (log n)² / n (niski!) |
|
||||
| **Odporność** | Odporna na losowe awarie, wrażliwa na celowe ataki |
|
||||
|
||||
### Porównanie z rzeczywistością
|
||||
|
||||
| Cecha | BA Model | Rzeczywiste sieci |
|
||||
|-------|----------|-------------------|
|
||||
| **Clustering** | Niski ❌ | Wysoki |
|
||||
| **Średnia ścieżka** | Ultra-short ✓ | Short ✓ |
|
||||
| **Rozkład stopni** | Power-law ✓ | Power-law ✓ |
|
||||
| **Huby** | Tak ✓ | Tak ✓ |
|
||||
|
||||
---
|
||||
|
||||
### 5. Porównanie zbiorcze
|
||||
|
||||
```
|
||||
┌──────────────┬───────────────┬───────────────┬───────────────┐
|
||||
│ Właściwość │ Erdős-Rényi │ Watts-Strogatz│ Barabási-Albert│
|
||||
├──────────────┼───────────────┼───────────────┼───────────────┤
|
||||
│ Clustering │ Niski (C=p) │ Wysoki │ Niski │
|
||||
│ Śr. ścieżka │ log(n) │ log(n) │ log(n)/loglog │
|
||||
│ Rozkład │ Poisson │ Quasi-regular │ Power-law │
|
||||
│ Huby │ Nie │ Nie │ Tak │
|
||||
│ Small-world │ Tak │ Tak │ Ultra-small │
|
||||
│ Mechanizm │ Losowość │ Rewiring │ Pref. attach. │
|
||||
└──────────────┴───────────────┴───────────────┴───────────────┘
|
||||
|
||||
Rzeczywiste sieci (WWW, social, biological):
|
||||
• Wysoki clustering → WS lepszy
|
||||
• Power-law → BA lepszy
|
||||
• Short paths → wszystkie OK
|
||||
|
||||
Żaden pojedynczy model nie oddaje wszystkich cech!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Modele rozszerzone
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ HOLME-KIM MODEL (BA + clustering): │
|
||||
│ Po preferential attachment → dodaj trójkąt z prawdop. p │
|
||||
│ Łączy power-law z wysokim clustering │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ HIERARCHICAL MODELS: │
|
||||
│ Rekurencyjna struktura (fraktalna) │
|
||||
│ Modeluje hierarchie w organizacjach │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ STOCHASTIC BLOCK MODEL: │
|
||||
│ Podział na grupy z różnymi p wewnątrz/między │
|
||||
│ Modeluje community structure │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ CONFIGURATION MODEL: │
|
||||
│ Generuj graf z zadanym rozkładem stopni │
|
||||
│ Elastyczny, ale brak mechanizmu wzrostu │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Przykłady rzeczywistych sieci
|
||||
|
||||
| Sieć | N | <k> | C | L | γ |
|
||||
|------|---|-----|---|---|---|
|
||||
| **WWW** | 10⁹ | ~7 | 0.11 | 11.2 | 2.1 |
|
||||
| **Facebook** | 10⁹ | ~200 | 0.16 | 4.7 | ~3 |
|
||||
| **Internet (AS)** | 10⁴ | ~6 | 0.24 | 3.7 | 2.2 |
|
||||
| **C. elegans** | 282 | 14 | 0.28 | 2.7 | - |
|
||||
| **Power grid** | 4941 | 2.7 | 0.08 | 18.7 | exp |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "ER = Equal Random":
|
||||
Erdős-Rényi - równe prawdopodobieństwo krawędzi
|
||||
|
||||
### "WS = Wires Switched":
|
||||
Watts-Strogatz - przepinanie krawędzi
|
||||
|
||||
### "BA = Big Attract":
|
||||
Barabási-Albert - duże węzły przyciągają więcej
|
||||
|
||||
### "Scale-free = -3 power":
|
||||
P(k) ~ k^(-3) dla BA modelu
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Dlaczego BA ma niski clustering?"
|
||||
**Odpowiedź:** Preferential attachment łączy nowe węzły głównie z hubami, nie tworząc trójkątów między sąsiadami. Rozwiązanie: Holme-Kim model dodaje krok "triad formation".
|
||||
|
||||
### Q2: "Co to jest robustness vs vulnerability?"
|
||||
**Odpowiedź:** Scale-free sieci są odporne na losowe awarie (większość węzłów ma mały stopień), ale wrażliwe na celowane ataki na huby. ER sieci są bardziej jednolite w obu przypadkach.
|
||||
|
||||
### Q3: "Jak mierzyć small-world property?"
|
||||
**Odpowiedź:** Współczynnik σ = (C/C_random) / (L/L_random). Jeśli σ >> 1 → small-world. C wysoki jak w kratce, L niski jak w random graph.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **ER:** Random, Poisson degree, low clustering
|
||||
2. **WS:** Rewiring, high clustering + short paths
|
||||
3. **BA:** Preferential attachment, power-law, huby
|
||||
4. **Real networks:** Power-law + high clustering + short paths
|
||||
5. **Żaden model nie jest kompletny** - łączone modele
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Barabási - "Network Science" (networkscience.com)
|
||||
2. Newman - "Networks: An Introduction"
|
||||
3. Watts, Strogatz - "Collective dynamics of small-world networks" (1998)
|
||||
4. Barabási, Albert - "Emergence of Scaling in Random Networks" (1999)
|
||||
@ -1,264 +0,0 @@
|
||||
# Pytanie 38: Projekcje grafów dwudzielnych
|
||||
|
||||
## Pytanie
|
||||
**"Porównać metody projekcji grafów dwudzielnych. Przedstawić ich użyteczność w grupowaniu dokumentów tekstowych."**
|
||||
|
||||
Przedmiot: TASS (Technologie i Algorytmy dla Sieci Społecznościowych)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Grafy dwudzielne (Bipartite Graphs)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ GRAF DWUDZIELNY │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Zbiór U (np. dokumenty) Zbiór V (np. słowa) │
|
||||
│ │
|
||||
│ D1 ●────────────────● word1 │
|
||||
│ │ ╲ │ │
|
||||
│ D2 ●──╲─────────────● word2 │
|
||||
│ │ ╲ │ │
|
||||
│ D3 ●────╲───────────● word3 │
|
||||
│ ╲ │ │
|
||||
│ D4 ●──────╲─────────● word4 │
|
||||
│ │
|
||||
│ Krawędzie tylko między U i V (nigdy wewnątrz zbioru) │
|
||||
│ │
|
||||
│ Przykłady: │
|
||||
│ • Dokumenty - Słowa │
|
||||
│ • Użytkownicy - Produkty │
|
||||
│ • Autorzy - Artykuły │
|
||||
│ • Aktorzy - Filmy │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Projekcja grafu dwudzielnego
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PROJEKCJA = przekształcenie grafu dwudzielnego na jednomodowy │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Graf dwudzielny: Projekcja na U (dokumenty): │
|
||||
│ │
|
||||
│ D1 ●───────● w1 D1 ●─────● D2 │
|
||||
│ │╲ │ │╲ ╱│ │
|
||||
│ D2 ●─╲─────● w2 │ ╲ ╱ │ │
|
||||
│ │ ╲ │ │ ╳ │ │
|
||||
│ D3 ●───╲───● w3 │ ╱ ╲ │ │
|
||||
│ ╲ │╱ ╲│ │
|
||||
│ D4 ●───────● w4 D3 ●─────● D4 │
|
||||
│ │
|
||||
│ Dwa dokumenty połączone ⟺ mają wspólne słowo │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Metody projekcji
|
||||
|
||||
#### 3.1 Projekcja binarna (Simple/Unweighted)
|
||||
|
||||
```
|
||||
Macierz sąsiedztwa projekcji:
|
||||
|
||||
P = B · Bᵀ (dla projekcji na U)
|
||||
P = Bᵀ · B (dla projekcji na V)
|
||||
|
||||
gdzie B = macierz incydencji grafu dwudzielnego
|
||||
|
||||
Pᵢⱼ > 0 ⟹ węzły i, j połączone w projekcji
|
||||
|
||||
Wady:
|
||||
❌ Utrata informacji o sile powiązania
|
||||
❌ Wszystkie wspólni sąsiedzi traktowani równo
|
||||
```
|
||||
|
||||
#### 3.2 Projekcja ważona (Weighted)
|
||||
|
||||
| Metoda | Waga krawędzi (i,j) | Opis |
|
||||
|--------|---------------------|------|
|
||||
| **Simple count** | w_ij = \|N(i) ∩ N(j)\| | Liczba wspólnych sąsiadów |
|
||||
| **Jaccard** | w_ij = \|N(i) ∩ N(j)\| / \|N(i) ∪ N(j)\| | Normalizacja przez sumę |
|
||||
| **Cosine** | w_ij = (B_i · B_j) / (\|\|B_i\|\| · \|\|B_j\|\|) | Podobieństwo wektorów |
|
||||
| **Hyperbolic** | w_ij = Σ_k 1/(k_k - 1) | Rzadkie słowa ważniejsze |
|
||||
| **Resource allocation** | w_ij = Σ_k 1/k_k | Jak hyperbolic |
|
||||
|
||||
```
|
||||
Przykład - Jaccard:
|
||||
|
||||
D1 = {w1, w2, w3}
|
||||
D2 = {w2, w3, w4}
|
||||
|
||||
Wspólne: {w2, w3} → |∩| = 2
|
||||
Suma: {w1, w2, w3, w4} → |∪| = 4
|
||||
|
||||
w(D1, D2) = 2/4 = 0.5
|
||||
```
|
||||
|
||||
#### 3.3 Projekcja TF-IDF (dla dokumentów)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ TF-IDF weighted projection │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ TF(t,d) = częstość słowa t w dokumencie d │
|
||||
│ IDF(t) = log(N / df(t)) gdzie df(t) = liczba dok. z t │
|
||||
│ │
|
||||
│ TF-IDF(t,d) = TF(t,d) × IDF(t) │
|
||||
│ │
|
||||
│ Podobieństwo dokumentów: │
|
||||
│ sim(d1, d2) = cos(TF-IDF(d1), TF-IDF(d2)) │
|
||||
│ │
|
||||
│ Rzadkie słowa mają większą wagę (IDF)! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Porównanie metod
|
||||
|
||||
| Metoda | Zalety | Wady |
|
||||
|--------|--------|------|
|
||||
| **Binarna** | Prosta, szybka | Brak wag, utrata info |
|
||||
| **Simple count** | Intuicyjna | Bias ku popularnym węzłom |
|
||||
| **Jaccard** | Normalizowana | Ignoruje rozmiar zbiorów |
|
||||
| **Cosine** | Standard w IR | Wymaga wektorów |
|
||||
| **Hyperbolic** | Rzadkie elementy ważne | Bardziej złożona |
|
||||
| **TF-IDF** | Standard dla tekstów | Specyficzna dla dokumentów |
|
||||
|
||||
---
|
||||
|
||||
### 5. Zastosowanie w grupowaniu dokumentów
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PIPELINE GRUPOWANIA DOKUMENTÓW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. PREPROCESSING │
|
||||
│ Dokumenty → tokenizacja → stemming → usunięcie stop words │
|
||||
│ │
|
||||
│ 2. BUDOWA GRAFU DWUDZIELNEGO │
|
||||
│ G = (Documents, Terms, Edges) │
|
||||
│ Krawędź (d, t) jeśli term t występuje w dokumencie d │
|
||||
│ │
|
||||
│ 3. PROJEKCJA │
|
||||
│ P = projekcja ważona (TF-IDF/Cosine) na dokumenty │
|
||||
│ │
|
||||
│ 4. GRUPOWANIE │
|
||||
│ Na grafie projekcji: │
|
||||
│ • Community detection (Louvain, Label Propagation) │
|
||||
│ • Spectral clustering │
|
||||
│ • K-means na wektorach podobieństwa │
|
||||
│ │
|
||||
│ 5. WYNIK │
|
||||
│ Grupy tematycznie podobnych dokumentów │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Przykład
|
||||
|
||||
```
|
||||
Dokumenty:
|
||||
D1: "machine learning algorithms"
|
||||
D2: "deep learning neural networks"
|
||||
D3: "neural network architecture"
|
||||
D4: "database query optimization"
|
||||
D5: "SQL query performance"
|
||||
|
||||
Graf dwudzielny projekcja (cosine similarity):
|
||||
|
||||
D1 ──0.3── D2 ──0.6── D3 Klaster 1: ML/DL
|
||||
{D1, D2, D3}
|
||||
|
||||
D4 ──0.5── D5 Klaster 2: Databases
|
||||
{D4, D5}
|
||||
|
||||
Grupowanie znajdzie te dwa klastry!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Algorytmy grupowania na projekcji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ LOUVAIN (Community Detection): │
|
||||
│ • Optymalizuje modularność Q │
|
||||
│ • Iteracyjne przenoszenie węzłów między grupami │
|
||||
│ • O(n log n) - szybki │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ SPECTRAL CLUSTERING: │
|
||||
│ • Eigendecomposition Laplacianu │
|
||||
│ • K-means na wektorach własnych │
|
||||
│ • Znajduje struktury niekonweksowe │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ LABEL PROPAGATION: │
|
||||
│ • Propagacja etykiet po krawędziach │
|
||||
│ • Bardzo szybki O(m) │
|
||||
│ • Niedeterministyczny │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Problemy i rozwiązania
|
||||
|
||||
| Problem | Opis | Rozwiązanie |
|
||||
|---------|------|-------------|
|
||||
| **Gęstość** | Projekcja tworzy gęste grafy | Threshold na wagi |
|
||||
| **Huby** | Popularne słowa łączą wszystko | TF-IDF, filtering |
|
||||
| **Skalowalność** | O(n²) krawędzi | Sparse representation, LSH |
|
||||
| **Utrata info** | Projekcja traci strukturę | Zachowaj oryginalny graf |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "B×Bᵀ = Projekcja":
|
||||
Mnożenie macierzy incydencji daje projekcję
|
||||
|
||||
### "TF-IDF = Term Frequency × Inverse Document Frequency":
|
||||
Rzadkie słowa ważniejsze
|
||||
|
||||
### "Jaccard = Intersection over Union":
|
||||
IoU dla zbiorów
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Dlaczego projekcja binarna jest problematyczna?"
|
||||
**Odpowiedź:** Traci informację o sile powiązania. Dokument z 1 wspólnym słowem ma taką samą krawędź jak z 100 wspólnymi. Popularne słowa (stop words) tworzą fałszywe powiązania.
|
||||
|
||||
### Q2: "Jak skalować dla dużych zbiorów?"
|
||||
**Odpowiedź:** MinHash/LSH dla approximate similarity, sparse matrix operations, sampling, dimension reduction (LSA/SVD), distributed computing (Spark GraphX).
|
||||
|
||||
### Q3: "Alternatywy dla projekcji?"
|
||||
**Odpowiedź:** Bezpośrednie algorytmy na grafach dwudzielnych (bipartite community detection), tensor decomposition, embedding methods (node2vec), GNN na grafach heterogenicznych.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Projekcja:** Graf dwudzielny → jednomodowy (P = B·Bᵀ)
|
||||
2. **Metody:** Binarna, Jaccard, Cosine, TF-IDF
|
||||
3. **TF-IDF:** Rzadkie słowa ważniejsze (IDF)
|
||||
4. **Grupowanie:** Louvain, Spectral, Label Propagation
|
||||
5. **Problem:** Gęstość, popularne węzły → filtering, thresholding
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Newman - "Networks: An Introduction"
|
||||
2. Zhou et al. - "Bipartite Network Projection and Personal Recommendation"
|
||||
3. Manning - "Introduction to Information Retrieval"
|
||||
@ -1,322 +0,0 @@
|
||||
# Pytanie 39: Segmentacja obrazu
|
||||
|
||||
## Pytanie
|
||||
**"Scharakteryzować problem segmentacji obrazu. Przedstawić podstawowe strategie i algorytmy segmentacji przy użyciu metod klasycznych oraz sieci neuronowych."**
|
||||
|
||||
Przedmiot: TWM (Techniki Wizji Maszynowej)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Definicja problemu segmentacji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SEGMENTACJA OBRAZU │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Obraz wejściowy: Maska segmentacji: │
|
||||
│ ┌────────────────┐ ┌────────────────┐ │
|
||||
│ │ ░░████░░░░░░ │ │ ░░1111░░░░░░ │ │
|
||||
│ │ ░████████░░░ │ → │ ░11111111░░░ │ │
|
||||
│ │ ░░████████░░ │ │ ░░11111111░░ │ │
|
||||
│ │ ░░░░████░░░░ │ │ ░░░░1111░░░░ │ │
|
||||
│ └────────────────┘ └────────────────┘ │
|
||||
│ │
|
||||
│ Cel: Przypisać każdemu pikselowi etykietę klasy/regionu │
|
||||
│ │
|
||||
│ Typy segmentacji: │
|
||||
│ • Semantic: klasa dla każdego piksela (person, car, sky) │
|
||||
│ • Instance: rozróżnia instancje tej samej klasy │
|
||||
│ • Panoptic: semantic + instance (unified) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Metody klasyczne
|
||||
|
||||
#### 2.1 Thresholding (progowanie)
|
||||
|
||||
```
|
||||
Globalne:
|
||||
pixel_out = 255 if pixel_in > T else 0
|
||||
|
||||
Otsu (automatyczny próg):
|
||||
- Maksymalizuje wariancję między klasami
|
||||
- σ²_between = w₀w₁(μ₀ - μ₁)²
|
||||
|
||||
Adaptacyjne:
|
||||
- Lokalny próg dla każdego regionu
|
||||
- T(x,y) = mean(neighborhood) - C
|
||||
|
||||
┌──────────────────┐ Threshold ┌──────────────────┐
|
||||
│░▒▓█░▒▓█░▒▓█░▒▓█ │ ────────────→ │░░██░░██░░██░░██ │
|
||||
│▒▓█░▒▓█░▒▓█░▒▓█░ │ T │░███░███░███░███░ │
|
||||
└──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
#### 2.2 Region Growing
|
||||
|
||||
```
|
||||
Algorytm:
|
||||
1. Wybierz punkt startowy (seed)
|
||||
2. Badaj sąsiadów
|
||||
3. Jeśli podobny (|I(neighbor) - I(region)| < threshold)
|
||||
→ dodaj do regionu
|
||||
4. Powtarzaj aż brak nowych pikseli
|
||||
|
||||
Seed Krok 1 Krok 2 Wynik
|
||||
● ●● ●●● ●●●●
|
||||
● ●●● ●●●●
|
||||
●● ●●●●
|
||||
```
|
||||
|
||||
#### 2.3 Watershed
|
||||
|
||||
```
|
||||
Obraz jako topografia:
|
||||
- Intensywność = wysokość
|
||||
- "Zalewanie" od minimów lokalnych
|
||||
- Granice gdzie woda z różnych źródeł się spotyka
|
||||
|
||||
╱╲ ╱╲
|
||||
╱ ╲ ╱ ╲
|
||||
╱ ╲__╱ ╲
|
||||
╱ ↑ ╲
|
||||
↑ granica ↑
|
||||
min1 (watershed) min2
|
||||
```
|
||||
|
||||
#### 2.4 Mean Shift
|
||||
|
||||
```
|
||||
Iteracyjne przesuwanie okna do maksimum gęstości:
|
||||
|
||||
1. Dla każdego piksela:
|
||||
m(x) = Σ K(x - xᵢ) × xᵢ / Σ K(x - xᵢ)
|
||||
|
||||
2. x ← m(x) (shift)
|
||||
3. Powtarzaj do zbieżności
|
||||
4. Piksele zbiegające do tego samego punktu → jeden segment
|
||||
```
|
||||
|
||||
#### 2.5 Graph-based (Normalized Cuts)
|
||||
|
||||
```
|
||||
Obraz jako graf:
|
||||
- Wierzchołki = piksele
|
||||
- Krawędzie = podobieństwo między pikselami
|
||||
- w(i,j) = exp(-||I(i) - I(j)||² / σ²)
|
||||
|
||||
Normalized Cut:
|
||||
Ncut(A,B) = cut(A,B)/assoc(A,V) + cut(A,B)/assoc(B,V)
|
||||
|
||||
Minimalizacja Ncut → eigendecomposition Laplacianu
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Porównanie metod klasycznych
|
||||
|
||||
| Metoda | Zalety | Wady |
|
||||
|--------|--------|------|
|
||||
| **Thresholding** | Szybki, prosty | Tylko 2 klasy, wrażliwy na oświetlenie |
|
||||
| **Region Growing** | Intuicyjny | Wymaga seedów, over-segmentation |
|
||||
| **Watershed** | Dobre krawędzie | Over-segmentation |
|
||||
| **Mean Shift** | Brak k | Wolny, parametr bandwidth |
|
||||
| **Graph Cut** | Globalnie optymalne | O(n³), wymaga unary terms |
|
||||
|
||||
---
|
||||
|
||||
### 4. Metody deep learning
|
||||
|
||||
#### 4.1 FCN (Fully Convolutional Network)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FCN - pierwsza architektura deep dla segmentacji (2015) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Input Encoder (VGG) Decoder Output │
|
||||
│ H×W×3 → Conv+Pool×5 → Upsampling (deconv) → H×W×C │
|
||||
│ │
|
||||
│ ┌────┐ ┌──┐ ┌──┐ ┌────┐ │
|
||||
│ │ │ → │ │ → │ │ → ··· → upsample → │ │ │
|
||||
│ │ │ │ │ │ │ ×32 │ │ │
|
||||
│ └────┘ └──┘ └──┘ └────┘ │
|
||||
│ input conv conv output │
|
||||
│ │
|
||||
│ Skip connections: FCN-32s, FCN-16s, FCN-8s │
|
||||
│ Coarser + finer features → sharper boundaries │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 4.2 U-Net
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ U-NET - encoder-decoder ze skip connections (2015) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Encoder Decoder │
|
||||
│ │ ↑ │
|
||||
│ ┌──┴──┐ ─ copy ─→ ┌──┴──┐ │
|
||||
│ │64×64│ │64×64│ │
|
||||
│ └──┬──┘ └──┬──┘ │
|
||||
│ ↓ ↑ │
|
||||
│ ┌──┴──┐ ─ copy ─→ ┌──┴──┐ │
|
||||
│ │32×32│ │32×32│ │
|
||||
│ └──┬──┘ └──┬──┘ │
|
||||
│ ↓ ↑ │
|
||||
│ ┌──┴──┐ ─ copy ─→ ┌──┴──┐ │
|
||||
│ │16×16│ │16×16│ │
|
||||
│ └──┬──┘ └──┬──┘ │
|
||||
│ ↓ ↑ │
|
||||
│ └───── bottleneck ───┘ │
|
||||
│ │
|
||||
│ Concat skip connections (nie add jak w ResNet) │
|
||||
│ Popularne w medycynie (małe datasety) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 4.3 DeepLab (v1-v3+)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DEEPLAB - Atrous/Dilated Convolutions + CRF │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Atrous Convolution (dilated): │
|
||||
│ │
|
||||
│ Standard 3×3: Atrous 3×3, rate=2: │
|
||||
│ ● ● ● ● ● ● │
|
||||
│ ● ● ● (większe receptive field │
|
||||
│ ● ● ● ● ● ● bez więcej parametrów) │
|
||||
│ │
|
||||
│ ● ● ● │
|
||||
│ │
|
||||
│ ASPP (Atrous Spatial Pyramid Pooling): │
|
||||
│ Parallel atrous conv z różnymi rates (6, 12, 18) │
|
||||
│ → multi-scale context │
|
||||
│ │
|
||||
│ DeepLabv3+: │
|
||||
│ Encoder-decoder + ASPP + depthwise separable conv │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 4.4 Transformer-based (SegFormer, Mask2Former)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SEGFORMER (2021) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Mix-Transformer encoder: │
|
||||
│ • Hierarchical features (1/4, 1/8, 1/16, 1/32) │
|
||||
│ • Efficient self-attention │
|
||||
│ • No positional encoding │
|
||||
│ │
|
||||
│ MLP decoder: │
|
||||
│ • Simple MLP combines multi-scale features │
|
||||
│ • Lightweight │
|
||||
│ │
|
||||
│ MASK2FORMER (2022): │
|
||||
│ • Universal: semantic, instance, panoptic │
|
||||
│ • Masked attention (per-segment) │
|
||||
│ • Deformable attention │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Porównanie architektur DL
|
||||
|
||||
| Architektura | mIoU (ADE20K) | Parametry | Cechy |
|
||||
|--------------|---------------|-----------|-------|
|
||||
| **FCN** | ~30% | ~135M | Pierwsze DL dla segmentacji |
|
||||
| **U-Net** | - | ~31M | Medical, skip connections |
|
||||
| **DeepLabv3+** | ~45% | ~60M | ASPP, dilated conv |
|
||||
| **SegFormer-B5** | ~51% | ~85M | Transformer, efficient |
|
||||
| **Mask2Former** | ~57% | ~200M | Universal, SOTA |
|
||||
|
||||
---
|
||||
|
||||
### 6. Loss functions
|
||||
|
||||
```
|
||||
Cross-Entropy Loss:
|
||||
L = -Σᵢ Σc yᵢc log(pᵢc)
|
||||
|
||||
Problem: class imbalance (dużo tła, mało obiektów)
|
||||
|
||||
Dice Loss:
|
||||
L = 1 - 2|X ∩ Y| / (|X| + |Y|)
|
||||
|
||||
Bezpośrednio optymalizuje IoU-like metric
|
||||
|
||||
Focal Loss:
|
||||
L = -αₜ(1 - pₜ)^γ log(pₜ)
|
||||
|
||||
γ > 0 → hard examples ważniejsze
|
||||
|
||||
Combined:
|
||||
L = λ₁ · CE + λ₂ · Dice
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Metryki
|
||||
|
||||
| Metryka | Formuła | Opis |
|
||||
|---------|---------|------|
|
||||
| **Pixel Accuracy** | TP / (TP+FP+FN+TN) | % poprawnych pikseli |
|
||||
| **IoU (Jaccard)** | TP / (TP+FP+FN) | Intersection over Union |
|
||||
| **mIoU** | mean IoU per class | Standard dla segmentacji |
|
||||
| **Dice** | 2TP / (2TP+FP+FN) | F1 dla segmentacji |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "U-Net = U-shaped skip":
|
||||
Kształt U z skip connections
|
||||
|
||||
### "ASPP = Atrous at Multiple Scales":
|
||||
DeepLab's Atrous Spatial Pyramid Pooling
|
||||
|
||||
### "IoU = Intersection / Union":
|
||||
Podstawowa metryka segmentacji
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jak radzić sobie z class imbalance?"
|
||||
**Odpowiedź:** Weighted cross-entropy, Focal Loss, oversampling małych klas, Dice Loss (ignoruje dominację dużych klas), OHEM (Online Hard Example Mining).
|
||||
|
||||
### Q2: "U-Net vs DeepLab?"
|
||||
**Odpowiedź:** U-Net: encoder-decoder z concat skip, dobre dla małych datasetów (medical). DeepLab: dilated conv zachowuje resolution, ASPP dla multi-scale, lepsze dla dużych datasetów.
|
||||
|
||||
### Q3: "Co to jest panoptic segmentation?"
|
||||
**Odpowiedź:** Unified semantic + instance. Dzieli na "stuff" (nieczęściowe: sky, road) i "things" (policzalne: person, car). Każdy piksel ma class ID + instance ID.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Klasyczne:** Thresholding, Region Growing, Watershed, Graph Cut
|
||||
2. **FCN:** Pierwszy fully convolutional dla segmentacji
|
||||
3. **U-Net:** Encoder-decoder + skip connections
|
||||
4. **DeepLab:** Dilated/Atrous conv, ASPP
|
||||
5. **Metryka:** mIoU (mean Intersection over Union)
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Long et al. - "Fully Convolutional Networks" (2015)
|
||||
2. Ronneberger et al. - "U-Net" (2015)
|
||||
3. Chen et al. - "DeepLab" series (2014-2018)
|
||||
4. Xie et al. - "SegFormer" (2021)
|
||||
@ -1,363 +0,0 @@
|
||||
# Pytanie 40: Detekcja obiektów w obrazach
|
||||
|
||||
## Pytanie
|
||||
**"Opisać problem detekcji obiektów w obrazach. Przedstawić podstawowe strategie i algorytmy detekcji przy użyciu metod klasycznych oraz sieci neuronowych. Jak skonstruować detektor obiektów dysponując istniejącym klasyfikatorem tych obiektów?"**
|
||||
|
||||
Przedmiot: TWM (Techniki Wizji Maszynowej)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Definicja problemu detekcji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DETEKCJA OBIEKTÓW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Obraz wejściowy: Wynik detekcji: │
|
||||
│ ┌────────────────┐ ┌────────────────┐ │
|
||||
│ │ 🚗 🚶 │ │ ┌──┐ ┌──┐ │ │
|
||||
│ │ 🚗 │ → │ │🚗│ │🚶│ │ │
|
||||
│ │ 🚶 │ │ └──┘ └──┘ ┌──┐ │ │
|
||||
│ │ │ │ ┌──┐│🚗│ │ │
|
||||
│ └────────────────┘ │ ┌──┤🚶│└──┘ │ │
|
||||
│ │ └──┴──┘ │ │
|
||||
│ └────────────────┘ │
|
||||
│ │
|
||||
│ Wynik: lista (class, bounding_box, confidence) │
|
||||
│ [(car, [x1,y1,x2,y2], 0.95), (person, [...], 0.87)] │
|
||||
│ │
|
||||
│ Różnica od klasyfikacji: │
|
||||
│ • Klasyfikacja: Co jest na obrazie? │
|
||||
│ • Detekcja: Co i GDZIE jest na obrazie? │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Metody klasyczne
|
||||
|
||||
#### 2.1 Sliding Window + HOG/SIFT
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SLIDING WINDOW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. Przesuwaj okno po obrazie (różne skale, pozycje) │
|
||||
│ │
|
||||
│ ┌──┐ │
|
||||
│ │░░│→→→→→→→→ │
|
||||
│ └──┘ │
|
||||
│ ↓ ↓ ↓ ↓ ↓ ↓ ↓ │
|
||||
│ │
|
||||
│ 2. Dla każdego okna: wyekstrahuj features (HOG, SIFT) │
|
||||
│ 3. Klasyfikuj (SVM, Random Forest) │
|
||||
│ 4. Non-Maximum Suppression (NMS) │
|
||||
│ │
|
||||
│ Problem: O(scales × positions × classifier) → WOLNE! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 2.2 HOG (Histogram of Oriented Gradients)
|
||||
|
||||
```
|
||||
HOG descriptor:
|
||||
1. Oblicz gradienty (Gx, Gy)
|
||||
2. Magnitude: √(Gx² + Gy²)
|
||||
3. Orientacja: arctan(Gy/Gx)
|
||||
4. Podziel na cells (8×8 pikseli)
|
||||
5. Histogram orientacji (9 bins)
|
||||
6. Normalizacja w blokach
|
||||
|
||||
┌───┬───┬───┬───┐
|
||||
│ │ │ │ │
|
||||
├───┼───┼───┼───┤
|
||||
│ │▓▓▓│▓▓▓│ │ ← histogram dla każdej cell
|
||||
├───┼───┼───┼───┤
|
||||
│ │▓▓▓│▓▓▓│ │
|
||||
└───┴───┴───┴───┘
|
||||
|
||||
Użycie: HOG + linear SVM → pedestrian detection (Dalal & Triggs)
|
||||
```
|
||||
|
||||
#### 2.3 Viola-Jones (Haar Cascades)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ VIOLA-JONES (2001) - real-time face detection │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Haar-like features: │
|
||||
│ ┌───┬───┐ ┌───────┐ ┌─┬─┐ │
|
||||
│ │░░░│███│ │░░░░░░░│ │░│█│ │
|
||||
│ │░░░│███│ │███████│ │█│░│ │
|
||||
│ └───┴───┘ └───────┘ └─┴─┘ │
|
||||
│ │
|
||||
│ Feature = Σ(white) - Σ(black) │
|
||||
│ Integral image: O(1) dla każdej feature! │
|
||||
│ │
|
||||
│ AdaBoost cascade: │
|
||||
│ Stage1 → Stage2 → Stage3 → ... → Face! │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ Reject Reject Reject (szybko odrzuca nie-twarze) │
|
||||
│ │
|
||||
│ Bardzo szybkie! (30fps w 2001) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Metody Deep Learning
|
||||
|
||||
#### 3.1 Two-Stage Detectors (R-CNN family)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ R-CNN (2014) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. Selective Search → ~2000 region proposals │
|
||||
│ 2. Dla każdego regionu: │
|
||||
│ - Resize do 224×224 │
|
||||
│ - CNN (AlexNet) → features │
|
||||
│ - SVM classifier │
|
||||
│ 3. Bounding box regression │
|
||||
│ 4. NMS │
|
||||
│ │
|
||||
│ Problem: 2000 × CNN forward pass → ~50 sec/image! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Fast R-CNN (2015) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Image → CNN → Feature map │
|
||||
│ ↓ │
|
||||
│ ROI Pooling (region proposals) │
|
||||
│ ↓ │
|
||||
│ FC layers │
|
||||
│ ↓ ↓ │
|
||||
│ class bbox │
|
||||
│ │
|
||||
│ CNN tylko raz! ROI pooling wycina regiony z feature map │
|
||||
│ ~2 sec/image (25× szybciej) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Faster R-CNN (2016) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Image → CNN → Feature map → RPN (Region Proposal Network) │
|
||||
│ │ ↓ │
|
||||
│ └──────→ ROI Pooling │
|
||||
│ ↓ │
|
||||
│ Detection head │
|
||||
│ ↓ ↓ │
|
||||
│ class bbox │
|
||||
│ │
|
||||
│ RPN: mała sieć generująca proposals (zamiast Selective Search) │
|
||||
│ End-to-end training! │
|
||||
│ ~0.2 sec/image (~5 fps) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 3.2 One-Stage Detectors (YOLO, SSD)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ YOLO (You Only Look Once) - 2016 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Image → CNN → S×S×(B×5 + C) tensor │
|
||||
│ │
|
||||
│ Dzieli obraz na S×S grid: │
|
||||
│ ┌───┬───┬───┬───┬───┬───┬───┐ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ ├───┼───┼───┼───┼───┼───┼───┤ │
|
||||
│ │ │ │ ● │ │ │ │ │ ← cell odpowiada za obiekt │
|
||||
│ ├───┼───┼───┼───┼───┼───┼───┤ którego centrum tu jest │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ └───┴───┴───┴───┴───┴───┴───┘ │
|
||||
│ │
|
||||
│ Każda cell predykuje: │
|
||||
│ • B bounding boxes: (x, y, w, h, confidence) │
|
||||
│ • C class probabilities │
|
||||
│ │
|
||||
│ Zaleta: Bardzo szybki! 45-155 fps │
|
||||
│ Wada: Gorszy dla małych obiektów, obiektów blisko siebie │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SSD (Single Shot Detector) - 2016 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Multi-scale feature maps: │
|
||||
│ │
|
||||
│ ┌────────────┐ │
|
||||
│ │ 38×38×512 │ ← detect small objects │
|
||||
│ └─────┬──────┘ │
|
||||
│ ↓ │
|
||||
│ ┌──────┐ │
|
||||
│ │19×19 │ ← detect medium objects │
|
||||
│ └──┬───┘ │
|
||||
│ ↓ │
|
||||
│ ┌────┐ │
|
||||
│ │10×10│ ← detect large objects │
|
||||
│ └────┘ │
|
||||
│ │
|
||||
│ Default boxes (anchors) o różnych aspect ratios │
|
||||
│ Łączy zalety YOLO (szybkość) i Faster R-CNN (multi-scale) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 3.3 Nowoczesne architektury
|
||||
|
||||
```
|
||||
YOLOv8 (2023):
|
||||
• Anchor-free detection
|
||||
• Decoupled head (cls/box separate)
|
||||
• C2f module (CSP + bottleneck)
|
||||
• ~80 mAP na COCO, real-time
|
||||
|
||||
DETR (2020):
|
||||
• Transformer-based
|
||||
• Bipartite matching loss (Hungarian)
|
||||
• No anchors, no NMS
|
||||
• End-to-end set prediction
|
||||
|
||||
RT-DETR (2023):
|
||||
• Real-time DETR
|
||||
• Efficient hybrid encoder
|
||||
• IoU-aware query selection
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Konstrukcja detektora z klasyfikatora
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ JAK ZROBIĆ DETEKTOR MAJĄC KLASYFIKATOR? │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Metoda 1: SLIDING WINDOW │
|
||||
│ ───────────────────────── │
|
||||
│ for scale in scales: │
|
||||
│ for (x, y) in positions: │
|
||||
│ crop = image[y:y+h, x:x+w] │
|
||||
│ if classifier(crop) > threshold: │
|
||||
│ detections.append((x, y, w, h, class)) │
|
||||
│ return NMS(detections) │
|
||||
│ │
|
||||
│ Problem: Bardzo wolne (wiele przesunięć × skale) │
|
||||
│ │
|
||||
│ │
|
||||
│ Metoda 2: REGION PROPOSALS + CLASSIFIER │
|
||||
│ ───────────────────────────────────────── │
|
||||
│ 1. Selective Search / EdgeBoxes → candidate regions │
|
||||
│ 2. Dla każdego regionu: │
|
||||
│ resize + classifier → class, confidence │
|
||||
│ 3. NMS │
|
||||
│ │
|
||||
│ Szybsze niż sliding window (mniej regionów) │
|
||||
│ │
|
||||
│ │
|
||||
│ Metoda 3: FINE-TUNE na DETECTION │
|
||||
│ ───────────────────────────────── │
|
||||
│ 1. Użyj pretrained classifier jako backbone │
|
||||
│ 2. Dodaj detection head (bbox regression + cls) │
|
||||
│ 3. Fine-tune na detection dataset │
|
||||
│ │
|
||||
│ Najlepsza jakość! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Non-Maximum Suppression (NMS)
|
||||
|
||||
```
|
||||
Problem: Wiele overlapping detections
|
||||
|
||||
┌─────────┐
|
||||
│ ┌──────┼──┐
|
||||
│ │ 🚗 │ │ ← 3 nakładające się bbox
|
||||
│ │ │ │
|
||||
└──┼──────┘ │
|
||||
└─────────┘
|
||||
|
||||
NMS Algorithm:
|
||||
1. Sortuj detekcje wg confidence
|
||||
2. Weź najlepszą, dodaj do wyników
|
||||
3. Usuń wszystkie z IoU > threshold
|
||||
4. Powtarzaj dla pozostałych
|
||||
|
||||
Soft-NMS: Nie usuwa, tylko obniża confidence
|
||||
score = score × f(IoU) gdzie f maleje z IoU
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Metryki
|
||||
|
||||
| Metryka | Opis |
|
||||
|---------|------|
|
||||
| **IoU** | Intersection over Union bbox |
|
||||
| **Precision** | TP / (TP + FP) |
|
||||
| **Recall** | TP / (TP + FN) |
|
||||
| **AP** | Area under Precision-Recall curve |
|
||||
| **mAP** | Mean AP across classes |
|
||||
| **mAP@0.5** | mAP przy IoU threshold = 0.5 |
|
||||
| **mAP@[.5:.95]** | mAP average across IoU thresholds |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "YOLO = You Only Look Once":
|
||||
Jednokrotne przejście przez sieć
|
||||
|
||||
### "R-CNN → Fast → Faster":
|
||||
Ewolucja: 50s → 2s → 0.2s
|
||||
|
||||
### "Two-stage = proposals + classify":
|
||||
Faster R-CNN: RPN + detection head
|
||||
|
||||
### "One-stage = direct":
|
||||
YOLO, SSD: bezpośrednia predykcja
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "YOLO vs Faster R-CNN?"
|
||||
**Odpowiedź:** YOLO: szybszy (real-time), gorszy dla małych obiektów. Faster R-CNN: dokładniejszy, wolniejszy, two-stage (RPN + detection). Trade-off speed vs accuracy.
|
||||
|
||||
### Q2: "Co to są anchor boxes?"
|
||||
**Odpowiedź:** Predefiniowane boxy o różnych rozmiarach i aspect ratios. Sieć predykuje offset od anchora, nie absolutne koordynaty. Ułatwia uczenie (mniejsza przestrzeń wyjściowa).
|
||||
|
||||
### Q3: "Jak działają anchor-free detektory?"
|
||||
**Odpowiedź:** Predykują bezpośrednio: punkt centralny + rozmiar (FCOS, CenterNet) lub keypoints (CornerNet). Prostsze, mniej hiperparametrów, konkurencyjne wyniki.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Klasyczne:** HOG+SVM, Viola-Jones (Haar cascades)
|
||||
2. **Two-stage:** R-CNN → Fast → Faster (RPN)
|
||||
3. **One-stage:** YOLO, SSD (szybsze, real-time)
|
||||
4. **NMS:** Eliminacja overlapping detekcji
|
||||
5. **Metryka:** mAP@[.5:.95]
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Girshick et al. - "R-CNN" (2014), "Fast R-CNN" (2015)
|
||||
2. Ren et al. - "Faster R-CNN" (2016)
|
||||
3. Redmon et al. - "YOLO" series (2016-2018)
|
||||
4. Liu et al. - "SSD" (2016)
|
||||
5. Carion et al. - "DETR" (2020)
|
||||
@ -1,270 +0,0 @@
|
||||
# Pytanie 41: Interaktywne wspomaganie decyzji w warunkach ryzyka
|
||||
|
||||
## Pytanie
|
||||
**"Przedstawić metody interaktywne wspomagania decyzji w warunkach ryzyka."**
|
||||
|
||||
Przedmiot: WDWR (Wspomaganie Decyzji w Warunkach Ryzyka)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Decyzje w warunkach ryzyka
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WARUNKI PODEJMOWANIA DECYZJI │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ PEWNOŚĆ: Znamy dokładnie wyniki każdej decyzji │
|
||||
│ (deterministyczne) │
|
||||
│ │
|
||||
│ RYZYKO: Znamy możliwe wyniki i ich prawdopodobieństwa │
|
||||
│ (stochastyczne, rozkłady znane) │
|
||||
│ │
|
||||
│ NIEPEWNOŚĆ: Możliwe wyniki znane, prawdopodobieństwa nie │
|
||||
│ (scenariusze bez prawdopodobieństw) │
|
||||
│ │
|
||||
│ Decyzja w warunkach ryzyka: │
|
||||
│ • Wybór między loteriami (gambles) │
|
||||
│ • Każda loteria: zbiór wyników z prawdopodobieństwami │
|
||||
│ • Decydent ma preferencje dotyczące ryzyka │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Metody interaktywne - przegląd
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ INTERAKTYWNE = Dialog z decydentem │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ DECYDENT │ ←─────→ │ SYSTEM │ │
|
||||
│ │ (preferencje)│ │ (analiza) │ │
|
||||
│ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │
|
||||
│ ↓ ↓ │
|
||||
│ Odpowiedzi na Generowanie pytań, │
|
||||
│ pytania, wybory eliminacja opcji, │
|
||||
│ porównawcze rekomendacje │
|
||||
│ │
|
||||
│ Cel: Odkryć preferencje decydenta (funkcję użyteczności) │
|
||||
│ bez wymagania pełnej specyfikacji z góry │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Metoda loterii (Lottery Method)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ELICYTACJA FUNKCJI UŻYTECZNOŚCI │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Cel: Wyznaczyć U(x) dla różnych wartości x │
|
||||
│ │
|
||||
│ Procedura: │
|
||||
│ 1. Ustal U(x_worst) = 0, U(x_best) = 1 │
|
||||
│ │
|
||||
│ 2. Dla wartości pośredniej x_mid, pytaj: │
|
||||
│ "Wolisz x_mid na pewno, czy loterię │
|
||||
│ (p: x_best, 1-p: x_worst)?" │
|
||||
│ │
|
||||
│ 3. Znajdź p* gdzie decydent jest obojętny: │
|
||||
│ U(x_mid) = p* × U(x_best) + (1-p*) × U(x_worst) │
|
||||
│ U(x_mid) = p* × 1 + (1-p*) × 0 = p* │
|
||||
│ │
|
||||
│ 4. Powtórz dla kolejnych punktów │
|
||||
│ │
|
||||
│ Przykład: │
|
||||
│ x_worst = 0 PLN, x_best = 1000 PLN, x_mid = 500 PLN │
|
||||
│ Pytanie: "500 PLN na pewno czy loteria (p: 1000, 1-p: 0)?" │
|
||||
│ Jeśli obojętny przy p* = 0.6 → U(500) = 0.6 │
|
||||
│ (risk averse: 0.6 < 0.5 liniowego) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Metoda pewnego ekwiwalentu (Certainty Equivalent)
|
||||
|
||||
```
|
||||
CE (Certainty Equivalent) = pewna kwota równoważna loterii
|
||||
|
||||
Dla loterii L = (p₁: x₁, p₂: x₂, ...):
|
||||
CE(L) taki że U(CE) = E[U(L)] = Σ pᵢ U(xᵢ)
|
||||
|
||||
Pytanie interaktywne:
|
||||
"Ile PLN na pewno jest dla Ciebie równoważne loterii
|
||||
(50%: 1000 PLN, 50%: 0 PLN)?"
|
||||
|
||||
Odpowiedź CE = 400 PLN oznacza:
|
||||
U(400) = 0.5 × U(1000) + 0.5 × U(0) = 0.5
|
||||
|
||||
Risk Premium = E[X] - CE = 500 - 400 = 100 PLN
|
||||
(ile decydent "płaci" za uniknięcie ryzyka)
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ U(x) │
|
||||
│ ↑ Risk Averse Risk Neutral Risk Seeking │
|
||||
│ │ ╭─── / ───╮ │
|
||||
│ │ ╭─╯ / ╰─╮ │
|
||||
│ │ ╭─╯ / ╰─╮ │
|
||||
│ │ ╭─╯ / ╰─╮ │
|
||||
│ │╭─╯ / ╰╮│
|
||||
│ └──────────────────────────────────────────────────────────→ x│
|
||||
│ CE < E[X] CE = E[X] CE > E[X] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Metoda AHP (Analytic Hierarchy Process)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ AHP - Hierarchiczna struktura problemu (Saaty) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ CEL │ │
|
||||
│ └──────┬──────┘ │
|
||||
│ ┌───────────────┼───────────────┐ │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │Kryterium1│ │Kryterium2│ │Kryterium3│ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||
│ └──────────────┼──────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌─────┬─────┬─────┐ │
|
||||
│ │Alt A│Alt B│Alt C│ │
|
||||
│ └─────┴─────┴─────┘ │
|
||||
│ │
|
||||
│ Porównania parami (skala 1-9): │
|
||||
│ "Ile razy kryterium K1 jest ważniejsze od K2?" │
|
||||
│ │
|
||||
│ Macierz porównań → eigenvalue → wagi │
|
||||
│ Consistency Ratio CR < 0.1 (sprawdzenie spójności) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Metoda PROMETHEE
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PROMETHEE - Preference Ranking Organization Method │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. Dla każdego kryterium j, definiuj funkcję preferencji Pⱼ │
|
||||
│ Pⱼ(a,b) = P(dⱼ) gdzie dⱼ = fⱼ(a) - fⱼ(b) │
|
||||
│ │
|
||||
│ Typy funkcji preferencji: │
|
||||
│ │ │ ____ │
|
||||
│ │ ____ │ / │
|
||||
│ │ / │ / │
|
||||
│ │___/ │___/ │
|
||||
│ Próg (threshold) Liniowa (V-shape) │
|
||||
│ │
|
||||
│ 2. Agregacja: │
|
||||
│ π(a,b) = Σⱼ wⱼ Pⱼ(a,b) (indeks preferencji) │
|
||||
│ │
|
||||
│ 3. Przepływy: │
|
||||
│ Φ⁺(a) = Σᵦ π(a,b) (outranking flow) │
|
||||
│ Φ⁻(a) = Σᵦ π(b,a) (outranked flow) │
|
||||
│ Φ(a) = Φ⁺(a) - Φ⁻(a) (net flow) │
|
||||
│ │
|
||||
│ 4. Ranking wg Φ(a) │
|
||||
│ │
|
||||
│ Interaktywność: wybór funkcji preferencji, progów, wag │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Metoda ELECTRE
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ELECTRE - ELimination Et Choix Traduisant la REalité │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Outranking: "a jest co najmniej tak dobra jak b" (aSb) │
|
||||
│ │
|
||||
│ Concordance Index C(a,b): │
|
||||
│ C(a,b) = Σ{wⱼ : fⱼ(a) ≥ fⱼ(b)} / Σwⱼ │
|
||||
│ (suma wag kryteriów gdzie a ≥ b) │
|
||||
│ │
|
||||
│ Discordance Index D(a,b): │
|
||||
│ D(a,b) = max{(fⱼ(b) - fⱼ(a)) / Δⱼ} │
|
||||
│ (największa przewaga b nad a, znormalizowana) │
|
||||
│ │
|
||||
│ Outranking: │
|
||||
│ aSb ⟺ C(a,b) ≥ c* AND D(a,b) ≤ d* │
|
||||
│ (wystarczająca zgodność, brak silnego sprzeciwu) │
|
||||
│ │
|
||||
│ Interaktywność: progi c*, d*, wagi wⱼ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. Porównanie metod
|
||||
|
||||
| Metoda | Typ | Interakcja | Zastosowanie |
|
||||
|--------|-----|------------|--------------|
|
||||
| **Lottery** | Utility | Porównania z loteriami | Elicytacja U(x) |
|
||||
| **CE** | Utility | Pewne ekwiwalenty | Pomiar ryzyka |
|
||||
| **AHP** | MCDM | Porównania parami | Hierarchie, wagi |
|
||||
| **PROMETHEE** | Outranking | Funkcje preferencji | Ranking |
|
||||
| **ELECTRE** | Outranking | Progi zgodności | Eliminacja |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "CE = Certain Equivalent":
|
||||
Pewna kwota równoważna loterii
|
||||
|
||||
### "AHP = Ask, Hierarchize, Prioritize":
|
||||
Pytaj, buduj hierarchię, ustal priorytety
|
||||
|
||||
### "PROMETHEE = Przepływy":
|
||||
Φ⁺ (outgoing), Φ⁻ (incoming), Φ (net)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jak wykryć niespójność odpowiedzi decydenta?"
|
||||
**Odpowiedź:** AHP: Consistency Ratio (CR < 0.1). Utility: sprawdzenie monotoniczności, przechodniości preferencji. Cross-validation różnymi metodami elicytacji.
|
||||
|
||||
### Q2: "Co to jest awersja do ryzyka?"
|
||||
**Odpowiedź:** Risk averse: U''(x) < 0 (funkcja wklęsła), CE < E[X], preferuje pewność nad loterię o tej samej wartości oczekiwanej. Miernik: Arrow-Pratt coefficient r(x) = -U''(x)/U'(x).
|
||||
|
||||
### Q3: "AHP vs PROMETHEE?"
|
||||
**Odpowiedź:** AHP: hierarchiczna dekompozycja, porównania parami, pełna kompensacja. PROMETHEE: outranking, progi preferencji, częściowa kompensacja, lepsze dla nieporównywalnych kryteriów.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Ryzyko:** Znane prawdopodobieństwa wyników
|
||||
2. **Interaktywność:** Dialog z decydentem
|
||||
3. **Loterie:** Elicytacja U(x) przez porównania
|
||||
4. **CE:** Certainty Equivalent, miara awersji do ryzyka
|
||||
5. **AHP/PROMETHEE/ELECTRE:** Metody wielokryterialne
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. von Neumann, Morgenstern - "Theory of Games and Economic Behavior"
|
||||
2. Saaty - "The Analytic Hierarchy Process"
|
||||
3. Brans, Vincke - "PROMETHEE Method"
|
||||
4. Roy - "ELECTRE Methods"
|
||||
@ -1,291 +0,0 @@
|
||||
# Pytanie 42: Dominacja stochastyczna
|
||||
|
||||
## Pytanie
|
||||
**"Scharakteryzować relacje dominacji stochastycznej pierwszego i drugiego rzędu. Jak mogą być użyte w modelach wyboru w warunkach ryzyka?"**
|
||||
|
||||
Przedmiot: WDWR (Wspomaganie Decyzji w Warunkach Ryzyka)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Idea dominacji stochastycznej
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DOMINACJA STOCHASTYCZNA (Stochastic Dominance) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Cel: Porównać rozkłady prawdopodobieństwa (loterie) │
|
||||
│ BEZ znajomości dokładnej funkcji użyteczności │
|
||||
│ │
|
||||
│ Pytanie: "Czy loteria A jest lepsza od loterii B │
|
||||
│ dla KAŻDEGO racjonalnego decydenta?" │
|
||||
│ │
|
||||
│ Jeśli A dominuje B → KAŻDY wybierze A (niezależnie od U) │
|
||||
│ │
|
||||
│ Hierarchia: │
|
||||
│ FSD (First-order) ⊂ SSD (Second-order) ⊂ TSD (Third-order) │
|
||||
│ │
|
||||
│ FSD implikuje SSD, ale nie odwrotnie │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Dominacja stochastyczna pierwszego rzędu (FSD)
|
||||
|
||||
#### Definicja
|
||||
|
||||
$$A \succeq_{FSD} B \Leftrightarrow F_A(x) \leq F_B(x) \quad \forall x$$
|
||||
|
||||
gdzie $F(x) = P(X \leq x)$ to dystrybuanta (CDF)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FSD: "A dominuje B jeśli F_A jest zawsze poniżej F_B" │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ F(x) │
|
||||
│ ↑ │
|
||||
│ 1 │ ╭───── F_B │
|
||||
│ │ ╭──╯ │
|
||||
│ │ ╭──╯ │
|
||||
│ │ ╭──╯ │
|
||||
│ │ ╭──╯ ╭───── F_A │
|
||||
│ │ ╭──╯ ╭──╯ │
|
||||
│ │ ╭──╯ ╭──╯ │
|
||||
│ │──╯ ╭──╯ │
|
||||
│ 0 └──────────────────────────────────────────────→ x │
|
||||
│ │
|
||||
│ F_A(x) ≤ F_B(x) dla każdego x → A dominuje B (FSD) │
|
||||
│ │
|
||||
│ Interpretacja: A ma zawsze większe prawdopodobieństwo │
|
||||
│ przekroczenia dowolnego progu x │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Charakterystyka FSD
|
||||
|
||||
| Aspekt | Opis |
|
||||
|--------|------|
|
||||
| **Warunek na U** | U'(x) ≥ 0 (monotoniczność, "więcej = lepiej") |
|
||||
| **Klasa decydentów** | WSZYSCY racjonalni (nienasyceni) |
|
||||
| **Siła** | Najsilniejsza dominacja |
|
||||
| **Częstość** | Rzadko występuje w praktyce |
|
||||
|
||||
#### Równoważna definicja
|
||||
|
||||
$$E[U(A)] \geq E[U(B)] \quad \forall U: U' \geq 0$$
|
||||
|
||||
---
|
||||
|
||||
### 3. Dominacja stochastyczna drugiego rzędu (SSD)
|
||||
|
||||
#### Definicja
|
||||
|
||||
$$A \succeq_{SSD} B \Leftrightarrow \int_{-\infty}^{x} F_A(t) dt \leq \int_{-\infty}^{x} F_B(t) dt \quad \forall x$$
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SSD: "Skumulowane pole pod F_A ≤ pole pod F_B" │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ F(x) ∫F(t)dt │
|
||||
│ ↑ ↑ │
|
||||
│ │ ╭── F_B │ ╭── ∫F_B │
|
||||
│ │ ╭─╯ │ ╭─╯ │
|
||||
│ │ ╱ ╭── F_A │ ╭─╯ │
|
||||
│ │╱ ╭─╯ │ ╭─╯ ╭── ∫F_A │
|
||||
│ ┼──────────→ x │ ╭─╯ ╭─╯ │
|
||||
│ │─╯───╭─╯ │
|
||||
│ Krzywe mogą └───────────────→ x │
|
||||
│ się przecinać! Skumulowane nie! │
|
||||
│ │
|
||||
│ SSD dopuszcza przecięcia CDF, ale całki muszą zachować relację│
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Charakterystyka SSD
|
||||
|
||||
| Aspekt | Opis |
|
||||
|--------|------|
|
||||
| **Warunek na U** | U' ≥ 0 i U'' ≤ 0 (monotoniczne + wklęsłe) |
|
||||
| **Klasa decydentów** | Risk-averse (awersja do ryzyka) |
|
||||
| **Siła** | Słabsza niż FSD |
|
||||
| **Częstość** | Częstsza niż FSD |
|
||||
|
||||
#### Równoważna definicja
|
||||
|
||||
$$E[U(A)] \geq E[U(B)] \quad \forall U: U' \geq 0, U'' \leq 0$$
|
||||
|
||||
---
|
||||
|
||||
### 4. Porównanie FSD i SSD
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FSD vs SSD │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Przykład 1: FSD │
|
||||
│ A: 50% szans na 100, 50% na 200 │
|
||||
│ B: 50% szans na 50, 50% na 150 │
|
||||
│ A dominuje B (FSD) - zawsze lepsze wyniki │
|
||||
│ │
|
||||
│ Przykład 2: SSD (ale nie FSD) │
|
||||
│ A: 100 na pewno │
|
||||
│ B: 50% szans na 50, 50% na 150 │
|
||||
│ E[A] = 100 = E[B], ale A ma mniejszą wariancję │
|
||||
│ A dominuje B (SSD) dla risk-averse │
|
||||
│ NIE dominuje (FSD) - B może dać 150 > 100 │
|
||||
│ │
|
||||
│ Przykład 3: Mean-Preserving Spread (MPS) │
|
||||
│ B = A + ε, gdzie E[ε|A] = 0 (noise) │
|
||||
│ A dominuje B (SSD) - ta sama średnia, większy rozrzut B │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| Cecha | FSD | SSD |
|
||||
|-------|-----|-----|
|
||||
| **Warunek** | F_A(x) ≤ F_B(x) ∀x | ∫F_A ≤ ∫F_B ∀x |
|
||||
| **Na U** | U' ≥ 0 | U' ≥ 0, U'' ≤ 0 |
|
||||
| **Decydenci** | Wszyscy racjonalni | Risk-averse |
|
||||
| **Implikacja** | FSD ⟹ SSD | SSD ⇏ FSD |
|
||||
| **Praktyka** | Rzadka | Częstsza |
|
||||
|
||||
---
|
||||
|
||||
### 5. Zastosowanie w modelach wyboru
|
||||
|
||||
#### Portfolio Selection
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WYBÓR PORTFELA │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Problem: Wybór między portfelami P₁, P₂, ..., Pₙ │
|
||||
│ │
|
||||
│ Krok 1: Sprawdź FSD │
|
||||
│ Jeśli Pᵢ FSD Pⱼ → wyeliminuj Pⱼ │
|
||||
│ (żaden racjonalny inwestor nie wybierze Pⱼ) │
|
||||
│ │
|
||||
│ Krok 2: Sprawdź SSD (dla risk-averse) │
|
||||
│ Jeśli Pᵢ SSD Pⱼ → wyeliminuj Pⱼ dla risk-averse │
|
||||
│ │
|
||||
│ Krok 3: Dla pozostałych - potrzebna specyfikacja U │
|
||||
│ │
|
||||
│ Efektywny zbiór SD = portfele niezdominowane │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Ocena inwestycji
|
||||
|
||||
```
|
||||
Inwestycja A: Zwrot ~ N(10%, 15%)
|
||||
Inwestycja B: Zwrot ~ N(8%, 20%)
|
||||
|
||||
Test SSD:
|
||||
• E[A] = 10% > E[B] = 8% ✓
|
||||
• σ[A] = 15% < σ[B] = 20% ✓
|
||||
|
||||
Dla rozkładów normalnych z E[A] > E[B] i σ[A] < σ[B]:
|
||||
A dominuje B (SSD)
|
||||
|
||||
Wniosek: Każdy risk-averse inwestor wybierze A
|
||||
```
|
||||
|
||||
#### Ubezpieczenia
|
||||
|
||||
```
|
||||
Bez ubezpieczenia: Loteria L z ryzykiem straty
|
||||
Z ubezpieczeniem: CE (pewna strata = składka)
|
||||
|
||||
Jeśli składka = "fair" (E[składka] = E[straty]):
|
||||
Ubezpieczenie SSD dominuje brak ubezpieczenia
|
||||
dla każdego risk-averse decydenta
|
||||
|
||||
Uzasadnienie zakupu ubezpieczenia bez znajomości U!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Testowanie dominacji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ALGORYTM SPRAWDZANIA SD │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Dane: Dwa rozkłady empiryczne (próbki x₁,...,xₙ i y₁,...,yₘ) │
|
||||
│ │
|
||||
│ FSD Test: │
|
||||
│ 1. Oblicz empiryczne CDF: F̂_X(t), F̂_Y(t) │
|
||||
│ 2. Sprawdź czy F̂_X(t) ≤ F̂_Y(t) dla wszystkich t │
|
||||
│ │
|
||||
│ SSD Test: │
|
||||
│ 1. Oblicz ∫F̂_X(t)dt i ∫F̂_Y(t)dt │
|
||||
│ 2. Sprawdź czy pierwsza ≤ druga dla wszystkich punktów │
|
||||
│ │
|
||||
│ Testy statystyczne: │
|
||||
│ • Kolmogorov-Smirnov (FSD) │
|
||||
│ • Barrett-Donald test │
|
||||
│ • Linton-Maasoumi-Whang test │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Ograniczenia
|
||||
|
||||
| Ograniczenie | Opis |
|
||||
|--------------|------|
|
||||
| **Częściowe uporządkowanie** | Nie wszystkie pary porównywalne |
|
||||
| **Konserwatywność** | Wiele par bez dominacji |
|
||||
| **Wymóg pełnego rozkładu** | Potrzebna cała dystrybuanta |
|
||||
| **Brak dominacji ≠ obojętność** | Brak dominacji nie znaczy równoważność |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "FSD = F always ≤":
|
||||
First-order: dystrybuanta A zawsze ≤ B
|
||||
|
||||
### "SSD = Second = Sum (integral)":
|
||||
Second-order: całka z F_A ≤ całka z F_B
|
||||
|
||||
### "FSD = wszyscy, SSD = risk-averse":
|
||||
FSD: U' ≥ 0, SSD: U' ≥ 0, U'' ≤ 0
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy FSD a kiedy SSD?"
|
||||
**Odpowiedź:** FSD: gdy jeden rozkład jest jednoznacznie lepszy (przesunięty w prawo). SSD: gdy różnica w ryzyku (rozproszeniu) kompensuje różnicę w średniej dla risk-averse.
|
||||
|
||||
### Q2: "Co jeśli ani FSD ani SSD?"
|
||||
**Odpowiedź:** Rozkłady są nieporównywalne w sensie SD. Potrzebna dokładniejsza specyfikacja preferencji (konkretna funkcja użyteczności) lub TSD (trzeci rząd).
|
||||
|
||||
### Q3: "Związek SD z mean-variance?"
|
||||
**Odpowiedź:** Mean-variance (Markowitz) to przybliżenie. SSD jest bardziej ogólne - nie wymaga założenia normalności rozkładu. Dla rozkładów normalnych: SSD ≈ dominacja mean-variance.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **FSD:** F_A(x) ≤ F_B(x) ∀x, dla U' ≥ 0
|
||||
2. **SSD:** ∫F_A ≤ ∫F_B, dla U' ≥ 0, U'' ≤ 0
|
||||
3. **FSD ⟹ SSD** (ale nie odwrotnie)
|
||||
4. **Zastosowanie:** Eliminacja zdominowanych opcji
|
||||
5. **Bez znajomości U:** Decyzja dla klasy decydentów
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Hadar, Russell - "Rules for Ordering Uncertain Prospects"
|
||||
2. Levy - "Stochastic Dominance"
|
||||
3. Rothschild, Stiglitz - "Increasing Risk"
|
||||
@ -1,276 +0,0 @@
|
||||
# Pytanie 43: Klasyfikacja zadań szeregowania
|
||||
|
||||
## Pytanie
|
||||
**"Jakie cechy zadań szeregowania wykorzystuje się do ich klasyfikacji? Omówić przykładową metodę dla wybranego problemu szeregowania."**
|
||||
|
||||
Przedmiot: ZBOP (Zarządzanie i Badania Operacyjne w Produkcji)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Notacja Graham'a (α|β|γ)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ NOTACJA KLASYFIKACJI ZADAŃ SZEREGOWANIA │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ α | β | γ │
|
||||
│ │ │ │ │
|
||||
│ │ │ └── Kryterium optymalizacji │
|
||||
│ │ └────── Charakterystyki zadań │
|
||||
│ └────────── Środowisko maszynowe │
|
||||
│ │
|
||||
│ Przykład: Pm | prec, pⱼ=1 | Cmax │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ └── minimalizuj makespan │
|
||||
│ │ │ └── jednostkowe czasy │
|
||||
│ │ └── ograniczenia kolejnościowe │
|
||||
│ └── m maszyn równoległych │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Pole α - Środowisko maszynowe
|
||||
|
||||
| Symbol | Opis |
|
||||
|--------|------|
|
||||
| **1** | Jedna maszyna |
|
||||
| **P** | Maszyny równoległe identyczne |
|
||||
| **Pm** | m maszyn równoległych identycznych |
|
||||
| **Q** | Maszyny równoległe o różnych prędkościach |
|
||||
| **R** | Maszyny niezwiązane (unrelated) |
|
||||
| **F** | Flow shop (linia produkcyjna) |
|
||||
| **Fm** | Flow shop z m maszynami |
|
||||
| **J** | Job shop |
|
||||
| **Jm** | Job shop z m maszynami |
|
||||
| **O** | Open shop |
|
||||
|
||||
```
|
||||
JEDNA MASZYNA (1):
|
||||
Job 1 ──→ ┌───┐
|
||||
Job 2 ──→ │ M │ ──→ Output
|
||||
Job 3 ──→ └───┘
|
||||
|
||||
MASZYNY RÓWNOLEGŁE (Pm):
|
||||
Job 1 ──→ ┌───┐
|
||||
│M1 │ ──→
|
||||
Job 2 ──→ ├───┤
|
||||
│M2 │ ──→ Output
|
||||
Job 3 ──→ ├───┤
|
||||
│M3 │ ──→
|
||||
└───┘
|
||||
|
||||
FLOW SHOP (F):
|
||||
Job 1 ──→ ┌───┐ ──→ ┌───┐ ──→ ┌───┐ ──→
|
||||
│M1 │ │M2 │ │M3 │
|
||||
Job 2 ──→ └───┘ ──→ └───┘ ──→ └───┘ ──→
|
||||
|
||||
JOB SHOP (J):
|
||||
Każde zadanie ma własną trasę przez maszyny
|
||||
Job 1: M1 → M3 → M2
|
||||
Job 2: M2 → M1 → M3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Pole β - Charakterystyki zadań
|
||||
|
||||
| Symbol | Opis |
|
||||
|--------|------|
|
||||
| **rⱼ** | Release dates (terminy dostępności) |
|
||||
| **dⱼ** | Due dates (terminy wymagane) |
|
||||
| **d̄ⱼ** | Deadlines (nieprzekraczalne terminy) |
|
||||
| **prec** | Precedence constraints (kolejność) |
|
||||
| **pmtn** | Preemption allowed (przerwanie dozwolone) |
|
||||
| **pⱼ=1** | Unit processing times |
|
||||
| **sᵢⱼ** | Setup times (czasy przezbrojeń) |
|
||||
| **brkdwn** | Machine breakdowns |
|
||||
| **batch** | Batch processing |
|
||||
|
||||
---
|
||||
|
||||
### 4. Pole γ - Kryteria optymalizacji
|
||||
|
||||
| Symbol | Nazwa | Formuła |
|
||||
|--------|-------|---------|
|
||||
| **Cmax** | Makespan | max Cⱼ |
|
||||
| **ΣCⱼ** | Total completion time | Σ Cⱼ |
|
||||
| **Σwⱼ Cⱼ** | Weighted completion | Σ wⱼ Cⱼ |
|
||||
| **Lmax** | Max lateness | max(Cⱼ - dⱼ) |
|
||||
| **Tmax** | Max tardiness | max(0, Cⱼ - dⱼ) |
|
||||
| **ΣTⱼ** | Total tardiness | Σ max(0, Cⱼ - dⱼ) |
|
||||
| **ΣUⱼ** | Number of tardy jobs | Σ 𝟙(Cⱼ > dⱼ) |
|
||||
|
||||
```
|
||||
Cⱼ = Completion time zadania j
|
||||
Lⱼ = Cⱼ - dⱼ (lateness, może być ujemne)
|
||||
Tⱼ = max(0, Lⱼ) (tardiness, ≥ 0)
|
||||
Uⱼ = 1 jeśli Tⱼ > 0, else 0 (unit penalty)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Złożoność obliczeniowa
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZŁOŻONOŚĆ WYBRANYCH PROBLEMÓW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ WIELOMIANOWE (P): │
|
||||
│ 1 || Cmax O(n) (dowolna kolejność) │
|
||||
│ 1 || ΣCⱼ O(n log n) (SPT rule) │
|
||||
│ 1 || Lmax O(n log n) (EDD rule) │
|
||||
│ Pm || Cmax O(n log n) (LPT heuristic) │
|
||||
│ │
|
||||
│ NP-TRUDNE: │
|
||||
│ 1 || ΣTⱼ NP-hard │
|
||||
│ 1 || ΣwⱼCⱼ (rⱼ) NP-hard │
|
||||
│ Pm || Cmax (m≥2) NP-hard (ale PTAS istnieje) │
|
||||
│ Fm || Cmax (m≥3) NP-hard (flow shop ≥3 maszyny) │
|
||||
│ Jm || Cmax silnie NP-hard │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Przykładowa metoda: Problem 1 || ΣCⱼ
|
||||
|
||||
#### Problem
|
||||
|
||||
```
|
||||
Jedna maszyna, n zadań, minimalizuj sumę czasów zakończenia
|
||||
|
||||
Dane:
|
||||
Zadanie: J1 J2 J3 J4 J5
|
||||
Czas pⱼ: 5 3 8 2 6
|
||||
```
|
||||
|
||||
#### Metoda: SPT (Shortest Processing Time)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ REGUŁA SPT: Szereguj zadania w kolejności rosnących pⱼ │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Posortowane: J4(2), J2(3), J1(5), J5(6), J3(8) │
|
||||
│ │
|
||||
│ Harmonogram: │
|
||||
│ │
|
||||
│ ├──J4──┼───J2───┼─────J1─────┼──────J5──────┼────────J3────────┤
|
||||
│ 0 2 5 10 16 24
|
||||
│ │
|
||||
│ Czasy zakończenia: │
|
||||
│ C₄ = 2 │
|
||||
│ C₂ = 2 + 3 = 5 │
|
||||
│ C₁ = 5 + 5 = 10 │
|
||||
│ C₅ = 10 + 6 = 16 │
|
||||
│ C₃ = 16 + 8 = 24 │
|
||||
│ │
|
||||
│ ΣCⱼ = 2 + 5 + 10 + 16 + 24 = 57 │
|
||||
│ │
|
||||
│ Dowód optymalności: │
|
||||
│ Zamiana sąsiednich i,j gdzie pᵢ > pⱼ zawsze zwiększa ΣC │
|
||||
│ SPT daje globalnie optymalne rozwiązanie │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Dlaczego SPT jest optymalne?
|
||||
|
||||
```
|
||||
Dla dwóch zadań i, j:
|
||||
Kolejność i→j: Cᵢ = pᵢ, Cⱼ = pᵢ + pⱼ → ΣC = 2pᵢ + pⱼ
|
||||
Kolejność j→i: Cⱼ = pⱼ, Cᵢ = pⱼ + pᵢ → ΣC = 2pⱼ + pᵢ
|
||||
|
||||
Różnica: (2pᵢ + pⱼ) - (2pⱼ + pᵢ) = pᵢ - pⱼ
|
||||
|
||||
Jeśli pᵢ < pⱼ → kolejność i→j lepsza (mniejsza ΣC)
|
||||
Stąd: krótsze zadania najpierw!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Inne klasyczne reguły
|
||||
|
||||
| Reguła | Problem | Opis |
|
||||
|--------|---------|------|
|
||||
| **SPT** | 1 \|\| ΣCⱼ | Shortest Processing Time |
|
||||
| **WSPT** | 1 \|\| ΣwⱼCⱼ | Weighted SPT (wⱼ/pⱼ malejąco) |
|
||||
| **EDD** | 1 \|\| Lmax | Earliest Due Date |
|
||||
| **LPT** | Pm \|\| Cmax | Longest Processing Time (heur.) |
|
||||
| **Moore** | 1 \|\| ΣUⱼ | Minimalizacja spóźnionych |
|
||||
| **Johnson** | F2 \|\| Cmax | 2-machine flow shop |
|
||||
|
||||
---
|
||||
|
||||
### 8. Algorytm Johnsona (F2 || Cmax)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ALGORYTM JOHNSONA - Flow shop 2 maszyny │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Dane: n zadań, czasy (a₁,b₁), (a₂,b₂), ..., (aₙ,bₙ) │
|
||||
│ aⱼ = czas na maszynie 1, bⱼ = czas na maszynie 2 │
|
||||
│ │
|
||||
│ Algorytm: │
|
||||
│ 1. Podziel zadania na dwa zbiory: │
|
||||
│ U = {j : aⱼ < bⱼ} (krótszy czas na M1) │
|
||||
│ V = {j : aⱼ ≥ bⱼ} (krótszy czas na M2) │
|
||||
│ │
|
||||
│ 2. Sortuj U rosnąco wg aⱼ │
|
||||
│ Sortuj V malejąco wg bⱼ │
|
||||
│ │
|
||||
│ 3. Harmonogram: [U posortowane] ++ [V posortowane] │
|
||||
│ │
|
||||
│ Złożoność: O(n log n) │
|
||||
│ Optymalność: gwarantowana! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "α|β|γ = Maszyny|Zadania|Cel":
|
||||
Trzy pola notacji Graham'a
|
||||
|
||||
### "SPT = Short First":
|
||||
Najkrótsze zadania najpierw dla ΣCⱼ
|
||||
|
||||
### "EDD = Early Due Date":
|
||||
Najwcześniejszy termin najpierw dla Lmax
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Kiedy stosować heurystyki a kiedy optymalne?"
|
||||
**Odpowiedź:** Optymalne (SPT, EDD, Johnson) gdy problem wielomianowy. Heurystyki (LPT, dispatching rules) dla NP-trudnych lub gdy wymagana szybkość. Metaheurystyki (GA, SA) dla trudnych instancji.
|
||||
|
||||
### Q2: "Co to jest preemption?"
|
||||
**Odpowiedź:** Możliwość przerwania zadania i kontynuacji później. pmtn w notacji. Upraszcza niektóre problemy (1|pmtn,rⱼ|Lmax jest P, bez pmtn jest NP-hard).
|
||||
|
||||
### Q3: "Job shop vs Flow shop?"
|
||||
**Odpowiedź:** Flow shop: wszystkie zadania ta sama trasa (M1→M2→...→Mm). Job shop: każde zadanie własna trasa. Job shop jest ogólniejszy i trudniejszy (silnie NP-hard nawet dla 3 maszyn).
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Notacja α|β|γ:** Maszyny | Zadania | Kryterium
|
||||
2. **SPT:** Optymalne dla 1||ΣCⱼ, O(n log n)
|
||||
3. **EDD:** Optymalne dla 1||Lmax
|
||||
4. **Johnson:** Optymalne dla F2||Cmax
|
||||
5. **Większość problemów NP-trudna**
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Pinedo - "Scheduling: Theory, Algorithms, and Systems"
|
||||
2. Brucker - "Scheduling Algorithms"
|
||||
3. Graham et al. - "Optimization and Approximation in Deterministic Sequencing"
|
||||
@ -1,334 +0,0 @@
|
||||
# Pytanie 44: Zarządzanie zapasami w łańcuchu dostaw
|
||||
|
||||
## Pytanie
|
||||
**"Jakie problemy wiążą się z zarządzaniem zapasami w łańcuchu dostaw? Omówić przykładowy model zarządzania zapasami w łańcuchu dostaw."**
|
||||
|
||||
Przedmiot: ZBOP (Zarządzanie i Badania Operacyjne w Produkcji)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Odpowiedź główna
|
||||
|
||||
### 1. Łańcuch dostaw - struktura
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ŁAŃCUCH DOSTAW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Dostawcy → Producent → Dystrybutor → Detalista → Klient │
|
||||
│ │ │ │ │ │
|
||||
│ └──────────┴────────────┴────────────┘ │
|
||||
│ Przepływ informacji (zamówienia) │
|
||||
│ ┌──────────┬────────────┬────────────┐ │
|
||||
│ │ │ │ │ │
|
||||
│ Dostawcy ← Producent ← Dystrybutor ← Detalista │
|
||||
│ Przepływ produktów │
|
||||
│ │
|
||||
│ Na każdym etapie: ZAPASY (inventory) │
|
||||
│ • Surowce (raw materials) │
|
||||
│ • Produkcja w toku (WIP) │
|
||||
│ • Wyroby gotowe (finished goods) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Problemy zarządzania zapasami
|
||||
|
||||
#### 2.1 Bullwhip Effect (Efekt byczego bicza)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ BULLWHIP EFFECT │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Popyt klienta: ─────────────────────────── │
|
||||
│ (stabilny) │
|
||||
│ │
|
||||
│ Zamówienia ┌┐ ┌┐ │
|
||||
│ detalisty: ───┘└──┘└───────────────── │
|
||||
│ (małe wahania) │
|
||||
│ │
|
||||
│ Zamówienia ┌──┐ ┌──┐ │
|
||||
│ dystrybutora: ──┘ └────┘ └───────── │
|
||||
│ (większe wahania) │
|
||||
│ │
|
||||
│ Zamówienia ┌────┐ ┌────┐ │
|
||||
│ producenta: ──┘ └────────┘ └─── │
|
||||
│ (jeszcze większe) │
|
||||
│ │
|
||||
│ Zamówienia ┌──────┐ ┌──────┐ │
|
||||
│ dostawcy: ──┘ └──────────────┘ │
|
||||
│ (AMPLIFIKACJA!) │
|
||||
│ │
|
||||
│ Przyczyny: │
|
||||
│ • Prognozowanie popytu (forecasting) │
|
||||
│ • Batching zamówień │
|
||||
│ • Wahania cen (promocje) │
|
||||
│ • Rationing/shortage gaming │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 2.2 Kluczowe problemy
|
||||
|
||||
| Problem | Opis |
|
||||
|---------|------|
|
||||
| **Bullwhip effect** | Amplifikacja wahań w górę łańcucha |
|
||||
| **Stockouts** | Brak towaru, utrata sprzedaży |
|
||||
| **Overstock** | Nadmiar zapasów, koszty magazynowania |
|
||||
| **Obsolescence** | Przestarzałe/przeterminowane produkty |
|
||||
| **Lead time variability** | Zmienność czasu dostawy |
|
||||
| **Demand uncertainty** | Niepewność popytu |
|
||||
| **Koordynacja** | Brak współpracy między ogniwami |
|
||||
| **Visibility** | Brak widoczności zapasów w łańcuchu |
|
||||
|
||||
---
|
||||
|
||||
### 3. Koszty zapasów
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ STRUKTURA KOSZTÓW │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. KOSZTY UTRZYMANIA (Holding costs) - h │
|
||||
│ • Koszt kapitału zamrożonego │
|
||||
│ • Magazynowanie, ubezpieczenie │
|
||||
│ • Zużycie, przestarzałość │
|
||||
│ Typowo: 15-30% wartości rocznie │
|
||||
│ │
|
||||
│ 2. KOSZTY ZAMAWIANIA (Ordering costs) - K │
|
||||
│ • Stałe koszty zamówienia │
|
||||
│ • Transport, obsługa │
|
||||
│ • Przezbrojenia (setup) │
|
||||
│ │
|
||||
│ 3. KOSZTY BRAKU (Shortage costs) - p │
|
||||
│ • Utrata sprzedaży │
|
||||
│ • Kary umowne │
|
||||
│ • Utrata reputacji │
|
||||
│ │
|
||||
│ CEL: Minimalizuj TC = Holding + Ordering + Shortage │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Model EOQ (Economic Order Quantity)
|
||||
|
||||
#### Założenia
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ MODEL EOQ - Klasyczny model Harrisa-Wilsona │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Założenia: │
|
||||
│ • Popyt deterministyczny, stały: D jednostek/rok │
|
||||
│ • Lead time = 0 (natychmiastowa dostawa) │
|
||||
│ • Brak braków (no stockouts) │
|
||||
│ • Stały koszt zamówienia: K │
|
||||
│ • Stały koszt utrzymania: h na jednostkę/rok │
|
||||
│ │
|
||||
│ Poziom zapasu: │
|
||||
│ Q │╲ │
|
||||
│ │ ╲ │
|
||||
│ │ ╲ │
|
||||
│ │ ╲ ╱╲ │
|
||||
│ │ ╲ ╱ ╲ │
|
||||
│ │ ╲ ╲ │
|
||||
│ 0 └──────────────────────────────→ t │
|
||||
│ │←── T ──→│←── T ──→│ │
|
||||
│ │
|
||||
│ Q = wielkość zamówienia │
|
||||
│ T = Q/D = cykl zamawiania │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Formuła EOQ
|
||||
|
||||
```
|
||||
Koszty roczne:
|
||||
|
||||
Ordering cost = K × (D/Q) (D/Q zamówień rocznie)
|
||||
Holding cost = h × (Q/2) (średni zapas = Q/2)
|
||||
|
||||
TC(Q) = K·D/Q + h·Q/2
|
||||
|
||||
Minimalizacja: dTC/dQ = 0
|
||||
|
||||
-K·D/Q² + h/2 = 0
|
||||
|
||||
┌──────────┐
|
||||
Q* = │ 2·K·D │
|
||||
│ ────── │
|
||||
│ h │
|
||||
└──────────┘
|
||||
|
||||
Optymalna wielkość zamówienia!
|
||||
```
|
||||
|
||||
#### Przykład numeryczny
|
||||
|
||||
```
|
||||
Dane:
|
||||
D = 10,000 jednostek/rok
|
||||
K = 100 PLN/zamówienie
|
||||
h = 2 PLN/jednostkę/rok
|
||||
|
||||
EOQ:
|
||||
Q* = √(2 × 100 × 10,000 / 2) = √1,000,000 = 1,000 jednostek
|
||||
|
||||
Cykl zamawiania:
|
||||
T* = Q*/D = 1,000/10,000 = 0.1 roku ≈ 5 tygodni
|
||||
|
||||
Liczba zamówień:
|
||||
D/Q* = 10,000/1,000 = 10 zamówień/rok
|
||||
|
||||
Koszt całkowity:
|
||||
TC* = √(2·K·D·h) = √(2×100×10,000×2) = 2,000 PLN/rok
|
||||
|
||||
(lub: TC = 100×10 + 2×500 = 1,000 + 1,000 = 2,000 PLN)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Model z punktem zamawiania (ROP)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ REORDER POINT (ROP) - uwzględnienie lead time │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Poziom zapasu: │
|
||||
│ │╲ ╱╲ │
|
||||
│ │ ╲ ╱ ╲ │
|
||||
│ │ ╲ ╱ ╲ │
|
||||
│ ROP │──────╲──────────╲────────────╲── │
|
||||
│ │ ╲ ╱ ╲ ╱ ╲ │
|
||||
│ SS│──────────╲──╱──────╲──────╱────── │
|
||||
│ 0 └────────────────────────────────→ t │
|
||||
│ │←L→│ │
|
||||
│ zamówienie dostawa │
|
||||
│ │
|
||||
│ ROP = d × L + SS │
|
||||
│ │
|
||||
│ gdzie: │
|
||||
│ d = średni popyt dzienny │
|
||||
│ L = lead time (czas dostawy) │
|
||||
│ SS = safety stock (zapas bezpieczeństwa) │
|
||||
│ │
|
||||
│ SS = z × σ_L │
|
||||
│ z = współczynnik (z tablic normalnych, np. 1.65 dla 95%) │
|
||||
│ σ_L = odchylenie std popytu w czasie L │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Model (s, S) / (R, Q)
|
||||
|
||||
| Model | Opis |
|
||||
|-------|------|
|
||||
| **(s, Q)** | Zamów Q gdy poziom spadnie do s |
|
||||
| **(s, S)** | Zamów do poziomu S gdy spadnie do s |
|
||||
| **(R, S)** | Co R okresów uzupełnij do S |
|
||||
| **(R, s, S)** | Co R okresów: jeśli ≤ s, uzupełnij do S |
|
||||
|
||||
```
|
||||
Model (s, S):
|
||||
Poziom zapasu:
|
||||
S │╲
|
||||
│ ╲
|
||||
│ ╲
|
||||
s │──────╲──────────────╲──
|
||||
│ ╲ ╱ ╲
|
||||
│ ╲ ╱ ╲
|
||||
0 └────────────────────────→ t
|
||||
zamów dostawa
|
||||
S-poziom
|
||||
|
||||
Polityka: Gdy poziom ≤ s, zamów aby osiągnąć S
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Vendor Managed Inventory (VMI)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ VMI - Dostawca zarządza zapasami klienta │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Tradycyjnie: │
|
||||
│ Klient → zamówienie → Dostawca → dostawa │
|
||||
│ │
|
||||
│ VMI: │
|
||||
│ Klient → dane o zapasach/sprzedaży → Dostawca │
|
||||
│ Dostawca → decyzja o uzupełnieniu → Klient │
|
||||
│ │
|
||||
│ Korzyści: │
|
||||
│ • Redukcja bullwhip effect │
|
||||
│ • Lepsza widoczność popytu │
|
||||
│ • Optymalizacja transportu │
|
||||
│ • Redukcja stockouts │
|
||||
│ │
|
||||
│ Przykłady: Walmart-P&G, 7-Eleven-dostawcy │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. Wskaźniki efektywności
|
||||
|
||||
| Wskaźnik | Formuła | Cel |
|
||||
|----------|---------|-----|
|
||||
| **Inventory Turnover** | COGS / Avg Inventory | Wyższy = lepszy |
|
||||
| **Days of Inventory** | 365 / Turnover | Niższy = lepszy |
|
||||
| **Fill Rate** | Zamówienia zrealizowane / Wszystkie | Wyższy |
|
||||
| **Service Level** | P(brak stockout) | 95-99% |
|
||||
| **GMROI** | Gross Margin / Avg Inventory | Wyższy |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki
|
||||
|
||||
### "EOQ = √(2KD/h)":
|
||||
Economic Order Quantity - kwadrat z 2KD/h
|
||||
|
||||
### "ROP = d×L + SS":
|
||||
Reorder Point = popyt w lead time + safety stock
|
||||
|
||||
### "Bullwhip = Bigger upstream":
|
||||
Wahania rosną w górę łańcucha
|
||||
|
||||
---
|
||||
|
||||
## ❓ Pytania dodatkowe
|
||||
|
||||
### Q1: "Jak zredukować bullwhip effect?"
|
||||
**Odpowiedź:** Współdzielenie informacji (POS data), VMI, CPFR (Collaborative Planning), redukcja lead times, stabilne ceny (EDLP), mniejsze partie (smaller batches), centralizacja decyzji.
|
||||
|
||||
### Q2: "EOQ vs JIT?"
|
||||
**Odpowiedź:** EOQ: optymalizuje koszty przy danych K, h. JIT (Just-In-Time): redukuje K (częste małe dostawy), redukuje zapasy (Q→0). JIT wymaga: niskich setup costs, niezawodnych dostawców, stabilnego popytu.
|
||||
|
||||
### Q3: "Jak ustalić poziom zapasu bezpieczeństwa?"
|
||||
**Odpowiedź:** SS = z × σ_L, gdzie z zależy od wymaganego service level (z=1.65 dla 95%, z=2.33 dla 99%). σ_L = σ_d × √L dla niezależnego popytu. Trade-off: wyższy SS = mniej stockouts, ale wyższe koszty.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Kluczowe punkty
|
||||
|
||||
1. **Bullwhip effect:** Amplifikacja wahań w łańcuchu
|
||||
2. **Koszty:** Holding (h), Ordering (K), Shortage (p)
|
||||
3. **EOQ:** Q* = √(2KD/h)
|
||||
4. **ROP:** d×L + SS (uwzględnia lead time)
|
||||
5. **VMI:** Dostawca zarządza zapasami klienta
|
||||
|
||||
---
|
||||
|
||||
## 📖 Źródła
|
||||
|
||||
1. Silver, Pyke, Peterson - "Inventory Management and Production Planning"
|
||||
2. Chopra, Meindl - "Supply Chain Management"
|
||||
3. Simchi-Levi - "Designing and Managing the Supply Chain"
|
||||
@ -1,568 +0,0 @@
|
||||
# Pytania egzaminacyjne o pracę magisterską
|
||||
|
||||
## Temat pracy
|
||||
**"Porównanie wydajności i możliwości współczesnych silników gier komputerowych"**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 1: Cel i motywacja pracy
|
||||
|
||||
### Pytanie
|
||||
**"Jaki jest cel Pana pracy magisterskiej i dlaczego wybrano akurat temat porównania silników gier?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
Celem pracy jest **kompleksowe porównanie wydajności i możliwości współczesnych silników gier** (Unity i Unreal Engine), ze szczególnym uwzględnieniem ich wpływu na proces tworzenia gier oraz końcową jakość produktu.
|
||||
|
||||
**Motywacja:**
|
||||
1. **Praktyczna potrzeba** - wybór silnika to kluczowa decyzja wpływająca na cały cykl życia projektu
|
||||
2. **Brak obiektywnych porównań** - większość istniejących materiałów ma charakter subiektywny lub marketingowy
|
||||
3. **Dominacja rynkowa** - Unity i Unreal wspólnie obsługują >70% globalnego rynku gier
|
||||
4. **Reprezentatywność architektur** - silniki reprezentują fundamentalnie różne podejścia (C# z GC vs C++ z ręcznym zarządzaniem pamięcią)
|
||||
|
||||
**Praktyczne znaczenie:**
|
||||
- Pomoc deweloperom w świadomym wyborze narzędzi
|
||||
- Dostarczenie obiektywnych danych wydajnościowych
|
||||
- Analiza praktycznych aspektów pracy z silnikami
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 2: Metodologia badawcza
|
||||
|
||||
### Pytanie
|
||||
**"Jaką metodologię badawczą zastosowano w pracy? Dlaczego wybrano takie podejście?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
Zastosowano **metodologię mieszaną** łączącą podejście ilościowe i jakościowe:
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ METODOLOGIA BADAWCZA │
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ILOŚCIOWA (Quantitative): │
|
||||
│ ├── Testy wydajnościowe z NVIDIA Nsight Graphics │
|
||||
│ ├── Pomiary FPS, CPU, GPU, pamięci RAM/VRAM │
|
||||
│ └── Obiektywne metryki porównawcze │
|
||||
│ │
|
||||
│ JAKOŚCIOWA (Qualitative): │
|
||||
│ ├── 8 wywiadów pogłębionych z deweloperami │
|
||||
│ ├── Analiza dokumentacji i materiałów edukacyjnych │
|
||||
│ └── Doświadczenia z implementacji porównawczej │
|
||||
│ │
|
||||
│ TRIANGULACJA ŹRÓDEŁ: │
|
||||
│ └── Weryfikacja wniosków z wielu perspektyw │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Uzasadnienie podejścia mieszanego:**
|
||||
1. **Obiektywność** - testy wydajnościowe eliminują subiektywizm
|
||||
2. **Kontekst praktyczny** - wywiady dostarczają perspektywy użytkowników
|
||||
3. **Kompletność** - sama wydajność nie determinuje jakości narzędzia
|
||||
4. **Wiarygodność** - triangulacja zwiększa pewność wniosków
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 3: Wybór gry testowej
|
||||
|
||||
### Pytanie
|
||||
**"Dlaczego do testów wybrano gatunek bullet hell? Jakie to ma znaczenie dla wyników?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Gatunek bullet hell (danmaku)** to strzelanka, w której gracz mierzy się z setkami/tysiącami pocisków tworzących skomplikowane wzory.
|
||||
|
||||
**Uzasadnienie wyboru:**
|
||||
|
||||
| Aspekt | Dlaczego bullet hell? |
|
||||
|--------|----------------------|
|
||||
| **Intensywność** | Setki obiektów na ekranie → obciążenie renderingu |
|
||||
| **Pamięć** | Ciągłe tworzenie/niszczenie pocisków → test GC vs ręczne |
|
||||
| **Fizyka** | Kolizje gracz↔pociski → obciążenie systemu fizyki |
|
||||
| **Skalowalność** | Łatwa kontrola obciążenia przez liczbę pocisków |
|
||||
| **Prostota** | Prosta logika → fokus na wydajność, nie złożoność |
|
||||
| **Reprezentatywność** | Typowa gra 2D indie → duży segment rynku |
|
||||
|
||||
**Parametry gry testowej:**
|
||||
- Czas rozgrywki: 90 sekund
|
||||
- Maksymalnie ~500 jednoczesnych pocisków
|
||||
- 3 typy przeciwników z różnymi wzorami
|
||||
- Object pooling dla eliminacji alokacji runtime
|
||||
|
||||
**Znaczenie dla wyników:**
|
||||
Gatunek wymusza stosowanie technik optymalizacyjnych (object pooling, spatial partitioning), których efektywność może różnić się między silnikami, co pozwala na rzeczywiste porównanie.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 4: Różnice architektoniczne silników
|
||||
|
||||
### Pytanie
|
||||
**"Jakie są fundamentalne różnice architektoniczne między Unity a Unreal Engine?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PORÓWNANIE ARCHITEKTONICZNE UNITY vs UNREAL │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ UNITY: UNREAL ENGINE: │
|
||||
│ ├─ Język: C# ├─ Język: C++ / Blueprints │
|
||||
│ ├─ Pamięć: Garbage Collector ├─ Pamięć: Ręczne/Smart ptr │
|
||||
│ ├─ Architektura: GameObject ├─ Architektura: Actor │
|
||||
│ │ └─ Component │ └─ Component │
|
||||
│ ├─ Natywne 2D: TAK ├─ Natywne 2D: NIE │
|
||||
│ ├─ Kod źródłowy: częściowo ├─ Kod źródłowy: pełny │
|
||||
│ └─ Rozmiar projektu: ~100 MB └─ Rozmiar projektu: ~1-2 GB │
|
||||
│ │
|
||||
│ FILOZOFIA: │
|
||||
│ Unity: Prostota, dostępność Unreal: Moc, kontrola │
|
||||
│ Mobile, indie AAA, fotorealizm │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Kluczowe implikacje:**
|
||||
|
||||
1. **C# z GC vs C++:**
|
||||
- Unity: szybszy rozwój, możliwe GC spikes
|
||||
- Unreal: maksymalna wydajność, większa złożoność
|
||||
|
||||
2. **Krzywa uczenia:**
|
||||
- Unity: łagodna, przyjazna początkującym
|
||||
- Unreal: stroma, wymaga znajomości C++
|
||||
|
||||
3. **Specjalizacja:**
|
||||
- Unity: elastyczne, dobre dla różnych typów gier
|
||||
- Unreal: zoptymalizowane pod FPS/AAA
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 5: Hipotezy badawcze
|
||||
|
||||
### Pytanie
|
||||
**"Jakie hipotezy badawcze postawiono w pracy? Czy zostały potwierdzone?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Hipotezy badawcze:**
|
||||
|
||||
1. **H1:** "Silniki komercyjne oferują lepszą wydajność niż rozwiązania open source"
|
||||
- *Status:* Nie dotyczy bezpośrednio (oba badane silniki są komercyjne z darmowymi wersjami)
|
||||
|
||||
2. **H2:** "Kompleksowość funkcjonalności wpływa negatywnie na wydajność"
|
||||
- *Status:* Częściowo potwierdzona - Unreal z większą liczbą wbudowanych mechanizmów wymaga większych zasobów (rozmiar projektu, RAM), ale kompensuje to optymalizacjami niskopoziomowymi
|
||||
|
||||
3. **H3:** "Łatwość użycia jest odwrotnie proporcjonalna do możliwości konfiguracji"
|
||||
- *Status:* Potwierdzona - Unity z łagodniejszą krzywą uczenia oferuje mniejszą kontrolę nad niskopoziomowymi aspektami; Unreal wymaga większego wysiłku, ale daje pełny dostęp do kodu źródłowego
|
||||
|
||||
**Wnioski z hipotez:**
|
||||
- Trade-off między dostępnością a kontrolą jest realny
|
||||
- Nie ma "lepszego" silnika - wybór zależy od kontekstu projektu
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 6: Wyniki wywiadów z deweloperami
|
||||
|
||||
### Pytanie
|
||||
**"Jakie główne wnioski płyną z wywiadów z deweloperami gier?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
Przeprowadzono **8 wywiadów pogłębionych** z deweloperami o zróżnicowanym doświadczeniu (1-10+ lat).
|
||||
|
||||
**Kluczowe wnioski:**
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ WNIOSKI Z WYWIADÓW │
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. DOKUMENTACJA: │
|
||||
│ Unity: "dogłębna, szczegółowa, z przykładami" │
|
||||
│ Unreal: "szkieletowa, praktycznie nieistniejąca" │
|
||||
│ │
|
||||
│ 2. MATERIAŁY EDUKACYJNE: │
|
||||
│ Unity: więcej, lepszej jakości (Brackeys) │
|
||||
│ Unreal: mniej, często nieaktualne, skupione na Blueprints │
|
||||
│ │
|
||||
│ 3. PRÓG WEJŚCIA: │
|
||||
│ Unity: łagodniejszy, C# jako język wysokopoziomowy │
|
||||
│ Unreal: wyższy, C++ rozszerzony o makra silnika │
|
||||
│ │
|
||||
│ 4. SPECJALIZACJA: │
|
||||
│ Unity: uniwersalne narzędzie │
|
||||
│ Unreal: zoptymalizowane pod FPS/gry akcji │
|
||||
│ │
|
||||
│ 5. KOMPILACJA: │
|
||||
│ Unity: problemy z czasem przy dużych projektach │
|
||||
│ Rozwiązanie: Assembly Definitions │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Wspólne problemy:**
|
||||
- Poradniki skupiają się na pojedynczych mechanikach, nie na architekturze
|
||||
- Brak holistycznego podejścia do nauczania
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 7: Narzędzia profilowania
|
||||
|
||||
### Pytanie
|
||||
**"Jakie narzędzia wykorzystano do testów wydajnościowych? Dlaczego akurat te?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Główne narzędzie: NVIDIA Nsight Graphics**
|
||||
|
||||
**Uzasadnienie wyboru:**
|
||||
1. **Niezależność** - zewnętrzne narzędzie, nie faworyzuje żadnego silnika
|
||||
2. **Precyzja** - niskopoziomowe metryki GPU
|
||||
3. **Porównywalność** - te same metryki dla obu silników
|
||||
4. **Kompleksowość** - analiza całego pipeline'u renderowania
|
||||
|
||||
**Mierzone metryki:**
|
||||
|
||||
| Kategoria | Metryki |
|
||||
|-----------|---------|
|
||||
| **Rendering** | FPS, frame time, draw calls |
|
||||
| **GPU** | Obciążenie, pamięć VRAM, shader performance |
|
||||
| **CPU** | Obciążenie, czas na frame |
|
||||
| **Pamięć** | RAM allocation, GC events (Unity) |
|
||||
|
||||
**Dodatkowe narzędzia:**
|
||||
- Wbudowane profilery Unity i Unreal (dla kontekstu wewnętrznego)
|
||||
- Monitoring systemu operacyjnego
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 8: Ograniczenia badań
|
||||
|
||||
### Pytanie
|
||||
**"Jakie są ograniczenia przeprowadzonych badań? Co można by ulepszyć?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Ograniczenia:**
|
||||
|
||||
1. **Zakres testów:**
|
||||
- Tylko jeden gatunek gry (bullet hell 2D)
|
||||
- Brak testów 3D, VR, mobile
|
||||
|
||||
2. **Środowisko:**
|
||||
- Jedna konfiguracja sprzętowa
|
||||
- Brak testów na różnych platformach
|
||||
|
||||
3. **Wersje silników:**
|
||||
- Wyniki specyficzne dla konkretnych wersji
|
||||
- Silniki szybko się rozwijają
|
||||
|
||||
4. **Próba wywiadów:**
|
||||
- 8 respondentów (ograniczona reprezentatywność)
|
||||
- Głównie rynek polski
|
||||
|
||||
5. **Subiektywność implementacji:**
|
||||
- Implementacja w obu silnikach przez jedną osobę
|
||||
- Możliwa nieświadoma preferencja
|
||||
|
||||
**Propozycje ulepszeń:**
|
||||
- Testy na większej liczbie gatunków gier
|
||||
- Badanie na różnych platformach (mobile, konsole)
|
||||
- Większa próba do badań jakościowych
|
||||
- Współpraca z ekspertami od każdego silnika
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 9: Praktyczne rekomendacje
|
||||
|
||||
### Pytanie
|
||||
**"Jakie praktyczne rekomendacje dla deweloperów wynikają z pracy?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ REKOMENDACJE WYBORU SILNIKA │
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ WYBIERZ UNITY gdy: │
|
||||
│ ✓ Tworzysz grę 2D lub mobilną │
|
||||
│ ✓ Jesteś początkującym deweloperem │
|
||||
│ ✓ Masz ograniczony budżet/zespół (indie) │
|
||||
│ ✓ Znasz C# lub języki podobne │
|
||||
│ ✓ Priorytetem jest szybkość prototypowania │
|
||||
│ │
|
||||
│ WYBIERZ UNREAL gdy: │
|
||||
│ ✓ Tworzysz grę AAA lub fotorealistyczną │
|
||||
│ ✓ Potrzebujesz maksymalnej wydajności │
|
||||
│ ✓ Robisz grę FPS/akcji z widokiem pierwszej osoby │
|
||||
│ ✓ Masz doświadczenie w C++ │
|
||||
│ ✓ Potrzebujesz zaawansowanych narzędzi cinematycznych │
|
||||
│ │
|
||||
│ UWAGI OGÓLNE: │
|
||||
│ • Oba silniki są profesjonalne i dojrzałe │
|
||||
│ • Wybór zależy od kontekstu projektu, nie "lepszości" │
|
||||
│ • Warto znać oba dla elastyczności kariery │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 10: Wkład naukowy pracy
|
||||
|
||||
### Pytanie
|
||||
**"Jaki jest wkład naukowy Pana pracy? Co wnosi do dziedziny?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Wkład naukowy:**
|
||||
|
||||
1. **Metodologia porównawcza:**
|
||||
- Zaproponowano systematyczne podejście do porównywania silników gier
|
||||
- Połączenie metod ilościowych (benchmarki) i jakościowych (wywiady)
|
||||
|
||||
2. **Obiektywne dane:**
|
||||
- Dostarczono konkretnych wyników wydajnościowych zamiast subiektywnych opinii
|
||||
- Dane z kontrolowanych warunków testowych
|
||||
|
||||
3. **Perspektywa praktyka:**
|
||||
- Wywiady z deweloperami dostarczają realnego kontekstu użytkowania
|
||||
- Uzupełnienie luki między marketingiem a rzeczywistością
|
||||
|
||||
4. **Dokumentacja różnic:**
|
||||
- Szczegółowe opisanie różnic architektonicznych
|
||||
- Praktyczne implikacje dla procesu deweloperskiego
|
||||
|
||||
**Znaczenie dla branży:**
|
||||
- Pomoc w świadomych decyzjach technologicznych
|
||||
- Redukcja ryzyka błędnego wyboru narzędzi
|
||||
- Materiał edukacyjny dla początkujących deweloperów
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 11: Object pooling
|
||||
|
||||
### Pytanie
|
||||
**"Czym jest object pooling i dlaczego był kluczowy w pracy?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Object pooling** to technika optymalizacyjna polegająca na **ponownym wykorzystywaniu obiektów** zamiast ciągłego tworzenia i niszczenia.
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ OBJECT POOLING │
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ BEZ POOLINGU: Z POOLINGIEM: │
|
||||
│ ┌─────┐ ┌─────┐ │
|
||||
│ │spawn│→ new Bullet() │spawn│→ pool.Get() │
|
||||
│ └─────┘ └─────┘ │
|
||||
│ ↓ ↓ │
|
||||
│ [gameplay] [gameplay] │
|
||||
│ ↓ ↓ │
|
||||
│ ┌─────┐ ┌─────┐ │
|
||||
│ │die │→ destroy + GC │die │→ pool.Return() │
|
||||
│ └─────┘ └─────┘ │
|
||||
│ │
|
||||
│ Problemy: Korzyści: │
|
||||
│ • Alokacje każdą klatkę • Zero alokacji runtime │
|
||||
│ • GC spikes (Unity) • Brak GC spikes │
|
||||
│ • Fragmentacja pamięci • Stały koszt pamięci │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Znaczenie dla pracy:**
|
||||
- Bullet hell generuje setki pocisków/sekundę
|
||||
- Bez poolingu → ciągłe alokacje → GC spikes w Unity
|
||||
- Pooling pozwala na **uczciwe porównanie** silników (eliminuje narzut GC)
|
||||
- Technika stosowana w obu implementacjach
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 12: Różnice w zarządzaniu pamięcią
|
||||
|
||||
### Pytanie
|
||||
**"Jak różni się zarządzanie pamięcią w Unity i Unreal Engine? Jakie to ma konsekwencje?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ ZARZĄDZANIE PAMIĘCIĄ: UNITY vs UNREAL │
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ UNITY (C# / .NET): │
|
||||
│ ├─ Garbage Collector (GC) - automatyczne zwalnianie │
|
||||
│ ├─ Zalety: │
|
||||
│ │ • Brak memory leaks z definicji │
|
||||
│ │ • Prostsze programowanie │
|
||||
│ │ • Bezpieczeństwo typów │
|
||||
│ ├─ Wady: │
|
||||
│ │ • GC spikes (nieprzewidywalne pauzy) │
|
||||
│ │ • Mniejsza kontrola nad alokacją │
|
||||
│ │ • Boxing/unboxing overhead │
|
||||
│ └─ Mitygacja: object pooling, struct zamiast class │
|
||||
│ │
|
||||
│ UNREAL (C++): │
|
||||
│ ├─ Ręczne zarządzanie + smart pointers │
|
||||
│ ├─ Zalety: │
|
||||
│ │ • Pełna kontrola nad pamięcią │
|
||||
│ │ • Przewidywalna wydajność │
|
||||
│ │ • Brak GC spikes │
|
||||
│ ├─ Wady: │
|
||||
│ │ • Ryzyko memory leaks │
|
||||
│ │ • Dangling pointers │
|
||||
│ │ • Większa złożoność kodu │
|
||||
│ └─ Mechanizmy UE: TSharedPtr, TWeakPtr, garbage collection │
|
||||
│ dla UObject │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Konsekwencje praktyczne:**
|
||||
- Unity: łatwiejsze dla początkujących, ale wymaga uwagi przy wydajności
|
||||
- Unreal: wymaga doświadczenia, ale daje przewidywalność
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 13: Kryteria porównania
|
||||
|
||||
### Pytanie
|
||||
**"Według jakich kryteriów porównywano silniki?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Trzy główne kategorie kryteriów:**
|
||||
|
||||
### 1. Wydajność
|
||||
- Szybkość renderowania (FPS)
|
||||
- Zużycie pamięci RAM
|
||||
- Obciążenie procesora
|
||||
- Zużycie pamięci karty graficznej
|
||||
- Czas ładowania scen
|
||||
|
||||
### 2. Funkcjonalność
|
||||
- Wsparcie dla różnych typów renderingu
|
||||
- Systemy fizyki
|
||||
- Systemy audio
|
||||
- Wsparcie dla VR/AR
|
||||
- Możliwości skryptowania
|
||||
|
||||
### 3. Użyteczność
|
||||
- Intuicyjność interfejsu
|
||||
- Jakość dokumentacji
|
||||
- Dostępność tutoriali
|
||||
- Wsparcie społeczności
|
||||
- Czas potrzebny na naukę (krzywa uczenia)
|
||||
|
||||
**Dlaczego te kryteria:**
|
||||
- Pokrywają wszystkie aspekty istotne dla deweloperów
|
||||
- Możliwe do zmierzenia (ilościowe) lub oceny (jakościowe)
|
||||
- Odpowiadają realnym potrzebom przy wyborze silnika
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 14: Przyszłość badań
|
||||
|
||||
### Pytanie
|
||||
**"Jakie kierunki dalszych badań Pan proponuje?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
**Propozycje dalszych badań:**
|
||||
|
||||
1. **Rozszerzenie zakresu testów:**
|
||||
- Testy na grach 3D (różne gatunki)
|
||||
- Porównanie wydajności VR/AR
|
||||
- Testy na platformach mobilnych i konsolach
|
||||
|
||||
2. **Uwzględnienie innych silników:**
|
||||
- Godot (open source, rosnąca popularność)
|
||||
- CryEngine, Amazon Lumberyard
|
||||
- Własne silniki studiów AAA
|
||||
|
||||
3. **Badania longitudinalne:**
|
||||
- Śledzenie rozwoju silników w czasie
|
||||
- Porównanie wersji (Unity 2020 vs 2025)
|
||||
|
||||
4. **Pogłębienie badań jakościowych:**
|
||||
- Większa próba deweloperów
|
||||
- Badania w różnych krajach/regionach
|
||||
- Studium przypadków konkretnych produkcji
|
||||
|
||||
5. **Aspekty ekonomiczne:**
|
||||
- Koszty licencji i royalties
|
||||
- ROI przy wyborze silnika
|
||||
- Czas rozwoju projektu
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pytanie 15: Blueprints vs C++ w Unreal
|
||||
|
||||
### Pytanie
|
||||
**"Jakie są różnice między programowaniem w Blueprints a C++ w Unreal Engine?"**
|
||||
|
||||
### Odpowiedź wzorcowa
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ BLUEPRINTS vs C++ w UNREAL ENGINE │
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ BLUEPRINTS: C++: │
|
||||
│ ├─ Wizualne programowanie ├─ Tradycyjny kod │
|
||||
│ ├─ Drag & drop węzłów ├─ Tekstowe pisanie │
|
||||
│ ├─ Szybkie prototypowanie ├─ Maksymalna wydajność │
|
||||
│ ├─ Dla designerów/artystów ├─ Dla programistów │
|
||||
│ ├─ Wolniejsze wykonanie ├─ Kompilacja do natywnego │
|
||||
│ └─ Trudniejsze przy złożoności └─ Pełna kontrola │
|
||||
│ │
|
||||
│ TYPOWE ZASTOSOWANIE: │
|
||||
│ Blueprints: UI, proste mechaniki, prototypy │
|
||||
│ C++: core gameplay, AI, systemy krytyczne wydajnościowo │
|
||||
│ │
|
||||
│ BEST PRACTICE: Hybrydowe podejście │
|
||||
│ └─ Implementacja w C++, ekspozycja do Blueprints │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Wnioski z wywiadów:**
|
||||
- Poradniki często skupiają się na Blueprints
|
||||
- Profesjonalne produkcje głównie C++
|
||||
- Blueprints dobre do nauki konceptów silnika
|
||||
|
||||
---
|
||||
|
||||
## 📋 Lista wszystkich pytań (podsumowanie)
|
||||
|
||||
1. Cel i motywacja pracy
|
||||
2. Metodologia badawcza
|
||||
3. Wybór gry testowej (bullet hell)
|
||||
4. Różnice architektoniczne silników
|
||||
5. Hipotezy badawcze
|
||||
6. Wyniki wywiadów z deweloperami
|
||||
7. Narzędzia profilowania
|
||||
8. Ograniczenia badań
|
||||
9. Praktyczne rekomendacje
|
||||
10. Wkład naukowy pracy
|
||||
11. Object pooling
|
||||
12. Różnice w zarządzaniu pamięcią
|
||||
13. Kryteria porównania
|
||||
14. Przyszłość badań
|
||||
15. Blueprints vs C++ w Unreal
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mnemoniki dla obrony
|
||||
|
||||
### "MWUK" - Metodologia:
|
||||
**M**ieszana, **W**ywiady, **U**nity vs Unreal, **K**ryterium porównania
|
||||
|
||||
### "BH = Benchmark Heaven":
|
||||
**B**ullet **H**ell = idealny test (dużo obiektów, kolizji, alokacji)
|
||||
|
||||
### "Unity = Easy, Unreal = Elite":
|
||||
Unity: łatwiejsze, Unreal: dla zaawansowanych
|
||||
|
||||
### "C# GC, C++ MC":
|
||||
C# = Garbage Collection, C++ = Manual Control
|
||||
77
pytania/questions/odpowiedzi_opracowane/pytanie_16.md
Normal file
@ -0,0 +1,77 @@
|
||||
**16\. Omówić specjalizowane języki programowania robotów. Uwypuklić ich klasyfikację. ERPM**
|
||||
*Źródło \- slajdy z ERPM:*
|
||||
Properties of AL, RAPT and TORBOL languages \- features:
|
||||
|
||||
* AL: objects represented by coordinate frames – shape is missing (difficult simulation)
|
||||
* AL: separate commands change the state of environment and its model
|
||||
* RAPT: objects modeled by elementary shapes, poses implied by desired situations – a lot left to presumption
|
||||
* TORBOL: objects modeled by attributes (coordinate frames, shapes etc.)
|
||||
* TORBOL: single operation acts on the environment and its model
|
||||
* AL – an object oriented robot programming language
|
||||
|
||||
Language description
|
||||
Data types (d.t.): basic data type: SCALAR with units
|
||||
Complex d.t.: VECTOR, ROTATION, FRAME, TRANSFORM
|
||||
Program flow: IF THEN ELSE, FOR, WHILE, UNTIL, CASE
|
||||
Process synchronization: EVENT, SIGNAL, WAIT
|
||||
Motion instruction:
|
||||
MOVE movable\_frame TO destination\_frame modifier
|
||||
modifier: WITH DEPARTURE, WITH APPROACH, VIA,
|
||||
WITH DURATION, WITH SPEEDFACTOR, WITH WOBBLE,
|
||||
WITH FORCE, WITH TORQUE
|
||||
Gripper commands: OPEN, CLOSE, CENTER
|
||||
World modeling: AFFIX frame TO frame BY expression modifier
|
||||
UNFIX frame FROM frame
|
||||
modifier: RIGID, NONRIGID
|
||||
|
||||
* RAPT – an object oriented robot programming language
|
||||
|
||||
Language description
|
||||
body definition statements which use:
|
||||
construction features (e.g. POINT, LINE, CIRCLE) to define:
|
||||
external features of bodies (e.g. FACE, SHAFT, HOLE, EDGE,
|
||||
VERTEX, SPHFACE, i.e. spherical face),
|
||||
relational statements describing the relationships between
|
||||
external features of the body (e.g. AGAINST, COPLANAR, FITS,
|
||||
ALIGNED, TIED, UNTIED, ISSUB, i.e. is a subassembly,
|
||||
NOTSUB),
|
||||
motion statements (e.g. MOVE, TURN) causing the motion of
|
||||
AGENTs (e.g. robot),
|
||||
situation description statements which use the same keywords
|
||||
and syntax as the relational statements.
|
||||
Example:
|
||||
REMARK shift the bottle to a new location on the table
|
||||
REMARK lift the bottle off the table
|
||||
MOVE/bottle,PERPTO,table;
|
||||
REMARK describe the situation: the bottle is above the table
|
||||
AGAINST/VERTEX of bottle, virtual\_plane;
|
||||
REMARK transfer the bottle to the new location
|
||||
MOVE/bottle,PARLEL,table
|
||||
MOVE/bottle,PERPTO,table
|
||||
REMARK describe the goal situation
|
||||
AGAINST/VERTEX of bottle, new\_vertex
|
||||
|
||||
* TORBOL ((Transformation of Relations Between Objects Language) – an object oriented robot prog. language
|
||||
|
||||
Language description
|
||||
Data types:
|
||||
INTEGER, REAL, LOGICAL, FRAME, OBJECT, RELATION
|
||||
Attributes of objects: BASE, TOP, BOTTOM, INSIDE, HANDLE,
|
||||
PATH, GRASPED, SHAPE (CUBOID, PRISM, PYRAMID)
|
||||
Relations: binary (between objects),
|
||||
unary (properties of objects) – defined in terms of attribute values
|
||||
Interaction with the environment:
|
||||
IN\_SIGNAL – EVENT (e.g., TIME) ) WAIT, CREATE, DELETE
|
||||
Program flow:
|
||||
IF THEN ELSE ENDIF, WHILE PERFORM ENDWHILE, REPEAT
|
||||
UNTIL ENDREPEAT, FOR ENDFOR
|
||||
Motion instruction: DO (relation object \[object\]) \[modifier\];
|
||||
modifier: CAUTIOUSLY, MODERATELY, QUICKLY
|
||||
|
||||
Klasyfikacja:
|
||||
[https://ocw.snu.ac.kr/sites/default/files/NOTE/Chap12\_Robot%20programming%20languages.pdf](https://ocw.snu.ac.kr/sites/default/files/NOTE/Chap12_Robot%20programming%20languages.pdf)
|
||||
Robot programming languages have likewise taken on many forms. We will split them into three categories:
|
||||
1\. Specialized manipulation languages. These robot programming languages have been built by developing a completely new language that, although addressing robot-specific areas, might well be considered a general computer programming language. \-\> AL, RAPT, TORBOL
|
||||
2\. Robot library for an existing computer language. These robot programming languages have been developed by starting with a popular computer language (e.g., Pascal) and adding a library of robot-specific subroutines. The user then writes a Pascal program making use of frequent calls to the predefined subroutine package for robot-specific needs.
|
||||
3\. Robot library for a new general-purpose language. These robot programming languages have been developed by first creating a new general-purpose language as a programming base and then supplying a library of predefined robot-specific subroutines. Examples of such robot programming languages
|
||||
are RAPID developed by ABB Robotics \[6\], AML developed by IBM \[7\], and KAREL developed by GMF Robotics \[8\].
|
||||
23
pytania/questions/odpowiedzi_opracowane/pytanie_24.md
Normal file
@ -0,0 +1,23 @@
|
||||
**24\. Opisać problem detekcji obiektów w obrazach. Przedstawić podstawowe strategie i algorytmy detekcji przy użyciu metod klasycznych oraz sieci neuronowych. Jak skonstruować detektor obiektów dysponując istniejącym klasyfikatorem tych obiektów? TWM**
|
||||
|
||||
Detekcja jest trudniejsze niż klasyfikacja, ponieważ oprócz określenia klas do których należy obiekt trzeba też określić lokalizację, przez co detekcja jest o wiele bardziej czasochłonna.
|
||||
Wyjściem detektora może być klasa i prostokąt w którym znajduje się obiekt, ale niektóre detektory zwracają też maskę obiektu.
|
||||
|
||||
Metoda okna przesuwnego – wzdłuż obrazu przesuwane jest okno o określonych rozmiarach.
|
||||
Dla każdego okna określa się wektor cech obrazu i używa się klasyfikator cech i określenie wiarygodności klasyfikacji.
|
||||
Wyniki klasyfikacji podlegają dalszemu filtrowaniu.
|
||||
Klasyfikator musi również znać również klasę Tło
|
||||
|
||||
W celu przyspieszenia metody okna przesuwnego można zastosować klasyfikator kaskadowy- na szybko odrzucamy tło i potem analizujemy to co nie odrzuciliśmy.
|
||||
Można też użyć AdaBoost dla którego cały klasyfikator stanowi sumę wyników klasyfikatorów prostszych.
|
||||
|
||||
Dopasowanie za pomocą punktów charakterystycznych – ekstrakcja punktów charakterystycznych i potem dopasowanie punktów charakterystycznych obiektu i obrazu
|
||||
|
||||
R-CNN
|
||||
propozycje regionów (odnalezienie prawdopodobnej lokalizacji i rozmiaru obiektu znanych klas)
|
||||
klasyfikacja regionu i uściślenie pozycji i rozmiaru obiektu
|
||||
|
||||
Region-Based Fully Convolutional Network
|
||||
propozycja regionów
|
||||
wiele map wyjściowych – każda określa odrębne przekonanie, że obiekt jest w pewnej relacji przestrzennej od danej pozycji (np. w lewo-dół)
|
||||
Pooling selektywny – wykorzystywane są tylko wybrane mapy wyjściowe
|
||||
@ -230,8 +230,24 @@ StudentAktywności(StID, Hobby, Umiejętność) — klucz: (StID, Hobby, Umieję
|
||||
|
||||
- **„Klucz, cały klucz i tylko klucz — tak mi dopomóż Codd"** — 1NF (klucz), 2NF (cały klucz), 3NF (tylko klucz)
|
||||
- **3 anomalie:** Wstawianie, Usuwanie, Modyfikacja — „WUM"
|
||||
- **3NF vs BCNF:** 3NF pozwala determinantowi nie-nadkluczowemu JEŚLI zależny jest prime; BCNF nie pozwala w ogóle
|
||||
- **BCNF:** jak 3NF, ale lewa strona FD zawsze nadklucz (bez wyjątku dla atrybutów pierwszych)
|
||||
- **3NF vs BCNF — jedno słowo różnicy: WYJĄTEK:**
|
||||
|
||||
Obie reguły sprawdzają to samo — dla każdej nietrywialnej FD X → A:
|
||||
|
||||
3NF: X jest nadkluczem? → ✅ | A jest prime? → ✅ (WYJĄTEK!) | żadne? → ❌
|
||||
BCNF: X jest nadkluczem? → ✅ | nie jest? → ❌ (BEZ wyjątków, kropka.)
|
||||
|
||||
3NF = „łagodny sędzia" — odpuści, jeśli zależny jest częścią klucza
|
||||
BCNF = „surowy sędzia" — lewa strona MUSI być nadkluczem, bez dyskusji
|
||||
|
||||
Kiedy się RÓŻNIĄ? Tylko przy kluczach ZŁOŻONYCH z nakładającymi się FD:
|
||||
Zapisy(StID, KursID, Prowadzący) — klucz: (StID, KursID)
|
||||
FD: Prowadzący → KursID
|
||||
• Prowadzący to nadklucz? NIE → BCNF mówi ❌
|
||||
• KursID to prime (część klucza)? TAK → 3NF mówi ✅ (wyjątek!)
|
||||
→ Tabela jest 3NF, ale NIE BCNF.
|
||||
|
||||
Przy prostych (jednokolumnowych) kluczach 3NF = BCNF zawsze.
|
||||
- **4NF:** Czy widzisz iloczyn kartezjański? Niezależne zbiory w jednej tabeli? → rozdziel!
|
||||
- **5NF:** Czy tabela „rozpadalna" na 3+ części bezstratnie? Reguła cykliczna? → dekomponuj!
|
||||
- **Hierarchia typów zależności:** FD (jedna wartość) → MVD (zbiór wartości) → JD (złączenie n tabel)
|
||||
|
||||
@ -311,6 +311,51 @@ Bez ortogonalności: M kontenerów × N algorytmów = **M×N** implementacji (so
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — STL vs kontenery silników gier
|
||||
|
||||
> W pracy porównuję Unity (C#/.NET) z Unrealiem (C++), który **NIE używa STL** lecz własnych kontenerów. To doskonały punkt wyjścia do dyskusji o STL.
|
||||
|
||||

|
||||
|
||||
#### Dlaczego Unreal NIE używa STL?
|
||||
|
||||
Epic Games stworzył własną bibliotekę kontenerów z 4 powodów — mnemonik **„TTTF"**:
|
||||
|
||||
| Powód | Problem z STL | Rozwiązanie Unreala |
|
||||
|-------|---------------|---------------------|
|
||||
| **T**ypeInfo (Reflection) | `std::vector` nie ma metadanych | `TArray` + `UPROPERTY()` → edytor, serializacja |
|
||||
| **T**racking (GC) | STL nie wie o UObject GC | Kontenery UE śledzą referencje → brak dangling ptr |
|
||||
| **T**uning (Alokatory) | `std::allocator` nieoptymalne dla gier | `FMemory::Malloc()` + pool allocator per-frame |
|
||||
| **F**idelity (Determinizm) | Implementacja STL różni się między kompilatorami | Identyczne zachowanie na PC/PS5/Xbox/Switch |
|
||||
|
||||
#### Mapowanie STL → Unreal → C#/.NET
|
||||
|
||||
| Kategoria STL | `std::` | Unreal `T`-prefix | C#/.NET (Unity) |
|
||||
|---------------|---------|---------------------|-----------------|
|
||||
| Sekwencyjny | `vector<T>` | `TArray<T>` | `List<T>` |
|
||||
| Sekwencyjny | `deque<T>` | — (TArray + RemoveAt) | `LinkedList<T>` |
|
||||
| Asocjacyjny | `map<K,V>` | `TMap<K,V>` | `Dictionary<K,V>` |
|
||||
| Asocjacyjny | `set<T>` | `TSet<T>` | `HashSet<T>` |
|
||||
| Kolejka | `queue<T>` | `TQueue<T>` | `Queue<T>` |
|
||||
| String | `string` | `FString` / `FName` / `FText` | `string` |
|
||||
| Smart ptr | `shared_ptr<T>` | `TSharedPtr<T>` | GC (automatyczny) |
|
||||
| Iterator | `begin()/end()` | `CreateIterator()` | `IEnumerator` |
|
||||
| Algorytm | `std::sort()` | `Algo::Sort()` | `LINQ .OrderBy()` |
|
||||
|
||||
#### Konkretny przykład — BulletPool
|
||||
|
||||
// Moja praca — C++ Unreal (gdyby BulletPool był w UE)
|
||||
TArray<ABullet*> Pool; // ← TArray, nie std::vector
|
||||
Pool.Reserve(500); // ← jak vector::reserve()
|
||||
for (auto& Bullet : Pool) { ... } // ← range-for działa identycznie
|
||||
|
||||
// Unity C#
|
||||
List<Bullet> _pool = new List<Bullet>(500); // ← List<T>, nie vector
|
||||
|
||||
Na obronie: *„Unreal Engine celowo porzucił STL na rzecz własnych kontenerów (TArray, TMap, TSet), bo potrzebuje refleksji, śledzenia GC i determinizmu cross-platform. To świetny przykład, że STL nie jest jedynym rozwiązaniem — jej alternatywy powtarzają te same kategorie (sekwencyjne, asocjacyjne, adaptery), ale dodają cechy specyficzne dla silnika gier."*
|
||||
|
||||
---
|
||||
|
||||
### Etymologia
|
||||
|
||||
**STL** — Standard Template Library; Alexander Stepanov + Meng Lee (HP, 1994); Stepanov od lat 70. marzył o programowaniu generycznym. **Iterator** — łac. „iter" = podróż/ścieżka; ten, kto przemierza kolekcję. **Funktor** — z teorii kategorii (matematyka); obiekt zachowujący się jak funkcja. **Deque** — Double-Ended QUEue. **Vector** — łac. „vector" = nośnik; tablica dynamiczna. **Lambda** — od greckiej litery λ; Alonzo Church, rachunek lambda (1930s).
|
||||
|
||||
@ -169,6 +169,65 @@ Realizacja: funkcje wirtualne (`virtual` + `override`) — tablica vtable wskazu
|
||||
|
||||
### 6. Biblioteki, frameworki, traity/mixiny
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — reużywalność w silnikach gier
|
||||
|
||||
> W pracy magisterskiej implementuję bullet-hell w Unity (C#) i Unreal (C++). Silniki gier to NAJLEPSZY przykład reużywalności przez kompozycję.
|
||||
|
||||

|
||||
|
||||
#### Component Pattern — „król reużywalności" w gamedev
|
||||
|
||||
Unity i Unreal **odrzuciły** klasyczne dziedziczenie na rzecz **Component Pattern**:
|
||||
|
||||
// Unity — C# Component Pattern
|
||||
public class EnemyController : MonoBehaviour {
|
||||
[RequireComponent(typeof(Health))] // ← KOMPOZYCJA!
|
||||
[RequireComponent(typeof(Collider2D))]
|
||||
|
||||
void Start() {
|
||||
var hp = GetComponent<Health>(); // ← has-a, nie is-a
|
||||
}
|
||||
}
|
||||
|
||||
// Unreal — C++ Component Pattern
|
||||
AEnemy::AEnemy() {
|
||||
HealthComp = CreateDefaultSubobject<UHealthComponent>("Health");
|
||||
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
|
||||
}
|
||||
|
||||
#### Dlaczego NIE dziedziczenie?
|
||||
|
||||
Klasyczna hierarchia (`GameObject → Enemy → FlyingEnemy → ShootingFlyingEnemy`) prowadzi do:
|
||||
- **Diamond problem** — Shooting + Flying = ???
|
||||
- **Fragile base class** — zmiana w Enemy psuje 50 podklas
|
||||
- **Combinatorial explosion** — N cech x M typów = NxM klas
|
||||
|
||||
Kompozycja: Enemy = Transform + Health + AI + Sprite + Collider → **dowolna kombinacja**
|
||||
|
||||
#### Reużywalność w mojej pracy — konkretne przykłady
|
||||
|
||||
| Mechanizm OOP | Mój kod Unity | Unreal odpowiednik |
|
||||
|---------------|---------------|---------------------|
|
||||
| Kompozycja | `[RequireComponent(typeof(Health))]` | `CreateDefaultSubobject<UHealthComp>()` |
|
||||
| Singleton | `GameDirector.Instance` | `UGameInstance` subsystem |
|
||||
| Observer | `C# event OnEnemyDeath` | `FOnEnemyDeath` multicast delegate |
|
||||
| Object Pool | `BulletPool<Bullet>` (generic) | `TPooledObject<ABullet>` (template) |
|
||||
| Interface | `IDamageable` | `UInterface` + `IDamageable` |
|
||||
|
||||
#### Mnemonik — „KSIOP" = Kompozycja Silnika I Obiektowy Pooling
|
||||
|
||||
- **K**ompozycja (Component Pattern — fundamentalna)
|
||||
- **S**ingleton (global managers)
|
||||
- **I**nterfejsy (IDamageable, IInteractable)
|
||||
- **O**bserver (events/delegates)
|
||||
- **P**ooling (Object Pool dla performance)
|
||||
|
||||
Na obronie: *„Moja praca jest doskonałym przykładem 'composition over inheritance' — w Unity każdy obiekt gry składa się z komponentów (MonoBehaviour), a w Unrealu z UActorComponent. Object Pooling to generyczna reużywalność eliminująca GC."*
|
||||
|
||||
---
|
||||
|
||||
### Etymologia
|
||||
|
||||
**OOP** — Alan Kay (Smalltalk, 1970s), sam ukuł termin „object-oriented". **GoF** — Gang of Four: Gamma, Helm, Johnson, Vlissides (1994). **Polimorfizm** — grec. „poly" (wiele) + „morphē" (forma) = wiele postaci. **Enkapsulacja** — łac. „capsula" = pudełeczko. **Abstrakcja** — łac. „abstrahere" = odciągać, oddzielać (oddzielanie istoty od szczegółów). **Design Pattern** — z architektury: Christopher Alexander „A Pattern Language" (1977); GoF zaadaptowali do IT. **Kompozycja > Dziedziczenie** — zasada z GoF: „favor object composition over class inheritance".
|
||||
|
||||
@ -97,40 +97,78 @@ Złam jeden = brak deadlocka.
|
||||
|
||||
### Budowa procesu
|
||||
|
||||
Proces = program w trakcie wykonania + cały jego kontekst. Składa się z:
|
||||
Proces = program w trakcie wykonania + cały jego kontekst. Składa się z **3 filarów**: pamięć, PCB, stany.
|
||||
|
||||
**Pamięć (oddzielna przestrzeń adresowa):**
|
||||
**Filar 1 — Pamięć (oddzielna przestrzeń adresowa):**
|
||||
|
||||
Każdy proces dostaje własną, izolowaną przestrzeń adresową. Inne procesy NIE widzą tej pamięci. Składa się z 5 segmentów (od niskich do wysokich adresów): TEXT → DATA → BSS → HEAP → STACK.
|
||||
|
||||

|
||||
|
||||
**PCB (Process Control Block)** — struktura w jądrze OS opisująca proces:
|
||||
Konkretny przykład — mapowanie kodu C na segmenty pamięci:
|
||||
|
||||

|
||||

|
||||
|
||||
**Filar 2 — PCB (Process Control Block):**
|
||||
|
||||
PCB to „dowód osobisty" procesu w jądrze OS. Zawiera WSZYSTKO co OS musi wiedzieć: PID, stan, rejestry CPU, tablice stron, otwarte pliki, priorytety, statystyki.
|
||||
|
||||

|
||||
|
||||
Przełączenie kontekstu = zapisanie PCB starego procesu → wczytanie PCB nowego.
|
||||
|
||||
**Stany procesu:** NEW → READY ↔ RUNNING → BLOCKED → TERMINATED.
|
||||
**Filar 3 — Stany procesu:**
|
||||
|
||||

|
||||
|
||||
Scheduler decyduje, który READY staje się RUNNING.
|
||||
|
||||
> **Mnemonik BUDOWY PROCESU — „TDBHS" (segmenty od dołu):**
|
||||
> **T**ata **D**aje **B**abci **H**erbatę ze **S**mietanką = TEXT → DATA → BSS → HEAP → STACK.
|
||||
> Proces = mieszkanie (własny adres, izolacja), PCB = dowód osobisty procesu (PID, stan, rejestry).
|
||||
> **Mnemonik BUDOWY PROCESU — „3 filary: MPS":**
|
||||
> **M**ieszkanie, **P**aszport, **S**tatus = **M**emory (5 segmentów), **P**CB (dowód), **S**tany (5 stanów).
|
||||
>
|
||||
> Segmenty od dołu — **„TDBHS"**: **T**ata **D**aje **B**abci **H**erbatę ze **S**mietanką = TEXT → DATA → BSS → HEAP → STACK.
|
||||
>
|
||||
> Stany — **„NRRBT"**: **N**igdy **R**ano **R**ybki **B**iegać nie **T**rafią = NEW → READY → RUNNING → BLOCKED → TERMINATED.
|
||||
>
|
||||
> PCB = paszport procesu — bez niego OS nie wie kim jest proces.
|
||||
|
||||
### Budowa wątku
|
||||
|
||||
Wątek = lekka jednostka wykonania WEWNĄTRZ procesu.
|
||||
|
||||
**Współdzielone** z innymi wątkami procesu: TEXT, DATA, BSS, HEAP, otwarte pliki, PID.
|
||||
**Prywatne** (każdy wątek ma własne): stos (stack), rejestry CPU, program counter (PC), TID.
|
||||
Kluczowa idea: wątek to NIE osobny byt — to dodatkowa „ścieżka wykonania" w istniejącym procesie. Proces z 3 wątkami ma 1 przestrzeń adresową, ale 3 niezależne ciągi instrukcji.
|
||||
|
||||

|
||||

|
||||
|
||||
Kluczowa różnica: proces ma CAŁĄ przestrzeń adresową, wątek to tylko kontekst wykonania (stos + rejestry) w ramach tej przestrzeni.
|
||||
**Co WSPÓŁDZIELONE**: TEXT, DATA, BSS, HEAP, otwarte pliki, PID — wszystkie wątki widzą to samo.
|
||||
|
||||
**Co PRYWATNE** (każdy wątek ma własne):
|
||||
- **Stos (stack)** — zmienne lokalne TEGO wątku, ramki wywołań
|
||||
- **Rejestry CPU** — stan procesora TEGO wątku (EAX, EBX, ESP...)
|
||||
- **Program Counter (PC)** — KTÓRA instrukcja jest teraz wykonywana
|
||||
- **TID** — unikalny identyfikator wątku
|
||||
|
||||
Konkretny przykład — dlaczego współdzielenie to siła i zagrożenie:
|
||||
|
||||
// Wątek 1 i Wątek 2 widzą TEN SAM obiekt:
|
||||
int shared_counter = 0; // HEAP — współdzielone!
|
||||
|
||||
// Wątek 1: // Wątek 2:
|
||||
shared_counter++; shared_counter++;
|
||||
// Oba czytają 0, oba piszą 1 → wynik 1 zamiast 2!
|
||||
// → race condition (potrzebny mutex)
|
||||
|
||||
Kluczowa różnica od procesu: proces ma CAŁĄ przestrzeń adresową (jak całe mieszkanie), wątek to tylko kontekst wykonania — stos + rejestry + PC (jak osoba w mieszkaniu ze swoim telefonem i pozycją w książce).
|
||||
|
||||
> **Mnemonik BUDOWY WĄTKU — „Wspólna kuchnia, własny pokój":**
|
||||
> Współdzielone = KOD + DANE + HEAP + PLIKI (kuchnia, salon, łazienka).
|
||||
> Współdzielone = KOD + DANE + HEAP + PLIKI (kuchnia, salon, łazienka — wszyscy korzystają).
|
||||
> Prywatne = STOS + REJESTRY + PC (twój pokój, twój telefon, twoja pozycja w książce).
|
||||
> Skrót: **„SRP"** — **S**tos, **R**ejestry, **P**C = prywatne.
|
||||
>
|
||||
> Skrót: **„SRP"** — **S**tos, **R**ejestry, **P**C = to co PRYWATNE.
|
||||
> Skrót odwrotny: **„KDHP"** — **K**od, **D**ane, **H**eap, **P**liki = to co WSPÓŁDZIELONE.
|
||||
>
|
||||
> Test: „Czy dwa wątki widzą tę samą zmienną globalną?" → TAK (współdzielone DATA).
|
||||
> „Czy dwa wątki widzą tę samą zmienną lokalną?" → NIE (osobne stosy).
|
||||
|
||||
### Szybkość — porównanie ilościowe
|
||||
|
||||
@ -151,23 +189,25 @@ Kluczowa różnica: proces ma CAŁĄ przestrzeń adresową, wątek to tylko kont
|
||||
### Zastosowanie — kiedy proces, kiedy wątek?
|
||||
|
||||
**Procesy — stosuj gdy:**
|
||||
|
||||
- **Izolacja jest krytyczna** — awaria jednego nie zabija reszty
|
||||
- Przeglądarka Chrome: każda karta = osobny proces. Crash Flash w jednej karcie nie zabija reszty.
|
||||
- Serwer: każde połączenie = fork() → klient nie może uszkodzić serwera (Apache pre-fork MPM)
|
||||
- Przeglądarka Chrome: każda karta = osobny proces. Crash Flash w jednej karcie nie zabija reszty.
|
||||
- Serwer: każde połączenie = fork() → klient nie może uszkodzić serwera (Apache pre-fork MPM)
|
||||
- **Bezpieczeństwo** — procesy nie widzą nawzajem pamięci
|
||||
- Sandboxing: proces renderujący PDFa nie ma dostępu do pamięci procesu z hasłami
|
||||
- Sandboxing: proces renderujący PDFa nie ma dostępu do pamięci procesu z hasłami
|
||||
- **Wieloprogramowość** — różne programy (edytor + kompilator + przeglądarka)
|
||||
- **Fork-exec** — klasyczny model Unix: fork() + exec() → nowy program
|
||||
|
||||
**Wątki — stosuj gdy:**
|
||||
|
||||
- **Współdzielenie danych** — wątki czytają/piszą ten sam heap bez kopiowania
|
||||
- Serwer WWW: wątki obsługujące requesty współdzielą cache w pamięci (nginx worker threads)
|
||||
- Gra: wątek renderujący i wątek fizyki czytają ten sam świat gry
|
||||
- Serwer WWW: wątki obsługujące requesty współdzielą cache w pamięci (nginx worker threads)
|
||||
- Gra: wątek renderujący i wątek fizyki czytają ten sam świat gry
|
||||
- **Szybkość tworzenia/przełączania** — potrzeba wielu lekkich zadań
|
||||
- Thread pool: 8 wątków obsługuje tysiące zadań (zamiast tysiąca procesów)
|
||||
- Thread pool: 8 wątków obsługuje tysiące zadań (zamiast tysiąca procesów)
|
||||
- **Obliczenia równoległe** — podział pracy na rdzenie CPU
|
||||
- Mnożenie macierzy: każdy wątek liczy fragment wyniku
|
||||
- Rendering: każdy wątek renderuje część klatki
|
||||
- Mnożenie macierzy: każdy wątek liczy fragment wyniku
|
||||
- Rendering: każdy wątek renderuje część klatki
|
||||
- **Responsywność UI** — wątek główny obsługuje interfejs, wątek tła liczy/pobiera dane
|
||||
|
||||

|
||||
@ -387,6 +427,68 @@ Wielu czytelników może czytać jednocześnie. Pisarz wymaga wyłącznego dost
|
||||
> Reguła kciuka: sekcja **> 1 μs → MUTEX** (wątek zasypia). Sekcja **< 1 μs → SPINLOCK** (kręci się). **n wątków naraz → SEMAFOR(n)**.
|
||||
> Mutex = klucz do łazienki (1 osoba). Semafor(3) = parking na 3 miejsca. Spinlock = obrotowe drzwi.
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — wątki w silnikach gier
|
||||
|
||||
> Praca magisterska: „Porównanie wydajności i możliwości współczesnych silników gier komputerowych" — Unity vs Unreal Engine. Temat wątków jest **kluczowy** dla game engine performance.
|
||||
|
||||

|
||||
|
||||
#### Game Loop = główny wątek silnika
|
||||
|
||||
Każdy silnik gier to **pętla główna (game loop)** działająca w jednym procesie z wieloma wątkami:
|
||||
|
||||
while (gameIsRunning) {
|
||||
ProcessInput(); // ← Main Thread (sekwencyjne)
|
||||
UpdateGameLogic(); // ← Main Thread
|
||||
PhysicsStep(); // ← Physics Thread (równoległe)
|
||||
RenderFrame(); // ← Render Thread (równoległe)
|
||||
PresentFrame(); // ← GPU sync (blokujące!)
|
||||
}
|
||||
|
||||
#### Unity vs Unreal — porównanie wielowątkowości
|
||||
|
||||
| Aspekt | Unity | Unreal Engine |
|
||||
|--------|-------|---------------|
|
||||
| Język | C# (managed) | C++ (native) |
|
||||
| Main thread | MonoBehaviour.Update() | AActor::Tick() |
|
||||
| Physics thread | PhysX (osobny) | PhysX (osobny) |
|
||||
| Render thread | Ukryty, submit GPU cmd | RenderThread (jawny) |
|
||||
| Worker pool | Job System (DOTS/Burst) | TaskGraph |
|
||||
| Problem | **GC pauses** zamrażają main thread! | Brak GC — deterministyczny timing |
|
||||
| Object pooling | BulletPool.cs eliminuje GC spikes | FPooledObject |
|
||||
|
||||
#### Przykład z pracy — BulletPool (Object Pooling)
|
||||
|
||||
W grze bullet-hell (1000+ pocisków) **bez poolingu**:
|
||||
- `Instantiate()` → alokacja na managed heap → GC musi zbierać → **spike w frame time**
|
||||
- Nsight Graphics pokazuje: frame time skacze z 8ms na 25ms podczas GC sweep
|
||||
|
||||
**Z poolingiem** (`BulletPool.cs`):
|
||||
- Pre-alokacja 2000 obiektów na starcie
|
||||
- `pool.Get()` / `pool.Return()` → **zero alokacji w runtime**
|
||||
- Frame time stabilny: 8ms ± 0.5ms
|
||||
|
||||
#### Problemy synchronizacji w silnikach gier — konkretne przykłady
|
||||
|
||||
| Problem (z pytania) | Jak występuje w game engine |
|
||||
|---------------------|------------------------------|
|
||||
| **Race condition** | Dwa wątki modyfikują pozycję tego samego obiektu (AI + Physics) |
|
||||
| **Deadlock** | Render Thread czeka na dane z Main Thread, który czeka na GPU fence |
|
||||
| **Zagłodzenie** | Render Thread ma wyższy priorytet → Audio Thread nie dostaje CPU |
|
||||
| **Inwersja priorytetów** | Low-pri asset loading blokuje mutex potrzebny High-pri render |
|
||||
|
||||
#### Mnemonik — „GRAJ WĄTKAMI"
|
||||
|
||||
**G**ame Loop (main thread) → **R**ender Thread → **A**udio Thread → **J**ob System (workers)
|
||||
Każda litera = osobny wątek. Game Loop orkiestruje resztę.
|
||||
|
||||
Kiedy na obronie padnie pytanie o wątki → od razu powiedz:
|
||||
*„W mojej pracy porównuję Unity Job System (C#/Burst) z Unreal TaskGraph (C++). Kluczowa różnica: Unity GC może zatrzymać main thread, Unreal ma deterministyczne czasy."*
|
||||
|
||||
---
|
||||
|
||||
### Etymologia
|
||||
|
||||
**Proces** — łac. „processus" = posuwanie się naprzód. **Wątek (Thread)** — metafora nitki wykonania (jak nić Ariadny). **Mutex** — portmanteau MUTual EXclusion. **Semafor** — Dijkstra (1965); od semaforów kolejowych; P() = hol. „proberen" (próbować), V() = hol. „verhogen" (podnosić). **Coffman** — Edward Coffman Jr. et al. (1971): 4 warunki konieczne deadlocka. **Deadlock (zakleszczenie)** — jak zablokowane koła zębate. **IPC** — Inter-Process Communication.
|
||||
|
||||
@ -438,6 +438,64 @@ Układ w pamięci:
|
||||
| Współdzielenie | Per-strona | Per-segment (naturalne) |
|
||||
| Współczesne OS | Dominuje (x86-64) | Rzadko (Intel porzucił) |
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — pamięć w silnikach gier
|
||||
|
||||
> Praca magisterska porównuje Unity (C#, Garbage Collector) z Unreal (C++, manual memory management). Zarządzanie pamięcią to **centralny temat** różnicy wydajnościowej.
|
||||
|
||||

|
||||
|
||||
#### Garbage Collector w Unity — jak to działa i dlaczego boli
|
||||
|
||||
**Boehm GC** (Unity < 2021) / **Incremental GC** (Unity 2019+):
|
||||
1. Allokacja: `new Bullet()` → managed heap
|
||||
2. Gdy heap pełny → **Stop-the-world GC pause** (mark & sweep)
|
||||
3. Wszystkie wątki **zamrożone** na czas GC → frame spike!
|
||||
|
||||
Frame time [ms]:
|
||||
Normal: █████████ 8ms
|
||||
GC hit: █████████████████████████████ 28ms ← SPIKE!
|
||||
Target: ████████████████ 16.67ms (60 FPS)
|
||||
|
||||
**Rozwiązanie #1 — Object Pooling:**
|
||||
|
||||

|
||||
|
||||
**Rozwiązanie #2 — Unity DOTS (ECS + Burst):**
|
||||
- NativeArray<T> → **unmanaged memory** (nie skanowana przez GC)
|
||||
- Burst Compiler → kompilacja C# do natywnego SIMD
|
||||
- Efekt: wydajność zbliżona do C++
|
||||
|
||||
#### Unreal Engine — pamięć w C++
|
||||
|
||||
| Mechanizm | Opis | Analogia z pytania |
|
||||
|-----------|------|---------------------|
|
||||
| `TSharedPtr<T>` | Reference counting (jak GC, ale deterministyczny) | Smart pointer = automatyczna relokacja |
|
||||
| `TUniquePtr<T>` | Exclusive ownership, zero overhead | Segment z private access |
|
||||
| `FMemory::Malloc` | Custom allocator z pool per size class | Jak system buddy allocation |
|
||||
| UObject GC | Reflection-based GC **tylko** dla UObject | Mark-sweep, ale kontrolowany timing |
|
||||
|
||||
#### Tabela porównawcza z pracy magisterskiej
|
||||
|
||||
| Metryka (Nsight) | Unity (bez pool) | Unity (z pool) | Unreal |
|
||||
|-------------------|-------------------|----------------|--------|
|
||||
| Alloc/frame | ~800 | ~0 | ~5 (deterministic) |
|
||||
| GC pause max | 25ms | 3ms | 0ms |
|
||||
| Heap fragmentation | Wysoka | Niska | Brak (custom alloc) |
|
||||
| Frame time sigma | 4.2ms | 0.8ms | 0.3ms |
|
||||
|
||||
#### Mnemonik — „GAP" = GC → Alloc → Pool
|
||||
|
||||
- **G**arbage Collector → problem (spikes)
|
||||
- **A**llocation → przyczyna (new w Update)
|
||||
- **P**ooling → rozwiązanie (pre-alloc + reuse)
|
||||
|
||||
Kiedy na obronie padnie pytanie o pamięć → powiedz:
|
||||
*„W mojej pracy kluczowa różnica to: Unity managed heap z GC (Boehm/Incremental) vs Unreal custom allocators + smart pointers. Object Pooling w Unity niweluje tę różnicę — mierzę to Nsight-em."*
|
||||
|
||||
---
|
||||
|
||||
### Etymologia
|
||||
|
||||
**Stronicowanie (Paging)** — pamięć dzielona na „strony" jak w książce. **TLB** — Translation Lookaside Buffer; „lookaside" = sprawdź z boku (cache) zanim sięgniesz do tablicy. **Segmentacja** — łac. „segmentum" = odcięty kawałek. **COW** — Copy-on-Write: kopiuj dopiero przy modyfikacji. **LRU** — Least Recently Used. **FIFO** — First In, First Out. **Page fault** — „fault" to wyjątek sprzętowy, nie błąd programisty.
|
||||
@ -448,3 +506,46 @@ Układ w pamięci:
|
||||
- **Segmentacja = pudełka różnej wielkości** (logiczne, ale fragmentacja zewnętrzna)
|
||||
- Współcześnie: **stronicowanie wygrało** — segmentacja prawie zniknęła (x86-64 = flat segments + paging)
|
||||
|
||||
**Mnemonik na 5 segmentów — „Tadek Będzie Dobry Student Harcerz":**
|
||||
|
||||
T — TEXT (kod programu, R-X)
|
||||
B — BSS (niezainicjalizowane globalne, zerowane)
|
||||
D — DATA (zainicjalizowane globalne, RW-)
|
||||
S — STOS (zmienne lokalne, rośnie ↓)
|
||||
H — HEAP (malloc/new, rośnie ↑)
|
||||
|
||||
Kolejność w pamięci (od niskich adresów):
|
||||
TEXT → DATA → BSS → HEAP ↑ ... ↓ STOS
|
||||
|
||||
Alternatywny mnemonik — od dołu pamięci w górę:
|
||||
„Tekst Daje Bezpieczeństwo, Hasła Stoją"
|
||||
TEXT → DATA → BSS → HEAP → STOS
|
||||
|
||||
**Mnemonik na fragmentację — „FOWZE":**
|
||||
|
||||
Fragmentacja:
|
||||
O (stały rOzmiar) → W (Wewnętrzna) — stronicowanie
|
||||
Z (Zmienny rozmiar) → E (Zewnętrzna) — segmentacja
|
||||
|
||||
Skojarzenie wizualne:
|
||||
Stronicowanie: szuflada 4KB, wkładasz 100B → reszta zmarnowana WEWNĄTRZ szuflady
|
||||
Segmentacja: pudełka różnej wielkości → dziury ZEWNĄTRZ między pudełkami
|
||||
|
||||
Krótka reguła: „Stały → Wewnętrzna, Zmienny → Zewnętrzna"
|
||||
|
||||
**Jak zapamiętać, żeby W OGÓLE wspomnieć o fragmentacji w odpowiedzi?**
|
||||
|
||||
Fragmentacja to PIERWSZY problem zarządzania pamięcią — wymień go jako punkt nr 1 listy problemów. Mnemonik na 5 problemów pamięci — **„FORWOW"**:
|
||||
|
||||
1. F — Fragmentacja (zewnętrzna + wewnętrzna)
|
||||
2. O — Ochrona (procesy nie widzą nawzajem pamięci)
|
||||
3. R — Relokacja (program pod różnymi adresami)
|
||||
4. W — Współdzielenie (biblioteki, COW)
|
||||
5. O — Ograniczona pamięć (więcej procesów niż RAM)
|
||||
(W — Wydajność — TLB, cache, minimalizacja page faults)
|
||||
|
||||
Kiedy mówisz o stronicowaniu → powiedz: „eliminuje fragmentację ZEWNĘTRZNĄ,
|
||||
ale wprowadza WEWNĘTRZNĄ" (to pokazuje, że pamiętasz!)
|
||||
Kiedy mówisz o segmentacji → powiedz: „brak wewnętrznej,
|
||||
ale fragmentacja ZEWNĘTRZNA — dlatego przegrała"
|
||||
|
||||
|
||||
@ -169,3 +169,28 @@ Stosowany w bankach, ubezpieczeniach, e-commerce. Unikalna cecha: diagram BPMN =
|
||||
- **3 typy bramek: XOR (jeden), AND (wszystkie), OR (jeden lub więcej)**
|
||||
- UML Activity → programiści; BPMN → wszyscy
|
||||
|
||||
---
|
||||
|
||||
### 📚 Odniesienia do publikacji z Katedry
|
||||
|
||||
> Poniższe notatki pochodzą z publikacji promotorów/recenzentów i mogą być przydatne jako dodatkowy kontekst na obronie.
|
||||
|
||||
**Szlenk, Zalewski, Borowa — „An evolution process for service-oriented systems" (DepCoS/Springer):**
|
||||
- Zaproponowano **4-fazowy proces modyfikacji systemów SOA** oparty o BPMN:
|
||||
1. Identyfikacja wpływu zmiany na usługi
|
||||
2. Przeprojektowanie usług dotkniętych zmianą
|
||||
3. Implementacja i testowanie
|
||||
4. Wdrożenie i monitoring
|
||||
- Proces jest zgodny z **ISO 20000 / ITIL** — łączy modelowanie procesów biznesowych z zarządzaniem usługami IT
|
||||
- BPMN użyty do formalnego opisu procesu ewolucji — każda faza ma diagram BPMN z bramkami decyzyjnymi i swimlane'ami
|
||||
- Walidacja: pilotaż z **11 firmami** — proces okazał się praktyczny i skalowalny
|
||||
- **Traceability** — śledzenie powiązań między procesami biznesowymi a usługami technicznymi, dzięki czemu zmiana w procesie BPMN automatycznie wskazuje usługi do modyfikacji
|
||||
|
||||
**Szlenk — „Extraction of UML class diagrams from natural language specifications":**
|
||||
- Automatyczne wyodrębnianie diagramów klas UML ze specyfikacji w języku naturalnym
|
||||
- Związek z BPMN: uzupełnienie modelowania procesów o modelowanie struktury danych (UML) na podstawie tych samych wymagań tekstowych
|
||||
|
||||
**Szlenk — „UML static models in formal approach" / „System model semantics of class diagrams":**
|
||||
- Formalizacja semantyki diagramów UML — umożliwia formalne sprawdzanie poprawności modeli
|
||||
- Przydatne gdy BPMN (procesy) i UML (struktura) muszą być spójne — formalizacja pozwala weryfikować tę spójność
|
||||
|
||||
|
||||
@ -344,3 +344,90 @@ Rozbicie:
|
||||
ATAM → ATakuj Architekturę Metodycznie
|
||||
ISO 25010 → 8 atrybutów: PS SM RUPC
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — architektura silników gier
|
||||
|
||||
> Moja praca porównuje architekturę Unity i Unreal Engine — to gotowy case study dla modelowania C4, 4+1, ADR.
|
||||
|
||||

|
||||
|
||||
#### C4 Model zastosowany do silnika gry
|
||||
|
||||
| Poziom C4 | Unity | Unreal Engine |
|
||||
|-----------|-------|---------------|
|
||||
| **Context** | Gracz → Gra ← Twórca (edytor) | Gracz → Gra ← Twórca (edytor) |
|
||||
| **Container** | Mono Runtime + IL2CPP, URP/HDRP Renderer, PhysX, FMOD | Unreal Runtime (C++), Nanite/Lumen Renderer, Chaos Physics, MetaSounds |
|
||||
| **Component** | `MonoBehaviour`, `ScriptableObject`, Job System | `UActorComponent`, `USubsystem`, TaskGraph |
|
||||
| **Code** | C# klasy: `BulletPool.cs`, `GameDirector.cs` | C++ klasy: `ABullet`, `AGameMode` |
|
||||
|
||||
#### 4+1 Kruchten — mapowanie na silnik
|
||||
|
||||
| Widok Kruchtena | Silnik gry |
|
||||
|----------------|------------|
|
||||
| Logiczny | Component Pattern, ECS, Scene Graph |
|
||||
| Procesowy | Game Loop (Update→Physics→Render), wątki |
|
||||
| Fizyczny | PC / PS5 / Xbox / Switch — deployment |
|
||||
| Rozwojowy | Edytor Unity/UE, pakiety, pluginy |
|
||||
| +1 Scenariusze | Gameplay: gracz strzela → bullet spawn → collision → damage |
|
||||
|
||||
#### ADR (Architecture Decision Records) z mojej pracy
|
||||
|
||||
Przykładowe decyzje architektoniczne, które mogę opisać językiem ADR:
|
||||
|
||||
1. **ADR-001**: Wybór Object Pooling zamiast Instantiate/Destroy
|
||||
*Kontekst*: 500 pocisków/sekundę powoduje GC spikes
|
||||
*Decyzja*: Pre-alokacja puli 500 obiektów
|
||||
*Konsekwencja*: Frame time σ z 8ms → 2ms
|
||||
|
||||
2. **ADR-002**: Singleton GameDirector zamiast static class
|
||||
*Kontekst*: Potrzeba globalnego stanu gry z lifecycle
|
||||
*Decyzja*: MonoBehaviour Singleton z `DontDestroyOnLoad`
|
||||
*Konsekwencja*: Testowalne, ale tight coupling
|
||||
|
||||
3. **ADR-003**: Unity URP zamiast Built-in RP
|
||||
*Kontekst*: SRP Batcher zmniejsza draw calls o ~40%
|
||||
*Decyzja*: Universal Render Pipeline
|
||||
*Konsekwencja*: Lepszy batching, ale ograniczenie custom shaderów
|
||||
|
||||
#### Mnemonik — „SPRM" = Silnik Porównuję Rysując Modele
|
||||
|
||||
- **S**cena jako Context (C4 Level 1)
|
||||
- **P**odsystemy jako Containers (Renderer, Physics, Audio)
|
||||
- **R**ejestr decyzji ADR (dlaczego Pool, Singleton, URP)
|
||||
- **M**oduły jako Components (MonoBehaviour, UActorComponent)
|
||||
|
||||
Na obronie: *„W mojej pracy porównuję architekturę Unity i Unreal — to idealny case study dla modelowania C4. Na poziomie Container widzimy fundamentalne różnice: Unity opiera się na Mono/.NET runtime z GC, a Unreal na natywnym C++ z ręcznym zarządzaniem pamięcią. Decyzje architektoniczne (ADR) w mojej implementacji — jak wybór Object Pooling — bezpośrednio odnoszą się do ADR rationales z publikacji Borowej."*
|
||||
|
||||
---
|
||||
|
||||
### 📚 Odniesienia do publikacji z Katedry
|
||||
|
||||
> Poniższe notatki pochodzą z publikacji promotorów/recenzentów i mogą być przydatne jako dodatkowy kontekst na obronie.
|
||||
|
||||
**Borowa, Zalewski, Kijas — „What rationales drive architectural decisions? An empirical inquiry" (ECSA 2023):**
|
||||
- Badanie empiryczne (46 uczestników) identyfikujące TOP rationales stojące za decyzjami architektonicznymi
|
||||
- Najczęstsze uzasadnienia decyzji: **łatwość użycia dla programisty**, **utrzymywalność (maintainability)**, **wydajność (performance)**, **wcześniejsza wiedza/doświadczenie**, **ograniczenia czasowe/deadlines**
|
||||
- Wniosek: decyzje architektoniczne są silnie napędzane czynnikami ludzkimi (doświadczenie, presja czasu), nie tylko technicznymi
|
||||
|
||||
**Borowa — „Cognitive Biases in Architectural Decision-Making: Impact and Debiasing Strategies" (rozprawa doktorska, PW 2024):**
|
||||
- Zidentyfikowano **11 błędów poznawczych (cognitive biases)** wpływających na ADM: efekt ramowania (framing), potwierdzenia (confirmation bias), efekt IKEA, prawo trywialności Parkinsona, zakotwiczenie (anchoring), klątwa wiedzy, pro-innovation bias, planistyczny optymizm, efekt owczego pędu (bandwagon), irracjonalna eskalacja, prawo instrumentu, optymizm
|
||||
- **„Wicked Triad"** — zakotwiczenie → potwierdzenie → optymizm: łańcuchowa reakcja prowadząca do źle uzasadnionych decyzji architektonicznych
|
||||
- Podstawa teoretyczna: **Dual Process Theory (Kahneman)** — System 1 (szybki, intuicyjny) vs System 2 (wolny, analityczny); biasy wynikają z nadmiernego polegania na System 1
|
||||
- ADR-y (Architecture Decision Records) mogą częściowo łagodzić biasy, wymuszając jawne zapisanie kontekstu i konsekwencji
|
||||
- Debiasing: **interwencja C-level Fischhoffa** — 3 techniki: (1) rozważ wiele opcji, (2) wypisz wady wybranego rozwiązania, (3) wypisz ryzyka
|
||||
- Eksperyment z 18 praktykami (Polska, Niemcy, Brazylia): statystycznie istotny wzrost kontrargumentów nie-biasowych (p=0.0449)
|
||||
|
||||
**Borowa, Zalewski — „The influence of cognitive biases on architectural technical debt" (ICSA 2021):**
|
||||
- Zakotwiczenie + optymizm → **„Architectural Lock-in"** (zamknięcie się w architekturze)
|
||||
- Confirmation bias → **„Re-inventing the wheel"** (wymyślanie koła na nowo zamiast reuse)
|
||||
- Biasy poznawcze są bezpośrednią przyczyną powstawania architektonicznego długu technicznego (ATD)
|
||||
|
||||
**Szlenk — „Formal Semantics of Architectural Decision Models":**
|
||||
- Formalizacja semantyki modeli decyzji architektonicznych — umożliwia formalne rozumowanie o poprawności i spójności decyzji
|
||||
- Związek z ADR: formalne podejście do walidacji decyzji architektonicznych
|
||||
|
||||
**Szlenk — „Modelling architectural decisions under changing requirements":**
|
||||
- Jak zmieniające się wymagania wpływają na decyzje architektoniczne
|
||||
- Metoda śledzenia wpływu zmian wymagań na podjęte wcześniej decyzje (traceability)
|
||||
|
||||
|
||||
@ -220,3 +220,68 @@ Każdy wzorzec w katalogu ma pole „Powiązane wzorce" — to linki w tym grafi
|
||||
- `pytania/img/q14_observer_card_filled.png` — wypełniona karta wzorca Observer
|
||||
- `pytania/img/q14_pattern_language_navigation.png` — nawigacja w języku wzorców
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — wzorce w silnikach gier
|
||||
|
||||
> Silniki gier to największe repozytorium wzorców architektonicznych i projektowych w praktyce. Moja praca verwendet 6 kluczowych wzorców.
|
||||
|
||||

|
||||
|
||||
#### 6 wzorców użytych w mojej pracy
|
||||
|
||||
| # | Wzorzec | Gdzie w Unity (C#) | Gdzie w Unreal (C++) | Kategoria GoF/POSA |
|
||||
|---|---------|---------------------|----------------------|---------------------|
|
||||
| 1 | **Component** | `MonoBehaviour` + `GetComponent<T>()` | `UActorComponent` + `CreateDefaultSubobject<T>()` | Strukturalny (GoF: Strategy wariant) |
|
||||
| 2 | **Object Pool** | `BulletPool.cs` — `Queue<Bullet>` | `TPooledObject<ABullet>` | Kreacyjny (gamedev-specific) |
|
||||
| 3 | **Observer** | `event Action OnEnemyDeath` | `DECLARE_DYNAMIC_MULTICAST_DELEGATE()` | Behawioralny (GoF) |
|
||||
| 4 | **Game Loop** | `Update()` / `FixedUpdate()` / `LateUpdate()` | `Tick()` / `TickComponent()` | Architektoniczny (gamedev-specific) |
|
||||
| 5 | **Singleton** | `GameDirector.Instance` (MonoBehaviour) | `UGameInstance` / Subsystem | Kreacyjny (GoF) — kontrowersyjny! |
|
||||
| 6 | **ECS** | Unity DOTS: `IComponentData` + `SystemBase` | Unreal Mass Entity: `FMassEntityManager` | Architektoniczny (data-oriented) |
|
||||
|
||||
#### Katalogi wzorców gamedev
|
||||
|
||||
| Katalog | Autor | Ile wzorców | Kluczowe dla mojej pracy |
|
||||
|---------|-------|-------------|--------------------------|
|
||||
| „Game Programming Patterns" | Robert Nystrom | 19 | Component, Object Pool, Game Loop, Observer |
|
||||
| GoF (Design Patterns, 1994) | Gamma et al. | 23 | Observer, Singleton, Strategy, State |
|
||||
| POSA (Pattern-Oriented SA) | Buschmann et al. | 25+ | Layers, Pipes-and-Filters, Broker |
|
||||
|
||||
#### Mnemonik — „KOGLES" = Komponent Observer Game-Loop ECS Singleton
|
||||
|
||||
- **K**omponent (Component Pattern — fundamentalny)
|
||||
- **O**bserver (event-driven gameplay)
|
||||
- **G**ame Loop (Update/Tick — serce silnika)
|
||||
- **L**ayers (Renderer → Physics → Logic → Audio → Input)
|
||||
- **E**CS (Entity Component System — data-oriented design)
|
||||
- **S**ingleton (GameDirector.Instance — globalny stan)
|
||||
|
||||
Na obronie: *„W mojej implementacji bullet-hell zidentyfikowałem 6 wzorców architektonicznych. Najważniejszy to Component Pattern — Unity i Unreal oparły na nim całą architekturę. Object Pool eliminuje alokacje (GC spikes), a Observer zapewnia loose coupling między podsystemami. Wzorce te odpowiadają katalogowi Nystroma 'Game Programming Patterns' i GoF."*
|
||||
|
||||
---
|
||||
|
||||
### 📚 Odniesienia do publikacji z Katedry
|
||||
|
||||
> Poniższe notatki pochodzą z publikacji promotorów/recenzentów i mogą być przydatne jako dodatkowy kontekst na obronie.
|
||||
|
||||
**Borowa, Zalewski, Kijas — „What rationales drive architectural decisions? An empirical inquiry" (ECSA 2023):**
|
||||
- Uzasadnienia (rationale) za wyborem wzorca architektonicznego to najczęściej: łatwość użycia dla dev, maintainability, performance, wcześniejsza wiedza i ograniczenia czasowe
|
||||
- Implikacja: wybór wzorca (np. Microservices vs Monolith) jest często napędzany doświadczeniem zespołu i deadlinem, nie tylko analizą tradeoffs
|
||||
- Wzorce powinny mieć udokumentowane rationale (→ ADR), bo decyzje bez jawnego uzasadnienia mogą wynikać z biasów
|
||||
|
||||
**Borowa, Zalewski — „The influence of cognitive biases on architectural technical debt" (ICSA 2021):**
|
||||
- **Błędy poznawcze prowadzą do złych wyborów wzorców:**
|
||||
- Zakotwiczenie (anchoring) + optymizm → „Architectural Lock-in" — zespół trzyma się wybranego wzorca mimo rosnących problemów
|
||||
- Confirmation bias → „Re-inventing the wheel" — budowanie od zera zamiast użycia istniejącego wzorca/frameworka
|
||||
- Bandwagon effect → wybór Microservices „bo wszyscy tak robią", bez analizy czy skala projektu to uzasadnia
|
||||
- Wzorce architektoniczne jako **narzędzie debiasujące**: katalogowane rozwiązania wymuszają rozważenie alternatyw i tradeoffs, co przeciwdziała zakotwiczeniu
|
||||
|
||||
**Borowa — „The technical debt gamble: A case study on TD in a large-scale industrial microservice architecture" (ScienceDirect 2025):**
|
||||
- Case study dużego systemu mikroserwisowego — dług techniczny narasta gdy decyzje o wzorcach są podejmowane pod presją czasu
|
||||
- Wzorce jak Microservices wymagają świadomego zarządzania TD, bo złożoność operacyjna generuje dług
|
||||
|
||||
**Borowa et al. — „Reframing Technical Debt — Dagstuhl Perspectives Workshop 24452":**
|
||||
- 5 values, 5 beliefs, 9 principles zarządzania TD
|
||||
- Architektura jako kluczowy wymiar TD — nieodpowiednie wzorce architektoniczne to główne źródło długu technicznego
|
||||
- Zasada: „TD jest nieunikniony, ale ZARZĄDZALNY" — świadomy wybór wzorca + dokumentacja (ADR) + regularny przegląd
|
||||
|
||||
|
||||
@ -38,26 +38,119 @@ Przyczyny: prognozowanie (forecasting), zamawianie partiami (batching), promocje
|
||||
|
||||
---
|
||||
|
||||
**EOQ (Economic Order Quantity)** — model Harrisa-Wilsona (1913). Najstarszy model zarządzenia zapasami. Znajduje optymalną wielkość zamówienia Q* minimalizującą łączny koszt (zamawianie + utrzymanie).
|
||||
**EOQ (Economic Order Quantity)** — model Harrisa-Wilsona (1913). Najstarszy i najważniejszy model zarządzania zapasami. Odpowiada na pytanie: **ile sztuk zamawiać jednorazowo**, żeby suma kosztów zamawiania i utrzymania była minimalna.
|
||||
|
||||
**Założenia EOQ:** popyt stały i znany (D szt/rok), lead time = 0, brak braków, koszt zamówienia K, koszt utrzymania h.
|
||||
**Intuicja — analogia z zakupami papieru toaletowego:**
|
||||
|
||||
**Wzór EOQ:**
|
||||
Strategia A: kupujesz 1 paczkę co tydzień
|
||||
→ dużo wizyt w sklepie (wysoki koszt zamawiania)
|
||||
→ mało miejsca w domu (niski koszt utrzymania)
|
||||
|
||||
Q* = √(2KD/h)
|
||||
Strategia B: kupujesz 100 paczek raz na 2 lata
|
||||
→ rzadko chodzisz do sklepu (niski koszt zamawiania)
|
||||
→ potrzebujesz magazynu (wysoki koszt utrzymania)
|
||||
|
||||
TC(Q) = K·D/Q + h·Q/2
|
||||
koszt koszt
|
||||
zamawiania utrzymania
|
||||
EOQ: ile paczek kupować, żeby SUMA obu kosztów była najniższa?
|
||||
|
||||
**Dlaczego √?** Bo koszty zamawiania maleją z Q (mniej zamówień), a koszty utrzymania rosną z Q (więcej w magazynie). Optimum = punkt przecięcia.
|
||||
**Założenia EOQ (ważne — na obronie mogą zapytać o ograniczenia!):**
|
||||
1. Popyt stały i znany: D sztuk/rok (np. sprzedaż jest przewidywalna)
|
||||
2. Lead time = 0 (dostawa natychmiastowa)
|
||||
3. Brak braków (nie dopuszczamy stockoutów)
|
||||
4. Zamówienie przychodzi w całości (nie częściami)
|
||||
5. Koszt zamówienia K — stały, niezależny od wielkości
|
||||
6. Koszt utrzymania h — liniowo zależy od ilości w magazynie
|
||||
|
||||
**Przykład liczbowy:**
|
||||
---
|
||||
|
||||
D = 10 000 szt/rok, K = 100 PLN/zamówienie, h = 2 PLN/szt/rok
|
||||
Q* = √(2 × 100 × 10000 / 2) = √1 000 000 = 1000 szt
|
||||
Liczba zamówień = 10000/1000 = 10/rok
|
||||
TC* = √(2 × 100 × 10000 × 2) = 2000 PLN/rok
|
||||
**Wyprowadzenie wzoru EOQ krok po kroku:**
|
||||
|
||||
Krok 1 — Funkcja kosztu całkowitego:
|
||||
|
||||
TC(Q) = K · D/Q + h · Q/2
|
||||
↑ ↑
|
||||
ile zamówień średni zapas
|
||||
rocznie? w magazynie
|
||||
(D/Q sztuk) (Q/2 sztuk)
|
||||
|
||||
Dlaczego D/Q? Bo potrzebujemy D sztuk rocznie, zamawiamy po Q → robimy D/Q zamówień.
|
||||
Dlaczego Q/2? Zapas waha się od Q (tuż po dostawie) do 0 (tuż przed następną) → średnio Q/2.
|
||||
|
||||

|
||||
|
||||
Krok 2 — Szukamy minimum (pochodna = 0):
|
||||
|
||||
dTC/dQ = -K·D/Q² + h/2 = 0
|
||||
|
||||
h/2 = K·D/Q²
|
||||
|
||||
Q² = 2·K·D / h
|
||||
|
||||
Q* = √(2KD/h) ← wzór EOQ!
|
||||
|
||||
Krok 3 — Weryfikacja: druga pochodna d²TC/dQ² = 2KD/Q³ > 0 → to jest minimum (nie maksimum).
|
||||
|
||||
**Dlaczego √?** Bo rozwiązujemy równanie kwadratowe — punkt, w którym malejąca hiperbola (koszt zamawiania K·D/Q) przecina rosnącą prostą (koszt utrzymania h·Q/2).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Przykład liczbowy (krok po kroku):**
|
||||
|
||||
Dane:
|
||||
D = 10 000 szt/rok (popyt roczny)
|
||||
K = 100 PLN/zamówienie (koszt złożenia zamówienia)
|
||||
h = 2 PLN/szt/rok (koszt trzymania jednej sztuki przez rok)
|
||||
|
||||
Q* = √(2 × 100 × 10000 / 2)
|
||||
= √(2 000 000 / 2)
|
||||
= √1 000 000
|
||||
= 1000 szt ← zamawiaj po 1000 sztuk
|
||||
|
||||
Ile zamówień rocznie? D/Q* = 10000/1000 = 10 zamówień
|
||||
Co ile? 365/10 ≈ co 36-37 dni
|
||||
Średni zapas: Q*/2 = 500 szt
|
||||
|
||||
Koszt roczny:
|
||||
Zamawianie: K·D/Q* = 100 × 10 = 1000 PLN
|
||||
Utrzymanie: h·Q*/2 = 2 × 500 = 1000 PLN ← ZAWSZE równe!
|
||||
Suma: TC* = 2000 PLN/rok
|
||||
|
||||
**Kluczowa własność:** w punkcie optymalnym koszt zamawiania = koszt utrzymania. To wynika z matematyki i jest świetnym testem kontrolnym.
|
||||
|
||||
TC* = √(2KDh) = √(2 × 100 × 10000 × 2) = √4 000 000 = 2000 PLN
|
||||
|
||||
---
|
||||
|
||||
**Analiza wrażliwości — co jeśli Q nie jest optymalne?**
|
||||
|
||||
EOQ jest odporny na błędy (robustness) — nawet 20% błąd w Q daje tylko ~2% wzrost kosztu:
|
||||
|
||||
Q TC(Q) vs TC*=2000 % wzrost
|
||||
─────────────────────────────────────────────
|
||||
500 2500 +500 +25%
|
||||
800 2050 +50 +2.5%
|
||||
1000 2000 ±0 optimum
|
||||
1200 2033 +33 +1.7%
|
||||
1500 2117 +117 +5.8%
|
||||
2000 2500 +500 +25%
|
||||
|
||||
Wniosek: lepiej zaokrąglić Q* do wygodnej liczby (np. do pełnej palety) niż trzymać się dokładnej wartości. Koszty rosną powoli wokół optimum.
|
||||
|
||||
---
|
||||
|
||||
**Ograniczenia EOQ (częste pytanie na obronie: „kiedy model NIE działa?"):**
|
||||
|
||||
Założenie EOQ Rzeczywistość
|
||||
──────────────────────────────────────────────────
|
||||
Popyt stały Popyt zmienny/sezonowy
|
||||
Lead time = 0 Lead time > 0 i zmienny
|
||||
Brak braków Braki się zdarzają
|
||||
Jeden produkt Wiele produktów konkuruje o magazyn
|
||||
Brak rabatów Rabaty ilościowe (za większe partie)
|
||||
Koszt h stały h zależy od ilości (schodkowo)
|
||||
|
||||
Dlatego EOQ jest punktem startowym — w praktyce stosuje się jego rozszerzenia (EOQ z rabatami, EOQ z backorders, dynamiczny lot sizing).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -232,3 +232,36 @@ Paxos ma 3 role: **Proposer** (proponuje wartość), **Acceptor** (głosuje), **
|
||||
- **CAP = „Partition → wybierz C albo A"**
|
||||
- **Quorum: W+R > N** gwarantuje odczyt najnowszej wartości
|
||||
|
||||
**Linearizability vs Sequential Consistency — jak zapamiętać różnicę:**
|
||||
|
||||
Kluczowe słowo: **ZEGAREK ŚCIENNY** (real-time).
|
||||
- **Linear**izability = **LINIA czasu rzeczywistego** — operacje respektują realny zegar. Litera **L** jak **Live** (transmisja na żywo). Jeśli zapis SKOŃCZYŁ SIĘ przed rozpoczęciem odczytu wg zegarka na ścianie → odczyt MUSI go widzieć.
|
||||
- **Sequential** consistency = **SEKWENCJA** (kolejka) bez zegarka — operacje każdego procesu zachowują swoją kolejność, ale system może je „przemieszać" w czasie. Litera **S** jak **Shuffled** (przetasowane w czasie, ale wewnętrznie spójne).
|
||||
|
||||
Pytanie kontrolne: „Czy liczy się KIEDY (zegarek) operacja się wydarzyła?"
|
||||
Linearizability: TAK — czas rzeczywisty się liczy
|
||||
Sequential: NIE — liczy się tylko KOLEJNOŚĆ wewnątrz procesu
|
||||
|
||||
Mnemonik: „Linearizability = Live, Sequential = Shifted"
|
||||
(Live = na żywo wg zegara, Shifted = przesunięte w czasie, ale po kolei)
|
||||
|
||||
**Session Guarantees — mnemonik na 4 nazwy: „RMM-W" (jak RMM-Wóz):**
|
||||
|
||||
Wyobraź sobie wóz dostawczy RMM-W, który dostarcza gwarancje sesji:
|
||||
|
||||
R — Read Your Writes (czytasz to co SAM napisałeś)
|
||||
M — Monotonic Reads (odczyty nie cofają się)
|
||||
M — Monotonic Writes (zapisy stosowane po kolei)
|
||||
W — Writes Follow Reads (zapis po odczycie = zapis zależy od odczytu)
|
||||
|
||||
Albo zdanie: **„Radek Ma Miłe Wspomnienia"** — każde słowo → pierwsza litera gwarancji:
|
||||
- **R**adek → **R**ead Your Writes
|
||||
- **M**a → **M**onotonic Reads
|
||||
- **M**iłe → **M**onotonic Writes
|
||||
- **W**spomnienia → **W**rites Follow Reads
|
||||
|
||||
Dodatkowy trik: 2 gwarancje „Monotonic" (Reads + Writes) — monotoniczny = „nie cofa się"
|
||||
Zostają 2 gwarancje „krzyżowe": Read→Write (RYW) i Write→Read (WFR)
|
||||
RYW = „widzę swoje własne zapisy"
|
||||
WFR = „mój zapis zależy od tego co przeczytałem"
|
||||
|
||||
|
||||
@ -108,6 +108,77 @@ Dla p=90%, n=100: Gustafson → S = 1 - 0.9 + 0.9×100 = 90.1x (vs Amdahl: ~10x!
|
||||
|
||||
### Efektywność: E(n) = S(n)/n — spada z n
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — Amdahl w silnikach gier
|
||||
|
||||
> W pracy mierzę frame time silników Nsightem — to DOKŁADNIE problem Amdahla: ile z pipeline'u renderowania da się zrównoleglić?
|
||||
|
||||

|
||||
|
||||
#### Frame budget jako problem Amdahla
|
||||
|
||||
Cel: 60 FPS → frame budget = 16.67 ms. Pipeline w jednej klatce:
|
||||
|
||||
| Faza pipeline'u | Czas [ms] | Równoległa? |
|
||||
|----------------|-----------|-------------|
|
||||
| Input polling | 0.2 | NIE (sekw.) |
|
||||
| Game Logic / AI | 2.0 | CZĘŚCIOWO (Job System) |
|
||||
| Physics (FixedUpdate) | 3.0 | TAK (PhysX broadphase) |
|
||||
| Rendering (draw calls) | 8.0 | TAK (GPU parallel) |
|
||||
| Audio mixing | 1.0 | TAK (osobny wątek) |
|
||||
| GC / Housekeeping | 1.5 | NIE (stop-the-world!) |
|
||||
| **SUMA** | **15.7** | |
|
||||
|
||||
Część sekwencyjna: $s = (0.2 + 1.5) / 15.7 ≈ 0.108$ (10.8%)
|
||||
|
||||
Prawo Amdahla: $S_{max} = \frac{1}{0.108} ≈ 9.26×$ — nawet z ∞ rdzeni max 9.26× speedup!
|
||||
|
||||
#### Unity vs Unreal — różnica w „s" (część sekwencyjna)
|
||||
|
||||
| Czynnik | Unity (C#) | Unreal (C++) | Wpływ na Amdahla |
|
||||
|---------|-----------|--------------|-------------------|
|
||||
| GC pauses | ~2 ms/frame (Boehm) | 0 ms (brak GC) | Unity: s ↑ → S_max ↓ |
|
||||
| Job System | Unity DOTS / Burst | TaskGraph | Oba: p ↑, ale API różne |
|
||||
| Draw call batching | SRP Batcher (~40% mniej) | Nanite (auto-LOD) | Oba redukują czas GPU |
|
||||
| Main thread lock | `Update()` jest single-thread | `Tick()` jest single-thread | Oba: s zawiera game logic |
|
||||
|
||||
#### Obliczenie z Nsight (dane z mojej pracy)
|
||||
|
||||
Unity bullet-hell (500 pocisków):
|
||||
Seq: Input(0.2) + GC(1.8) + MainThread-Logic(1.5) = 3.5 ms
|
||||
Par: Physics(2.0) + Render(7.0) + Audio(0.8) = 9.8 ms
|
||||
Total = 13.3 ms → s = 3.5/13.3 = 0.263
|
||||
S_max = 1/0.263 ≈ 3.8×
|
||||
|
||||
Unreal bullet-hell (500 pocisków):
|
||||
Seq: Input(0.2) + MainThread-Logic(1.2) = 1.4 ms
|
||||
Par: Physics(1.8) + Render(6.5) + Audio(0.7) = 9.0 ms
|
||||
Total = 10.4 ms → s = 1.4/10.4 = 0.135
|
||||
S_max = 1/0.135 ≈ 7.4×
|
||||
|
||||
**Wniosek**: Unreal ma mniejszą część sekwencyjną (brak GC!) → lepsze skalowanie.
|
||||
|
||||
#### Gustafson w gamedev — „zwiększ świat"
|
||||
|
||||
Podejście Gustafson: zamiast „jak szybko 500 pocisków?" → „ile pocisków przy stałym frame budget?"
|
||||
- Unity (4 rdzenie): ~800 pocisków w 16.67ms
|
||||
- Unreal (4 rdzenie): ~1200 pocisków w 16.67ms
|
||||
- To **weak scaling** — typowe dla open-world gier
|
||||
|
||||
#### Mnemonik — „NSIGHT" = Naprawdę Sekwencyjna Część Ogranicza
|
||||
|
||||
- **N**ie da się przyspieszyć ponad 1/s
|
||||
- **S**ekwencyjna = GC + Input + Main Thread
|
||||
- **I**nstrukcje GPU = ta równoległa część
|
||||
- **G**ustafson = zwiększ problem (więcej pocisków!)
|
||||
- **H**ardware ma N rdzeni → E(n)=S(n)/n
|
||||
- **T**est w Nsight → zmierz s i p empirycznie
|
||||
|
||||
Na obronie: *„Prawo Amdahla bezpośrednio tłumaczy wyniki moich benchmarków — Unity ma większą część sekwencyjną (GC stop-the-world), więc gorzej skaluje się wielowątkowo. Unreal bez GC osiąga prawie 2× lepsze teoretyczne speedup. To zmierzyłem Nsightem."*
|
||||
|
||||
---
|
||||
|
||||
### Etymologia
|
||||
|
||||
**Gene Amdahl** (IBM, 1967, „Validity of the single processor approach..."); współtwórca IBM System/360. **John Gustafson** (Sandia Labs, 1988, „Reevaluating Amdahl's Law"); weak scaling vs strong scaling. **Speedup (przyspieszenie)** — stosunek czasu sekwencyjnego do równoległego. **Efektywność** — ile z dodanych procesorów jest naprawdę wykorzystane. **Lock-free** — struktury danych bez blokad (CAS — Compare-And-Swap).
|
||||
|
||||
@ -96,6 +96,10 @@ Analogia: Isend/Irecv to jak złożenie zamówienia w restauracji — kelner zap
|
||||
|
||||
**Metoda Jacobiego (Jacobi iteration)** — iteracyjna metoda rozwiązywania układów równań liniowych $Ax = b$. W każdej iteracji nowa wartość $x_i$ jest obliczana WYŁĄCZNIE na podstawie wartości z poprzedniej iteracji (w przeciwieństwie do metody Gaussa-Seidla, która używa już obliczonych nowych wartości).
|
||||
|
||||
**Kluczowa intuicja — szablon obliczeniowy (stencil):** W 1D Jacobi nowa wartość punktu to średnia jego dwóch sąsiadów: $x'[i] = \frac{1}{2}(x[i-1] + x[i+1])$. Aby obliczyć JEDNĄ nową wartość, potrzebujesz DWÓCH starych wartości — lewej i prawej. To jest właśnie powód, dla którego procesy muszą się komunikować.
|
||||
|
||||

|
||||
|
||||
Konkretny przykład — układ 3 równań:
|
||||
|
||||
10x₁ + 2x₂ + x₃ = 27 Przekształcenie:
|
||||
@ -114,14 +118,56 @@ Konkretny przykład — układ 3 równań:
|
||||
|
||||
**Wersja równoległa metody Jacobiego** — w obliczeniach naukowych (np. symulacja ciepła, dynamika płynów) macierz $A$ jest ogromna (miliony zmiennych). Dzielimy wektor $x$ na bloki — każdy proces MPI oblicza swój fragment. Ale na granicy bloków proces potrzebuje wartości od sąsiada → wymiana komunikatami Send/Recv.
|
||||
|
||||
Domena 1D podzielona na 4 procesy:
|
||||
Proc 0 Proc 1 Proc 2 Proc 3
|
||||
[x₀ x₁ x₂] [x₃ x₄ x₅] [x₆ x₇ x₈] [x₉ x₁₀ x₁₁]
|
||||
↑↓ ↑↓ ↑↓
|
||||
wymiana x₂↔x₃ wymiana x₅↔x₆ wymiana x₈↔x₉
|
||||
**Dlaczego proces potrzebuje wartości od sąsiada — krok po kroku:**
|
||||
|
||||
Każdy proces potrzebuje "ghost cells" (komórek-duchów) od sąsiada,
|
||||
by obliczyć nowe wartości na swojej granicy.
|
||||
Wyobraź sobie tablicę 12 elementów podzieloną na 3 procesy:
|
||||
- Proces 0 ma x[0], x[1], x[2], x[3]
|
||||
- Proces 1 ma x[4], x[5], x[6], x[7]
|
||||
- Proces 2 ma x[8], x[9], x[10], x[11]
|
||||
|
||||
Teraz Proces 0 chce obliczyć nową wartość x'[3] (swoją prawą granicę). Wzór mówi:
|
||||
|
||||
$x'[3] = \frac{1}{2}(x[2] + x[4])$
|
||||
|
||||
- x[2] — Proces 0 **MA** tę wartość (należy do niego)
|
||||
- x[4] — Proces 0 **NIE MA** tej wartości! Należy do Procesu 1!
|
||||
|
||||
→ Proces 0 **musi poprosić** Proces 1 o przesłanie x[4]. Tę dodatkową kopię nazywamy **komórką-duchem (ghost cell)**.
|
||||
|
||||
Analogicznie Proces 1 potrzebuje x[3] od Procesu 0, żeby obliczyć x'[4] = ½(x[3] + x[5]).
|
||||
|
||||

|
||||
|
||||
**Wymiana ghost cells** — w każdej iteracji Jacobiego każda para sąsiednich procesów musi wymienić po jednej wartości granicznej. Przed wymianą ghost cells są puste (?), po wymianie zawierają kopie wartości od sąsiada:
|
||||
|
||||

|
||||
|
||||
**Pseudokod jednej iteracji równoległego Jacobiego:**
|
||||
|
||||
// Każdy proces (SPMD — ten sam kod na każdym procesie):
|
||||
for iter = 1 to max_iter:
|
||||
|
||||
// Krok 1: Oblicz punkty WEWNĘTRZNE (nie potrzebują ghost cells)
|
||||
for i = 1 to local_n - 2: // pomijamy granice
|
||||
x_new[i] = 0.5 * (x[i-1] + x[i+1])
|
||||
|
||||
// Krok 2: Wymień ghost cells z sąsiadami
|
||||
wyślij x[local_n-1] do prawego sąsiada // moja prawa granica
|
||||
wyślij x[0] do lewego sąsiada // moja lewa granica
|
||||
odbierz ghost_right od prawego sąsiada // kopia jego lewej granicy
|
||||
odbierz ghost_left od lewego sąsiada // kopia jego prawej granicy
|
||||
|
||||
// Krok 3: Oblicz punkty GRANICZNE (teraz ghost cells są dostępne)
|
||||
x_new[0] = 0.5 * (ghost_left + x[1])
|
||||
x_new[local_n-1] = 0.5 * (x[local_n-2] + ghost_right)
|
||||
|
||||
// Sprawdź zbieżność
|
||||
if |x_new - x| < epsilon: break
|
||||
x = x_new
|
||||
|
||||

|
||||
|
||||
**Uwaga na kolejność Krok 2!** Sposób realizacji wymiany ghost cells (Krok 2) to właśnie sedno tego pytania — jeśli użyjemy blokującego, synchronicznego Send (Ssend), oba procesy zawiśną czekając na siebie nawzajem (deadlock). Rozwiązania omówione poniżej.
|
||||
|
||||
**Kod SPMD (Single Program, Multiple Data)** — model programowania, gdzie WSZYSTKIE procesy uruchamiają TEN SAM program. Każdy rozróżnia się tylko numerem (rankiem). To jest właśnie „symetryczny kod" — i tu leży problem z deadlockiem.
|
||||
|
||||
@ -138,6 +184,8 @@ Konkretny przykład — układ 3 równań:
|
||||
Proc 1: Ssend(to=0) → czeka na Recv(from=0) w Proc 0
|
||||
→ OBA CZEKAJĄ → DEADLOCK!
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Rozwiązania deadlocka w symetrycznym kodzie** — istnieją 4 główne strategie. Każda ma inne kompromisy między prostotą kodu, wydajnością i bezpieczeństwem.
|
||||
@ -383,6 +431,77 @@ Nadawca kopiuje dane do wcześniej zaalokowanego bufora i wraca natychmiast. Rec
|
||||
MPI_Sendrecv Tak Nie Nie ★ Najlepsza
|
||||
Bsend Tak Nie Bufor użytkownika Średnia
|
||||
|
||||
---
|
||||
|
||||
### 🎮 Mostek do pracy magisterskiej — sync/async w silnikach gier
|
||||
|
||||
> Komunikacja CPU↔GPU w silniku gry to DOKŁADNIE problem synchronicznego vs asynchronicznego przesyłania wiadomości — jak MPI Send/Recv.
|
||||
|
||||

|
||||
|
||||
#### CPU↔GPU jako MPI Send/Recv
|
||||
|
||||
| Mechanizm silnika | MPI analogia | Blokująca? | Sync? |
|
||||
|-------------------|-------------|------------|-------|
|
||||
| `glFinish()` / `WaitForGPU()` | `MPI_Ssend` | TAK | TAK |
|
||||
| `glFlush()` / submit command buffer | `MPI_Send` (buforowane) | NIE | NIE |
|
||||
| Unity `AsyncGPUReadback` | `MPI_Irecv` + `MPI_Wait` | NIE (initial) | NIE |
|
||||
| Triple buffering (3 frame buffers) | Pipeline z `MPI_Isend` + `MPI_Irecv` | NIE | NIE |
|
||||
| `CommandBuffer.IssuePluginEvent()` | `MPI_Bsend` (bufor użytkownika) | NIE | TAK |
|
||||
| Unity Coroutine `yield return` | `MPI_Isend` + ... + `MPI_Wait` (later) | NIE → TAK | NIE → TAK |
|
||||
|
||||
#### Coroutines — async w Unity (C#)
|
||||
|
||||
// Unity — coroutine = non-blocking wystrzelenie, yield = wait
|
||||
IEnumerator SpawnWave() {
|
||||
for (int i = 0; i < 50; i++) {
|
||||
_bulletPool.Get(); // ← „MPI_Isend" — fire & forget
|
||||
yield return new WaitForSeconds(0.05f); // ← „MPI_Wait" — oddaj sterowanie
|
||||
}
|
||||
}
|
||||
|
||||
// Unity — async/await (nowsze API)
|
||||
async Task LoadLevel() {
|
||||
var op = SceneManager.LoadSceneAsync("Level2"); // ← Irecv
|
||||
while (!op.isDone) { await Task.Yield(); } // ← Wait(request)
|
||||
}
|
||||
|
||||
// Unreal — C++ Latent Action
|
||||
void AMyActor::LoadLevel() {
|
||||
UGameplayStatics::OpenLevelBySoftObjectPtr(this, LevelRef);
|
||||
// Latent node w Blueprintach = "Isend + callback"
|
||||
}
|
||||
|
||||
#### Deadlock w silnikach gier — realny scenariusz
|
||||
|
||||
CPU: „Czekam aż GPU skończy renderowanie klatki N" // ← Ssend
|
||||
GPU: „Czekam aż CPU prześle dane klatki N+1" // ← Ssend
|
||||
→ DEADLOCK! (Send-Send pattern z MPI)
|
||||
|
||||
Rozwiązanie: Triple Buffering = pipeline
|
||||
CPU pracuje na klatce N+2, GPU renderuje N, wyświetla N-1
|
||||
→ „MPI_Sendrecv" — jednoczesne nadawanie i odbieranie
|
||||
|
||||
#### Frame pipeline — sync vs async comparison
|
||||
|
||||
| Podejście | Frame time | CPU utilization | GPU idle |
|
||||
|-----------|-----------|-----------------|----------|
|
||||
| Sync (`glFinish` co klatkę) | 25 ms | 40% (czeka na GPU) | 30% |
|
||||
| Async (triple buffer) | 16 ms | 85% | 10% |
|
||||
| Unity default (double buffer) | 18 ms | 70% | 15% |
|
||||
| Unreal RHI thread (3 klatki pipeline) | 14 ms | 90% | 5% |
|
||||
|
||||
#### Mnemonik — „GFCA" = GPU-Fence Coroutine Async
|
||||
|
||||
- **G**PU fence = `MPI_Ssend` (blokuj aż GPU skończy)
|
||||
- **F**lush = `MPI_Send` (wyślij i idź dalej)
|
||||
- **C**oroutine = `Isend` + later `Wait` (yield = oddaj, resume = sprawdź)
|
||||
- **A**sync readback = `Irecv` + `Wait` (nie blokuj GPU pipeline)
|
||||
|
||||
Na obronie: *„W mojej pracy komunikacja CPU↔GPU to bezpośrednia analogia do MPI — glFinish to synchroniczny Ssend, triple buffering to pipeline z Isend/Irecv, a Unity coroutines to 'fire and forget' z późniejszym Wait. Nsight pokazuje, że async pipeline (Unreal RHI thread) daje ~30% lepsze CPU utilization niż synchroniczny submit."*
|
||||
|
||||
---
|
||||
|
||||
### Etymologia
|
||||
|
||||
**MPI** — Message Passing Interface (MPI Forum, 1994); standard komunikacji w obliczeniach równoległych. **Jacobi** — Carl Gustav Jacob Jacobi (1804–1851, mat. niemiecki); metoda iteracyjna rozwiązywania układów równań. **Synchroniczna** — grec. „syn" (razem) + „chronos" (czas) = w tym samym czasie. **Asynchroniczna** — grec. „a-" (nie) + synchronous = nie w tym samym czasie. **Blokująca** — funkcja „blokuje" wątek aż operacja się skończy.
|
||||
|
||||
@ -344,3 +344,34 @@ Przykład ryzyka: „Z 60% szansą zysk 100 zł, z 40% strata 50 zł." Przykład
|
||||
- **Hurwicz = „huśtawka — α pomiędzy"** → α·max + (1−α)·min, kręcisz pokrętłem optymizmu
|
||||
- **Savage = „szał żalu → min max żalu"** → macierz żalu → minimalizuj maksymalny żal (trzymaj żal na smyczy)
|
||||
|
||||
---
|
||||
|
||||
### 📚 Odniesienia do publikacji z Katedry
|
||||
|
||||
> Poniższe notatki pochodzą z publikacji promotorów/recenzentów i mogą być przydatne jako dodatkowy kontekst na obronie. Temat „decyzje w warunkach ryzyka" bezpośrednio wiąże się z badaniami nad błędami poznawczymi w podejmowaniu decyzji architektonicznych.
|
||||
|
||||
**Borowa — „Cognitive Biases in Architectural Decision-Making: Impact and Debiasing Strategies" (rozprawa doktorska, PW 2024):**
|
||||
- **Dual Process Theory (Kahneman):** System 1 (szybki, intuicyjny, podatny na biasy) vs System 2 (wolny, analityczny, racjonalny) — framework wyjaśniający DLACZEGO decydenci popełniają systematyczne błędy
|
||||
- **11 cognitive biases** w decyzjach: zakotwiczenie (anchoring), potwierdzenie (confirmation), optymizm, efekt ramowania (framing), efekt IKEA, bandwagon, prawo trywialności Parkinsona, klątwa wiedzy, irracjonalna eskalacja, prawo instrumentu, planistyczny optymizm
|
||||
- **„Wicked Triad"** — zakotwiczenie → potwierdzenie → optymizm = łańcuchowa reakcja błędów w podejmowaniu decyzji
|
||||
- Związek z pytaniem: klasyczne kryteria decyzyjne (Laplace, Wald, Hurwicz, Savage) zakładają **racjonalnego decydenta** — badania Borowej pokazują, że ludzie NIE są racjonalni i systematycznie odchylają oceny ryzyka
|
||||
- **Optimism bias** analogiczny do kryterium maximax — decydent przecenia korzystne wyniki, ignoruje ryzyka
|
||||
- **Anchoring** — decydent „zakotwicza się" na pierwszej informacji (np. pierwszej szacowanej wartości) i niewystarczająco koryguje
|
||||
|
||||
**Borowa, Zalewski — „Is knowledge the key? An experiment on debiasing architectural decision-making — a pilot study" (PROFES 2021):**
|
||||
- Pytanie badawcze: czy **samo nauczenie o biasach** wystarcza do ich redukcji?
|
||||
- Wynik pilotażu: wiedza o biasach poprawia jakość argumentów, ale NIE eliminuje samych biasów
|
||||
- Implikacja dla wspomagania decyzji: interaktywne metody (jak w pytaniu) mogą być skuteczniejsze niż pasywna edukacja, bo wymuszają aktywne przetwarzanie
|
||||
|
||||
**Borowa, Zalewski, Kijas — „Debiasing architectural decision-making: a workshop-based training approach" (ECSA 2022):**
|
||||
- **Interwencja C-level Fischhoffa** — 3 techniki debiasujące:
|
||||
1. Rozważ wiele opcji (analogia: metoda interaktywna generuje alternatywy krok po kroku)
|
||||
2. Wypisz wady wybranego rozwiązania (analogia: analiza wrażliwości w metodach decyzyjnych)
|
||||
3. Wypisz ryzyka (analogia: warunki ryzyka — jawna identyfikacja stanów natury i prawdopodobieństw)
|
||||
- Techniki te są formą **interaktywnego wspomagania decyzji** — analityk/narzędzie prowadzi decydenta przez ustrukturyzowany dialog
|
||||
|
||||
**Borowa, Zalewski, Kijas — „Debiasing architectural decision-making: An experiment with students and practitioners" (ECSA 2024):**
|
||||
- Eksperyment z **18 praktykami** (Polska, Niemcy, Brazylia) — statystycznie istotny wzrost kontrargumentów (p=0.0449) i techniki wielu rozwiązań (p=0.029)
|
||||
- **Studenci vs praktycy**: studenci poprawiają jakość argumentów, ale liczba biasów stabilna; praktycy osiągają rzeczywistą redukcję biasów
|
||||
- 4 sugestie dydaktyczne: (1) nacisk na jakość kontrargumentów, (2) włączenie wszystkich poziomów seniorności, (3) ostrzeganie osób o wysokiej pewności siebie, (4) ograniczenie liczby decyzji na sesję
|
||||
|
||||
|
||||