2026. június 29., hétfő

SIR járványmodell COVID terjedésre

A SIR modell egy alapvető matematikai egyenletrendszer az epidemiológiában, amely a fertőző betegségek terjedését modellezi egy zárt populációban az egyének három csoportba sorolásával: fogékonyak, fertőzöttek és gyógyultak. A populáció teljes létszáma állandó (N = S + I + R) A nyájimmunitás (vagy közösségi immunitás) egy járványügyi fogalom. Azt az állapotot jelenti, amikor a teljes populációnak (vagy egy adott közösségnek) egy bizonyos része már immunis egy adott fertőző betegséggel szemben.A védettség megszerezhető a betegségen való áteséssel (természetes fertőződés) vagy védőoltással.Hogyan akadályozza meg a terjedést?Amikor a lakosság kritikus tömege védetté válik, a kórokozó nem talál elég fogékony gazdatestet a terjedéshez. A fertőzési lánc megszakad, ami közvetett védelmet (pajzsot) biztosít a még védtelen, például oltatlan vagy immunhiányos személyek számára is.
----------------
import numpy as np
import matplotlib.pyplot as plt

print("=" * 70)
print("STOCHASZTIKUS SIR JÁRVÁNYDINAMIKA HÁLÓZATON")
print("Komplex rendszerek – epidemiológiai szimuláció")
print("=" * 70)

# -----------------------------
# PARAMÉTEREK
# -----------------------------
N = 200
p_edge = 0.03
beta = 0.25
gamma = 0.05
T = 300

print(f"Populáció: {N}")
print(f"Kapcsolati valószínűség: {p_edge}")
print(f"Fertőzési ráta β = {beta}")
print(f"Gyógyulási ráta γ = {gamma}")
print(f"Időlépések: {T}")
print("\nInicializálás...")

# -----------------------------
# HÁLÓZAT
# -----------------------------
rng = np.random.default_rng()
adj = [[] for _ in range(N)]
for i in range(N):
    for j in range(i + 1, N):
        if rng.random() < p_edge:
            adj[i].append(j)
            adj[j].append(i)

# állapotok: 0 = S, 1 = I, 2 = R
state = np.zeros(N, dtype=int)

# kezdeti fertőzött
patient_zero = rng.integers(N)
state[patient_zero] = 1

S_hist, I_hist, R_hist = [], [], []

print(f"Nulladik páciens: {patient_zero}")

# -----------------------------
# SZIMULÁCIÓ
# -----------------------------
for t in range(T):
    new_state = state.copy()

    for i in range(N):
        if state[i] == 1:
            if rng.random() < gamma:
                new_state[i] = 2

            for j in adj[i]:
                if state[j] == 0 and rng.random() < beta:
                    new_state[j] = 1

    state = new_state

    S_hist.append(np.sum(state == 0))
    I_hist.append(np.sum(state == 1))
    R_hist.append(np.sum(state == 2))

    if t % 30 == 0:
        print(
            f"t={t:3d} | "
            f"S={S_hist[-1]:3d} "
            f"I={I_hist[-1]:3d} "
            f"R={R_hist[-1]:3d}"
        )

print("\nSzimuláció befejeződött.")

# -----------------------------
# EREDMÉNYEK
# -----------------------------
plt.figure(figsize=(10, 6))

plt.plot(S_hist, label="Fogékony (S)")
plt.plot(I_hist, label="Fertőzött (I)")
plt.plot(R_hist, label="Gyógyult (R)")

plt.xlabel("Idő")
plt.ylabel("Egyének száma")
plt.title("SIR járványdinamika komplex hálózaton")
plt.legend()
plt.grid()
plt.show()

print("\nVÉGEREDMÉNY")
print("-" * 40)
print(f"Max fertőzöttek száma: {max(I_hist)}")
print(f"Utolsó fertőzöttek: {I_hist[-1]}")
print(f"Átfertőzött populáció: {R_hist[-1] / N:.2%}")
--------------------
730 ms
======================================================================
STOCHASZTIKUS SIR JÁRVÁNYDINAMIKA HÁLÓZATON
Komplex rendszerek – epidemiológiai szimuláció
======================================================================
Populáció: 200
Kapcsolati valószínűség: 0.03
Fertőzési ráta β = 0.25
Gyógyulási ráta γ = 0.05
Időlépések: 300

Inicializálás...
Nulladik páciens: 44
t=  0 | S=198 I=  2 R=  0
t= 30 | S=  0 I= 74 R=126
t= 60 | S=  0 I= 17 R=183
t= 90 | S=  0 I=  4 R=196
t=120 | S=  0 I=  0 R=200
t=150 | S=  0 I=  0 R=200
t=180 | S=  0 I=  0 R=200
t=210 | S=  0 I=  0 R=200
t=240 | S=  0 I=  0 R=200
t=270 | S=  0 I=  0 R=200

Szimuláció befejeződött.

VÉGEREDMÉNY
----------------------------------------
Max fertőzöttek száma: 163
Utolsó fertőzöttek: 0
Átfertőzött populáció: 100.00%

A dimanikát leíró differenciál egyenlet;
Értékelés; gráfelméleti hálózaton fut (Erdős–Rényi random graph), sztochasztikus differenciáldinamikát használ, nemlineáris terjedési folyamatot modellez, epidemiológiai alapmodell (COVID, influenza stb. alapja), komplex rendszerek tipikus „küszöbjelenségét” mutatja (epidémia vs. kihalás).eleinte lassú fertőzés, majd exponenciális felfutás, csúcsfertőzési állapot, végül kifutás (immunitás miatt). 

