লিংক স্টেট রাউটিং — OSPF
এই পাঠে যা শিখবেন
- লিংক স্টেট রাউটিং-এর মূল ধারণা ও ডিসট্যান্স ভেক্টরের সাথে দার্শনিক পার্থক্য
- OSPF প্রোটোকলের সুবিধা — কেন এটি দ্রুত ও নির্ভরযোগ্যভাবে কনভার্জ করে
- Dijkstra-এর শর্টেস্ট-পাথ অ্যালগরিদম কীভাবে কাজ করে, ধাপে ধাপে
- Python দিয়ে একটি সত্যিকারের, hand-verified Dijkstra বাস্তবায়ন ও পরীক্ষা
১ · লিংক স্টেট রাউটিং — সম্পূর্ণ ভিন্ন একটি দর্শন
L18-এ আমরা দেখেছি ডিসট্যান্স ভেক্টর রাউটিং-এ প্রতিটি রাউটার শুধু প্রতিবেশীদের সাথে কথা বলে, পুরো নেটওয়ার্কের মানচিত্র কখনো জানে না। লিংক স্টেট রাউটিংLink State Routingএকটি রাউটিং কৌশল যেখানে প্রতিটি রাউটার তার নিজের লিংক তথ্য পুরো নেটওয়ার্কে ফ্লাড করে, যাতে প্রতিটি রাউটার সম্পূর্ণ টপোলজি জেনে স্বাধীনভাবে শর্টেস্ট পাথ হিসাব করতে পারে। এর সম্পূর্ণ উল্টো পথ নেয় — প্রতিটি রাউটার প্রথমে নিজের সরাসরি-সংযুক্ত লিংক ও তাদের খরচ আবিষ্কার করে, তারপর এই তথ্য প্রতিবেশীদের কাছে নয়, পুরো নেটওয়ার্কের প্রতিটি রাউটারের কাছে ফ্লাড করে। ফলাফল — প্রতিটি রাউটারের কাছে পুরো নেটওয়ার্ক টপোলজির একটি অভিন্ন, সম্পূর্ণ মানচিত্র থাকে। এরপর প্রতিটি রাউটার স্বাধীনভাবে (কারো উপর নির্ভর না করে) নিজের থেকে বাকি সবার কাছে শর্টেস্ট পাথ হিসাব করে — এই হিসাবের জন্য ব্যবহৃত হয় Dijkstra-এর অ্যালগরিদম।
শুধু প্রতিবেশীর সাথে তথ্য শেয়ার, আংশিক দৃষ্টিভঙ্গি, Bellman-Ford ব্যবহার করে।
পুরো নেটওয়ার্কে তথ্য ফ্লাড, সম্পূর্ণ মানচিত্র, Dijkstra ব্যবহার করে।
২ · OSPF (Open Shortest Path First)
OSPF হলো স্ট্যান্ডার্ড লিংক-স্টেট প্রোটোকল, ব্যাপকভাবে বড় প্রতিষ্ঠানের নেটওয়ার্কে ব্যবহৃত হয়। যেহেতু প্রতিটি রাউটার সম্পূর্ণ, সামঞ্জস্যপূর্ণ টপোলজি তথ্য থেকে স্বাধীনভাবে হিসাব করে (প্রতিবেশীর সম্ভাব্য পুরনো/ভুল তথ্যের উপর নির্ভর না করে), OSPF L18-এর count-to-infinity সমস্যা এড়িয়ে যায় এবং টপোলজি বদলের পর দ্রুত কনভার্জ করে।
লিংক স্টেট রাউটিং-এর দাম আছে — প্রতিটি রাউটারকে পুরো টপোলজি মেমরিতে রাখতে হয় (ডিসট্যান্স ভেক্টরের চেয়ে বেশি মেমরি) এবং প্রতিটি রাউটারকে নিজে Dijkstra চালাতে হয় (বেশি CPU হিসাব)। কিন্তু বিনিময়ে পাওয়া যায় দ্রুত কনভার্জেন্স ও অনেক বেশি নির্ভরযোগ্যতা — বড় নেটওয়ার্কে এই ট্রেড-অফ প্রায় সবসময় লাভজনক।
৩ · Dijkstra-এর অ্যালগরিদম — কীভাবে কাজ করে
লক্ষ্য: একটি উৎস (source) রাউটার থেকে নেটওয়ার্কের বাকি সব রাউটারে সর্বনিম্ন-খরচের পথ বের করা। মূল ধারণা — প্রতি ধাপে, এখনো "চূড়ান্ত নয়" এমন রাউটারগুলোর মধ্যে সবচেয়ে কম দূরত্বেরটি বেছে নাও, সেটিকে "চূড়ান্ত" ঘোষণা করো, তারপর তার প্রতিবেশীদের দূরত্ব আপডেট করো (যদি এই রাউটার হয়ে যাওয়া পথ আগের চেয়ে সস্তা হয়) — এভাবে সব রাউটার চূড়ান্ত না হওয়া পর্যন্ত চলতে থাকে।
# Dijkstra-এর শর্টেস্ট-পাথ অ্যালগরিদম — সম্পূর্ণ, সঠিক বাস্তবায়ন
import heapq
# নেটওয়ার্ক টপোলজি: রাউটারদের মধ্যে লিংক ও তাদের খরচ (OSPF-এ যেমন "cost" মেট্রিক)
graph = {
"A": {"B": 2, "C": 5},
"B": {"A": 2, "C": 1, "D": 4},
"C": {"A": 5, "B": 1, "D": 1, "E": 3},
"D": {"B": 4, "C": 1, "E": 1},
"E": {"C": 3, "D": 1},
}
def dijkstra(graph, source):
dist = {node: float("inf") for node in graph}
prev = {node: None for node in graph}
dist[source] = 0
visited = set()
pq = [(0, source)]
while pq:
d, u = heapq.heappop(pq)
if u in visited:
continue
visited.add(u)
for neighbor, weight in graph[u].items():
new_dist = d + weight
if new_dist < dist[neighbor]:
dist[neighbor] = new_dist
prev[neighbor] = u
heapq.heappush(pq, (new_dist, neighbor))
return dist, prev
def build_path(prev, target):
path = []
node = target
while node is not None:
path.append(node)
node = prev[node]
path.reverse()
return path
source = "A"
distances, previous = dijkstra(graph, source)
print(f"'{source}' থেকে প্রতিটি রাউটারে সর্বনিম্ন-খরচের পথ —\n")
for node in graph:
path = build_path(previous, node)
print(f" {source} -> {node}: খরচ = {distances[node]:<3} পথ = {' -> '.join(path)}")
# --- স্ব-যাচাই: hand-trace করে যাচাই করা প্রত্যাশিত মান ---
expected = {"A": 0, "B": 2, "C": 3, "D": 4, "E": 5}
assert distances == expected, f"Dijkstra-এর ফলাফল প্রত্যাশিত মানের সাথে মেলেনি! পাওয়া গেছে: {distances}"
assert build_path(previous, "E") == ["A", "B", "C", "D", "E"], "E পর্যন্ত শর্টেস্ট পাথ ভুল!"
print("\nস্ব-যাচাই পাস — লক্ষ্য করুন সরাসরি A-C লিংকের খরচ ৫ হলেও,")
print("A-B-C পথের খরচ মাত্র ৩ — তাই C-তে পৌঁছানোর প্রকৃত শর্টেস্ট পাথ B হয়ে যায়, সরাসরি লিংক দিয়ে নয়।")
A থেকে C-এ সরাসরি লিংকের খরচ ৫, কিন্তু প্রকৃত শর্টেস্ট
পাথ A-B-C (খরচ ২+১=৩), সরাসরি লিংকের চেয়ে সস্তা। Dijkstra ঠিক এই কারণেই দরকার — শুধু সরাসরি সংযোগ
দেখলে ভুল সিদ্ধান্ত হতো। এই মানগুলো কোনো hand-derived অনুমান নয় — উপরের কোড সত্যিই এগুলো হিসাব করে assert
দিয়ে নিজেই যাচাই করেছে।
লিংক স্টেট রাউটিং-এ প্রতিটি রাউটার "নিজে নিজে ভাবে," কিন্তু সবাই একই (সম্পূর্ণ, সামঞ্জস্যপূর্ণ) তথ্য থেকে ভাবে — তাই তাদের সিদ্ধান্ত সবসময় সামঞ্জস্যপূর্ণ থাকে, ডিসট্যান্স ভেক্টরের মতো ধীরে ধীরে ভুল তথ্য ছড়ানোর ঝুঁকি ছাড়াই। M4/L20-এ আমরা দেখব কেন এই দুটি প্রোটোকলই (RIP, OSPF) শুধু একটি প্রতিষ্ঠানের ভেতরে কাজ করে, আর প্রতিষ্ঠানগুলোর মধ্যে সংযোগের জন্য সম্পূর্ণ ভিন্ন একটি প্রোটোকল — BGP — দরকার হয়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ লিংক স্টেট রাউটিং কীভাবে count-to-infinity সমস্যা (L18) সম্পূর্ণভাবে এড়িয়ে যায়?
Count-to-infinity সমস্যা হয় কারণ ডিসট্যান্স ভেক্টর রাউটাররা একে অপরের (সম্ভবত পুরনো/ভুল) দূরত্বের দাবির উপর ভরসা করে, ধাপে ধাপে। লিংক স্টেটে, প্রতিটি রাউটার নিজে সরাসরি জানে কোন লিংক আছে/নেই (নিজের ফ্লাড করা তথ্য থেকে), এবং সম্পূর্ণ টপোলজি থেকে নিজে Dijkstra চালায় — কারো "দূরত্বের দাবি"-র উপর নির্ভর করার দরকার নেই। তাই ভুল তথ্য ধাপে ধাপে বাড়তে থাকার কোনো সুযোগ নেই।
প্র ০২ কেন প্রতিটি রাউটার নিজে থেকে Dijkstra চালায়, একজন কেন্দ্রীয় "নেটওয়ার্ক ম্যানেজার" কেন হিসাব করে দেয় না?
একটি কেন্দ্রীয় ম্যানেজার একক ব্যর্থতার বিন্দু (single point of failure) হয়ে যেত — সে ব্যর্থ হলে পুরো নেটওয়ার্ক রাউটিং করতে পারত না (L01-এর ক্লায়েন্ট-সার্ভার বনাম বিকেন্দ্রীভূত মডেলের একই আলোচনা মনে করুন)। প্রতিটি রাউটার নিজে হিসাব করলে সিস্টেমটি বিকেন্দ্রীভূত ও ফল্ট-টলারেন্ট থাকে — যেকোনো একটি রাউটার ব্যর্থ হলেও বাকিরা স্বাধীনভাবে কাজ চালিয়ে যেতে পারে।
প্র ০৩
উপরের কোডে যদি A-C লিংকের খরচ ৫-এর বদলে ২ করা হতো, তাহলে A-থেকে-C-এর শর্টেস্ট পাথ কী হতো?
তাহলে সরাসরি লিংক (খরচ ২) এবং A-B-C পথ (খরচ ২+১=৩) দুটোই বিবেচনায় আসত, আর সরাসরি লিংকই জিততো
(২ < ৩)। Dijkstra সবসময় প্রকৃত সংখ্যাসূচক খরচ তুলনা করে সিদ্ধান্ত নেয় — কোনো পথ "সরাসরি" না "ঘুরপথ" তা
বিবেচ্য নয়, শুধু মোট খরচটাই গুরুত্বপূর্ণ।
অনুশীলন
-
চিন্তা করুন: উপরের গ্রাফে
AথেকেD-এ পৌঁছানোর জন্য কোন পথটি ব্যবহৃত হবে, এবং কেনA-C-Dপথ (খরচ ৫+১=৬) ব্যবহৃত হয় না?ব্যবহৃত পথ হবে
A-B-C-D(খরচ ২+১+১=৪), যাA-C-D-এর ৬-এর চেয়ে সস্তা। Dijkstra সবসময় সর্বনিম্ন মোট খরচের পথ বেছে নেয় — সরাসরি-দেখতে লিংক ব্যবহার করলে সবসময় সবচেয়ে কম হপ বা সবচেয়ে সস্তা পথ হয় না। -
পরীক্ষা করুন: উপরের কোডে
source-এর মান"E"-এ পরিবর্তন করে Run চাপুন এবং দেখুনEথেকেA-এ পৌঁছানোর শর্টেস্ট পাথ ও খরচ কত আসে।যেহেতু গ্রাফটি undirected (দ্বিমুখী লিংক, একই খরচ উভয় দিকে),
EথেকেA-এর শর্টেস্ট পাথ ঠিক আগের পথের উল্টো হবে —E-D-C-B-A, মোট খরচ ৫ (আগের মতোই, যেহেতুAথেকেE-এর খরচও ছিল ৫)। এটি নিশ্চিত করে গ্রাফটি প্রতিসম (symmetric)।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ পরবর্তী পাঠ — BGP ইন্টার-ডোমেইন রাউটিং — প্রতিষ্ঠানগুলোর মধ্যে রাউটিং কীভাবে কাজ করে তা দেখাবে।
- Cloud Computing & DevOps কোর্স সঙ্গী কোর্স ক্লাউড নেটওয়ার্কে রুট অপ্টিমাইজেশন ও লেটেন্সি-ভিত্তিক রাউটিং কীভাবে কাজ করে তা শিখতে দেখুন।
- Data Structures & Algorithms কোর্স সঙ্গী কোর্স Dijkstra ও অন্যান্য শর্টেস্ট-পাথ অ্যালগরিদমের গভীর তাত্ত্বিক বিশ্লেষণ শিখতে দেখুন।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps ও Computer Networks — সব এক জায়গায়।