← คู่มือ Mesh Networking — สื่อสารในที่ที่ไม่มีเสาสัญญาณ
LEVEL 1 · พื้นฐานที่ใช้ทุกวัน
เส้นทางสั้นที่สุด ไม่ใช่เส้นทางที่ดีที่สุด
ตอนนี้ทุกโหนดรู้จักเพื่อนบ้านและรู้ค่า ETX ของลิงก์รอบตัวแล้ว ถึงเวลาแปลงมันเป็นเส้นทาง
6.1 อัลกอริทึมเก่าแก่ที่ยังใช้อยู่
การหาเส้นทางถูกที่สุดในกราฟมีคำตอบตั้งแต่ปี 1959 ชื่อ Dijkstra หลักการคือค่อย ๆ ขยายวงจากต้นทาง เลือกโหนดที่ไปถึงได้ถูกที่สุดก่อนเสมอ แล้วอัปเดตเพื่อนบ้านของมัน
จุดสำคัญไม่ได้อยู่ที่ตัวอัลกอริทึม แต่อยู่ที่ น้ำหนักที่ใส่เข้าไป — เปลี่ยนน้ำหนัก คำตอบเปลี่ยนทันที ทั้งที่โค้ดเหมือนเดิมทุกบรรทัด
6.2 พิสูจน์ด้วยตาเอง
import heapq
# ลิงก์ (u, v, ETX) — ค่ามาจากการวัดแบบบทที่ 4
LINKS = [("A","C",2.10), ("C","F",2.10), # เส้นตรง 2 hop ผ่านย่านที่คนใช้เยอะ
("A","D",1.14), ("D","B",1.20), ("B","F",1.10)] # เส้นอ้อม 3 hop ลิงก์ดีทุกเส้น
def dijkstra(links, src):
g = {}
for u, v, w in links:
g.setdefault(u, []).append((v, w))
g.setdefault(v, []).append((u, w))
dist = {src: 0.0}; prev = {}; pq = [(0.0, src)]
while pq:
d, u = heapq.heappop(pq)
if d > dist.get(u, float("inf")): continue
for v, w in g.get(u, []):
nd = d + w
if nd < dist.get(v, float("inf")):
dist[v] = nd; prev[v] = u; heapq.heappush(pq, (nd, v))
return dist, prev
def path(prev, dst):
out = [dst]
while dst in prev:
dst = prev[dst]; out.append(dst)
return " -> ".join(reversed(out))
dist, prev = dijkstra(LINKS, "A")
best = path(prev, "F"); hops = best.count("->")
short, chosen = (2.10+2.10)*100, dist["F"]*100
print(f" ถ้านับ hop : A -> C -> F 2 hop ETX รวม {2.10+2.10:.2f}")
print(f" ถ้านับ ETX : {best} {hops} hop ETX รวม {dist['F']:.2f}")
print(f" ส่ง 100 ชิ้น: เส้น 2 hop = {short:.0f} ครั้ง · เส้น {hops} hop = {chosen:.0f} ครั้ง"
f" ประหยัดกว่า {(1-chosen/short)*100:.0f}%")ผลรันจริง
ถ้านับ hop : A -> C -> F 2 hop ETX รวม 4.20
ถ้านับ ETX : A -> D -> B -> F 3 hop ETX รวม 3.44
ส่ง 100 ชิ้น: เส้น 2 hop = 420 ครั้ง · เส้น 3 hop = 344 ครั้ง ประหยัดกว่า 18%เส้นทางที่ยาวกว่าหนึ่ง hop ใช้การออกอากาศน้อยกว่า 76 ครั้งต่อข้อมูล 100 ชิ้น นี่คือคำตอบเต็มของปริศนาที่ปลูกไว้ตั้งแต่บทที่ 1 — และเหตุผลที่โปรโตคอลเมชรุ่นแรก ๆ ที่นับ hop อย่างเดียวถึงทำงานได้แย่ในสนามจริงจนต้องถูกแทนที่
6.3 ทำไมการบวกถึงถูกต้องตามความหมาย
การเอาค่ามาบวกกันข้าม hop ฟังดูเป็นเรื่องเทคนิค แต่มันมีความหมายทางกายภาพจริง
ETX ของหนึ่งลิงก์ = จำนวนครั้งที่คาดว่าต้องออกอากาศเพื่อให้ผ่านลิงก์นั้นสำเร็จหนึ่งครั้ง ⇒ ผลรวมของทั้งเส้นทาง = จำนวนครั้งที่ต้องออกอากาศรวมทั้งเส้น ซึ่งเป็นสิ่งที่เราอยากประหยัดจริง ๆ เพราะทุกครั้งที่ออกอากาศคือการกินอากาศที่คนอื่นต้องใช้ และกินแบตที่มีจำกัด
เทียบกับการนับ hop ที่บวกได้เหมือนกัน แต่ผลรวมไม่ได้แปลว่าอะไรเลยนอกจาก "จำนวนเครื่องที่แตะข้อมูลนี้"