Terjedési modell a fővárosban
-------------------
import numpy as np
import matplotlib.pyplot as plt

print("=" * 70)
print("BUDAPEST VÁROSI KÖZLEKEDÉSI HÁLÓZAT SZIMULÁCIÓ")
print("Önálló gráf-alapú forgalmi terhelés modell")
print("=" * 70)

# -----------------------------
# 1. SZINTETIKUS HÁLÓZAT
# -----------------------------
rng = np.random.default_rng(42)

n_nodes = 120
area_size = 100.0
p_edge = 0.06

coords = rng.uniform(0, area_size, size=(n_nodes, 2))

adj = [[] for _ in range(n_nodes)]
edges = []

for i in range(n_nodes):
    for j in range(i + 1, n_nodes):
        if rng.random() < p_edge:
            dist = np.linalg.norm(coords[i] - coords[j])
            travel_time = dist / 20.0 + rng.uniform(0.1, 1.0)
            adj[i].append((j, travel_time))
            adj[j].append((i, travel_time))
            edges.append((i, j, travel_time))

print(f"Csomópontok száma: {n_nodes}")
print(f"Élek száma: {len(edges)}")

# -----------------------------
# 2. LEGRÖVIDEBB ÚTVONAL DIJKSTRA
# -----------------------------
def shortest_path(start, end):
    import heapq

    dist = [float("inf")] * n_nodes
    prev = [-1] * n_nodes
    dist[start] = 0.0
    pq = [(0.0, start)]

    while pq:
        d, u = heapq.heappop(pq)
        if d != dist[u]:
            continue
        if u == end:
            break
        for v, w in adj[u]:
            nd = d + w
            if nd < dist[v]:
                dist[v] = nd
                prev[v] = u
                heapq.heappush(pq, (nd, v))

    if dist[end] == float("inf"):
        return []

    path = []
    cur = end
    while cur != -1:
        path.append(cur)
        cur = prev[cur]
    return path[::-1]

# -----------------------------
# 3. FORGALMI MODELL
# -----------------------------
flow = {}
for u, v, _ in edges:
    flow[(u, v)] = 0
    flow[(v, u)] = 0

print("\nForgalom szimuláció indul...")

num_trips = 2000
for i in range(num_trips):
    origin = rng.integers(n_nodes)
    dest = rng.integers(n_nodes)

    if origin == dest:
        continue

    path = shortest_path(origin, dest)
    if len(path) < 2:
        continue

    for a, b in zip(path[:-1], path[1:]):
        flow[(a, b)] += 1
        flow[(b, a)] += 1

    if i % 300 == 0:
        print(f"Számolt utak: {i}/{num_trips}")

print("\nSzimuláció befejezve.")

# -----------------------------
# 4. LEGTERHELTEBB ÉLEK
# -----------------------------
edge_list = []
flows = []

for u, v, _ in edges:
    f = flow[(u, v)]
    edge_list.append((u, v))
    flows.append(f)

flows = np.array(flows)

top_idx = np.argsort(flows)[-20:]

print("\nLEGTERHELTEBB ÚTVONALAK (top 20 él):")
for idx in reversed(top_idx):
    u, v = edge_list[idx]
    print(f"{u} → {v} | forgalom: {flows[idx]}")

# -----------------------------
# 5. VIZUALIZÁCIÓ
# -----------------------------
print("\nTérkép generálása...")

plt.figure(figsize=(10, 10))
plt.scatter(coords[:, 0], coords[:, 1], s=10, c="white")

max_flow = flows.max() if flows.size > 0 else 1

for u, v, _ in edges:
    f = flow[(u, v)]
    alpha = 0.05 + 0.9 * (f / (max_flow + 1))
    width = 0.3 + 2.5 * (f / (max_flow + 1))
    plt.plot(
        [coords[u, 0], coords[v, 0]],
        [coords[u, 1], coords[v, 1]],
        color=plt.cm.inferno(f / (max_flow + 1)),
        linewidth=width,
        alpha=alpha
    )

plt.title("Budapest közlekedési hálózat - forgalmi terhelés")
plt.axis("off")
plt.gca().set_facecolor("black")
plt.gcf().patch.set_facecolor("black")
plt.show()

print("\nKész.")
-----------------
946 ms
======================================================================
BUDAPEST VÁROSI KÖZLEKEDÉSI HÁLÓZAT SZIMULÁCIÓ
Önálló gráf-alapú forgalmi terhelés modell
======================================================================
Csomópontok száma: 120
Élek száma: 433

Forgalom szimuláció indul...
Számolt utak: 0/2000
Számolt utak: 300/2000
Számolt utak: 600/2000
Számolt utak: 900/2000
Számolt utak: 1200/2000
Számolt utak: 1500/2000
Számolt utak: 1800/2000

Szimuláció befejezve.

LEGTERHELTEBB ÚTVONALAK (top 20 él):
53 → 70 | forgalom: 70
56 → 85 | forgalom: 62
38 → 85 | forgalom: 57
23 → 70 | forgalom: 57
47 → 59 | forgalom: 56
72 → 82 | forgalom: 55
56 → 72 | forgalom: 52
27 → 58 | forgalom: 48
57 → 80 | forgalom: 48
53 → 55 | forgalom: 48
28 → 46 | forgalom: 47
110 → 115 | forgalom: 47
71 → 109 | forgalom: 47
23 → 30 | forgalom: 46
49 → 54 | forgalom: 45
14 → 56 | forgalom: 44
35 → 85 | forgalom: 42
1 → 58 | forgalom: 42
0 → 30 | forgalom: 41
38 → 57 | forgalom: 41

Kész.

Nincsenek megjegyzések:

Megjegyzés küldése