- Qrafı qonşuluq matrisi və ya qonşuluq siyahısı ilə təsvir etmək və seçimi əsaslandırmaq
- BFS, DFS və Deykstra alqoritmlərini əl ilə izləmək
- Topoloji sıra və minimal örtücü ağac tapmaq
Naviqator Bakıdan Şəkiyə ən qısa yolu saniyədə tapır, sosial şəbəkə «tanıya biləcəyin insanları» təklif edir, universitet isə fənlərin ardıcıllığını elə qurur ki, heç kim «Alqoritmlər»ə «Proqramlaşdırma»dan əvvəl yazılmasın. Üç fərqli məsələ, bir model: qraf. Qraf obyektləri (təpələri) və onlar arasındakı əlaqələri (tilləri) təsvir edir və informatikanın ən çox işlədilən modellərindəndir.
Qraflar və onların təsviri
V təpələr çoxluğu və E tillər (təpə cütləri) çoxluğu. Tillər istiqamətsiz (dostluq) və ya istiqamətlənmiş (A → B, «izləyir») ola bilər; hər tilin çəkisi (məsafə, qiymət, vaxt) varsa, qraf çəkili adlanır. Təpənin dərəcəsi ona bitişik tillərin sayıdır.
- deg(v)v təpəsinin dərəcəsi
- |V|, |E|təpələrin və tillərin sayı
«Əl sıxma lemması»: hər istiqamətsiz til iki ucunda iki dərəcə verir. İkinci bərabərsizlik sadə istiqamətsiz qrafda tillərin maksimal sayıdır.
| Xassə | Qonşuluq matrisi | Qonşuluq siyahıları |
|---|---|---|
| yaddaş | O(V²) | O(V + E) |
| (u, v) tili varmı? | O(1) | O(deg u) |
| u-nun bütün qonşularını gəzmək | O(V) | O(deg u) |
| nə vaxt seçilir | sıx qraf (E ≈ V²) | seyrək qraf (yollar, sosial şəbəkələr) |
Dərs boyu bir nümunə qrafdan istifadə edəcəyik. Altı təpə A–F və çəkili istiqamətsiz tillər: A–B 4, A–C 2, B–C 1, B–D 5, C–D 8, C–E 10, D–E 2, D–F 6, E–F 3. Çəkiləri kilometr kimi təsəvvür et.
Eninə (BFS) və dərininə (DFS) axtarış
BFS başlanğıc təpədən «dalğa» kimi yayılır: əvvəl bütün qonşular, sonra qonşuların qonşuları. Bunun üçün növbə işlədilir və nəticədə çəkisiz qrafda ən az til sayı ilə ən qısa yollar alınır. DFS isə bir yol ilə mümkün qədər dərinə gedir, dalana çatanda geri qayıdır; o, stek (və ya rekursiya) ilə işləyir və əlaqəlilik, dövrlərin tapılması və topoloji çeşidləmə üçün istifadə olunur. Hər ikisi hər təpəyə və hər tilə bir dəfə baxır: O(V + E).
Çəkiləri nəzərə almadan nümunə qrafda F-dən BFS və DFS apar. Qonşuları əlifba sırası ilə götür: A: B, C; B: A, C, D; C: A, B, D, E; D: B, C, E, F; E: C, D, F; F: D, E.
Həllini göstərHəllini gizlət
Səviyyələr: F | D, E | B, C | A.
DFS (rekursiya): F → D (F-in ilk qonşusu) → B (D-nin ilk ziyarət olunmamış qonşusu) → A → C (A-nın qonşusu) → E (C-nin ziyarət olunmamış qonşusu).
Sıra: F, D, B, A, C, E — DFS A-ya 4 addımla çatdı, BFS isə ən qısa yolu (3 til) tapdı.
from collections import deque
graph = {'A': ['B', 'C'], 'B': ['A', 'C', 'D'], 'C': ['A', 'B', 'D', 'E'],
'D': ['B', 'C', 'E', 'F'], 'E': ['C', 'D', 'F'], 'F': ['D', 'E']}
def bfs(start):
dist = {start: 0}
queue = deque([start])
while queue:
v = queue.popleft()
for w in graph[v]:
if w not in dist:
dist[w] = dist[v] + 1
queue.append(w)
return dist
def dfs(v, seen):
seen.append(v)
for w in graph[v]:
if w not in seen:
dfs(w, seen)
return seen
print('BFS from F:', bfs('F'))
print('DFS from F:', dfs('F', []))▸ Gözlənilən nəticə
BFS from F: {'F': 0, 'D': 1, 'E': 1, 'B': 2, 'C': 2, 'A': 3}
DFS from F: ['F', 'D', 'B', 'A', 'C', 'E']Deykstra alqoritmi: çəkili ən qısa yollar
Tillərin çəkisi olanda BFS yaramır: 3 qısa til bir uzun tildən ucuz ola bilər. Deykstra alqoritmi (mənfi olmayan çəkilər üçün) hər addımda hələ qəti olmayan təpələr arasından məsafəsi ən kiçik olanı seçir (prioritet növbəsi), onu qəti elan edir və qonşularının məsafələrini relaksasiya ilə yeniləyir.
- dist[v]mənbədən v-yə indiyədək tapılmış ən qısa məsafə
- w(u, v)u–v tilinin çəkisi (≥ 0)
- Tikili yığınla iş vaxtı
| Addım: qəti olan | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 0: başlanğıc | 0 | ∞ | ∞ | ∞ | ∞ | ∞ |
| 1: A (0) | 0 | 4 | 2 | ∞ | ∞ | ∞ |
| 2: C (2) | 0 | 3 | 2 | 10 | 12 | ∞ |
| 3: B (3) | 0 | 3 | 2 | 8 | 12 | ∞ |
| 4: D (8) | 0 | 3 | 2 | 8 | 10 | 14 |
| 5: E (10) | 0 | 3 | 2 | 8 | 10 | 13 |
| 6: F (13) | 0 | 3 | 2 | 8 | 10 | 13 |
Cədvələ əsasən A-dan F-ə ən qısa yolu və onun uzunluğunu tap.
Həllini göstərHəllini gizlət
Sondan geriyə: F ← E ← D ← B ← C ← A.
Yol: A → C → B → D → E → F, uzunluq 2 + 1 + 5 + 2 + 3 = 13.
Diqqət: birbaşa görünən A → B → D → F yolu 4 + 5 + 6 = 15-dir.
import heapq
edges = [('A', 'B', 4), ('A', 'C', 2), ('B', 'C', 1), ('B', 'D', 5), ('C', 'D', 8),
('C', 'E', 10), ('D', 'E', 2), ('D', 'F', 6), ('E', 'F', 3)]
adj = {}
for u, v, w in edges:
adj.setdefault(u, []).append((v, w))
adj.setdefault(v, []).append((u, w))
def dijkstra(src):
dist, prev, pq = {src: 0}, {}, [(0, src)]
while pq:
d, u = heapq.heappop(pq)
if d > dist[u]:
continue
for v, w in adj[u]:
if d + w < dist.get(v, float('inf')):
dist[v], prev[v] = d + w, u
heapq.heappush(pq, (d + w, v))
return dist, prev
dist, prev = dijkstra('A')
path = ['F']
while path[-1] != 'A':
path.append(prev[path[-1]])
print(dict(sorted(dist.items())))
print(' -> '.join(reversed(path)), '=', dist['F'])▸ Gözlənilən nəticə
{'A': 0, 'B': 3, 'C': 2, 'D': 8, 'E': 10, 'F': 13}
A -> C -> B -> D -> E -> F = 13heapq prioritet növbəsi rolunu oynayır. Təpə növbəyə bir neçə dəfə düşə bilər; köhnəlmiş qeydləri d > dist[u] şərti atır («tənbəl silmə»).Topoloji çeşidləmə və minimal örtücü ağac
Topoloji çeşidləmə istiqamətlənmiş dövrsüz qrafın (DAG) təpələrini elə düzür ki, hər u → v tili üçün u v-dən əvvəl gəlsin: fənlərin ardıcıllığı, proqram modullarının yığılma sırası, Excel-də xanaların hesablanma sırası. Kan alqoritmi: daxil olan dərəcəsi 0 olan təpələri növbəyə qoy, birini çıxar, onun tillərini sil və dərəcəsi 0-a enən təpələri növbəyə əlavə et. Nəticədə V-dən az təpə çıxırsa, qrafda dövr var. Vaxt: O(V + E).
from collections import deque
courses = {'Programming': ['DataStructures', 'Databases'], 'Math': ['Algorithms'],
'DataStructures': ['Algorithms'], 'Databases': ['AI'],
'Algorithms': ['AI'], 'AI': []}
def topo_sort(g):
indeg = {v: 0 for v in g}
for v in g:
for w in g[v]:
indeg[w] += 1
queue = deque(v for v in g if indeg[v] == 0)
order = []
while queue:
v = queue.popleft()
order.append(v)
for w in g[v]:
indeg[w] -= 1
if indeg[w] == 0:
queue.append(w)
return order if len(order) == len(g) else None
print(topo_sort(courses))
print(topo_sort({'X': ['Y'], 'Y': ['Z'], 'Z': ['X']}))▸ Gözlənilən nəticə
['Programming', 'Math', 'DataStructures', 'Databases', 'Algorithms', 'AI'] None
None qaytarılır — belə tələblərlə heç bir fənnə başlamaq mümkün deyil.Əlaqəli çəkili qrafın bütün təpələrini birləşdirən, dövrü olmayan və tillərinin çəkiləri cəmi ən kiçik olan tillər çoxluğu. Onun həmişə düz V − 1 tili olur. Tətbiq: kəndləri ən az kabel ilə birləşdirmək, elektrik və su şəbəkələrinin layihələndirilməsi, klasterləşmə.
Nümunə qrafın minimal örtücü ağacını Kruskal alqoritmi ilə tap: tilləri çəkiyə görə artan sıra ilə götür və dövr yaratmayanları seç.
Həllini göstərHəllini gizlət
B–C 1 ✓ → {B, C}
A–C 2 ✓ → {A, B, C}
D–E 2 ✓ → {D, E}
E–F 3 ✓ → {D, E, F}
A–B 4 ✗ — A və B artıq eyni komponentdədir (A–C–B dövrü yaranardı)
B–D 5 ✓ → bütün təpələr birləşdi; 5 = V − 1 til, dayanırıq.
MST: {B–C, A–C, D–E, E–F, B–D}, ümumi çəki 1 + 2 + 2 + 3 + 5 = 13.
edges = [('A', 'B', 4), ('A', 'C', 2), ('B', 'C', 1), ('B', 'D', 5), ('C', 'D', 8),
('C', 'E', 10), ('D', 'E', 2), ('D', 'F', 6), ('E', 'F', 3)]
parent = {v: v for v in 'ABCDEF'}
def find(v):
while parent[v] != v:
v = parent[v]
return v
mst = []
for u, v, w in sorted(edges, key=lambda e: e[2]):
ru, rv = find(u), find(v)
if ru != rv:
parent[ru] = rv
mst.append((u, v, w))
print(mst)
print('total weight:', sum(w for _, _, w in mst))▸ Gözlənilən nəticə
[('B', 'C', 1), ('A', 'C', 2), ('D', 'E', 2), ('E', 'F', 3), ('B', 'D', 5)]
total weight: 13find komponentin «başçısını» tapır, iki təpənin başçısı eynidirsə, til dövr yaradar. Kruskalın vaxtı çeşidləmə ilə müəyyən olunur: O(E log E). Prim alqoritmi isə ağacı bir təpədən böyüdür (Deykstraya bənzər, prioritet növbəsi ilə).Əsas fikirlər
- Qraf G = (V, E); seyrək qraf üçün qonşuluq siyahısı (O(V + E)), sıx qraf üçün matris (O(V²)).
- BFS növbə ilə səviyyə-səviyyə gedir və çəkisiz ən qısa yolları verir; DFS stek ilə dərinə gedir; hər ikisi O(V + E).
- Deykstra mənfi olmayan çəkilərlə prioritet növbəsi və relaksasiya ilə O((V + E) log V) vaxtda işləyir.
- Topoloji sıra yalnız DAG-da mövcuddur; Kan alqoritmi dövrü də aşkar edir.
- MST-nin V − 1 tili var; Kruskal tilləri çəkiyə görə düzür və union–find ilə dövrlərdən qaçır.
Özünü yoxla
10 sual. Hər düzgün cavab XP qazandırır.