You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
import random
|
|
import seaborn as sns
|
|
|
|
def plot_spider_web_and_matrix():
|
|
# ==========================================
|
|
# 1. 核心參數 (延用你的設定)
|
|
# ==========================================
|
|
NUM_RINGS = 4
|
|
NUM_SPOKES = 10
|
|
JITTER = 5.0
|
|
HIGH_RISK = 10.0 # F 矩陣中的高風險懲罰值
|
|
|
|
# 生成節點
|
|
nodes = [(50, 50)]
|
|
radii = np.linspace(12, 45, NUM_RINGS)
|
|
angles = np.linspace(0, 2*np.pi, NUM_SPOKES, endpoint=False)
|
|
for r in radii:
|
|
for t in angles:
|
|
x = 50 + r * np.cos(t) + np.random.uniform(-JITTER, JITTER)
|
|
y = 50 + r * np.sin(t) + np.random.uniform(-JITTER, JITTER)
|
|
nodes.append((x, y))
|
|
|
|
N = len(nodes)
|
|
|
|
# 建立連線清單 (Edges)
|
|
edges = []
|
|
for i in range(NUM_SPOKES): edges.append((0, 1 + i)) # 中心連線
|
|
for ring in range(NUM_RINGS - 1): # 輻射線
|
|
for spoke in range(NUM_SPOKES):
|
|
edges.append((1 + ring * NUM_SPOKES + spoke, 1 + (ring + 1) * NUM_SPOKES + spoke))
|
|
for ring in range(NUM_RINGS): # 同心圓
|
|
for spoke in range(NUM_SPOKES):
|
|
u = 1 + ring * NUM_SPOKES + spoke
|
|
v = 1 + ring * NUM_SPOKES + ((spoke + 1) % NUM_SPOKES)
|
|
edges.append((u, v))
|
|
|
|
# ==========================================
|
|
# 2. 核心邏輯:建構擾動矩陣 F
|
|
# ==========================================
|
|
# 初始化:假設所有路徑都是極度危險的 (F=10)
|
|
F = np.full((N, N), HIGH_RISK)
|
|
np.fill_diagonal(F, 0) # 自己到自己沒擾動
|
|
|
|
# 只有在「蜘蛛絲」上的路徑,擾動才設為 0
|
|
for u, v in edges:
|
|
F[u, v] = 0.0
|
|
F[v, u] = 0.0
|
|
|
|
# ==========================================
|
|
# 3. 繪圖與對比
|
|
# ==========================================
|
|
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 8))
|
|
|
|
# --- 左圖:實體蜘蛛網佈局 ---
|
|
ax1.set_facecolor('#2A2A2A')
|
|
for u, v in edges:
|
|
ax1.plot([nodes[u][0], nodes[v][0]], [nodes[u][1], nodes[v][1]],
|
|
color='#E0E0E0', linewidth=1.5, alpha=0.6)
|
|
nx, ny = zip(*nodes)
|
|
ax1.scatter(nx, ny, color='#00FFFF', s=50, zorder=5)
|
|
ax1.scatter(nodes[0][0], nodes[0][1], color='yellow', s=150, marker='*')
|
|
ax1.set_title("1. Physical World (Spider Web Topology)", fontsize=14)
|
|
ax1.axis('off')
|
|
|
|
# --- 右圖:擾動矩陣 F 的熱圖 ---
|
|
# 我們畫出 F 矩陣,顏色越深(0)代表越安全,顏色越淺(10)代表越危險
|
|
sns.heatmap(F, cmap="YlGnBu", ax=ax2, cbar_kws={'label': 'Disturbance Value (F)'})
|
|
ax2.set_title(f"2. Algorithm World (Disturbance Matrix F)\nMatrix Size: {N}x{N}", fontsize=14)
|
|
ax2.set_xlabel("City Index")
|
|
ax2.set_ylabel("City Index")
|
|
|
|
plt.tight_layout()
|
|
plt.show()
|
|
|
|
return F
|
|
|
|
if __name__ == "__main__":
|
|
F_matrix = plot_spider_web_and_matrix() |