codexedge-relaxation-trace.py
edge-relaxation-trace.py
"""Draw an original relaxation trace, writing this script's PNG basename to CWD.
Run from _media with MPLCONFIGDIR=/tmp/codex-wiki-matplotlib.
Tested with Python 3.14.4, matplotlib 3.10.7 and numpy 2.3.5.
Weights are constructed exact costs, not measured data.
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
INK = "#253746"
BLUE = "#196b9b"
GRAY = "#84919c"
def trace():
edges = [("s", "t", 10), ("s", "a", 6), ("s", "b", 2),
("a", "t", 2), ("b", "a", -1), ("a", "t", 2),
("b", "t", 7)]
labels = dict.fromkeys("sabt z".replace(" ", ""), float("inf"))
labels["s"] = 0
predecessors = dict.fromkeys(labels)
rows = [("Start", labels.copy(), None)]
for u, v, weight in edges:
candidate = labels[u] + weight
improved = candidate < labels[v]
if improved:
labels[v] = candidate
predecessors[v] = u
rows.append((f"{u} → {v}", labels.copy(), v if improved else None))
assert [row[1]["t"] for row in rows] == [float("inf"), 10, 10, 10, 8, 8, 3, 3]
assert predecessors == {"s": None, "a": "b", "b": "s", "t": "a", "z": None}
return rows
def main():
plt.rcParams.update({"font.family": "DejaVu Sans", "font.size": 11})
fig = plt.figure(figsize=(9.0, 5.0), dpi=120, facecolor="white")
fig.text(0.5, 0.95, "One edge at a time: discovered routes get cheaper",
ha="center", fontsize=16, weight="bold", color=INK)
fig.text(0.5, 0.895, "Constructed directed graph • negative edge allowed • s stays at 0",
ha="center", fontsize=11, color=INK)
ax = fig.add_axes((0.03, 0.23, 0.43, 0.60), facecolor="white")
positions = {"s": (0, 1.2), "a": (2.2, 2.1), "b": (2.2, 0.1),
"t": (4.4, 1.2), "z": (0, -0.5)}
# Original edge costs; blue edges are the final predecessor route.
edges = [("s", "a", 6, (0.98, 1.85), 0),
("s", "b", 2, (0.96, 0.47), 0),
("b", "a", -1, (2.44, 1.1), 0),
("a", "t", 2, (3.4, 1.85), 0),
("b", "t", 7, (3.4, 0.47), 0),
("s", "t", 10, (2.2, 3.13), -0.86)]
route_edges = {("s", "b"), ("b", "a"), ("a", "t")}
for u, v, weight, label_pos, bend in edges:
color = BLUE if (u, v) in route_edges else GRAY
ax.add_patch(FancyArrowPatch(
positions[u], positions[v], arrowstyle="-|>", mutation_scale=14,
shrinkA=15, shrinkB=15, linewidth=2.5 if color == BLUE else 1.6,
color=color, connectionstyle=f"arc3,rad={bend}", zorder=1))
ax.text(*label_pos, str(weight), fontsize=13, ha="center", va="center",
color="#b63d2c" if weight < 0 else color,
bbox={"facecolor": "white", "edgecolor": "none", "pad": 1.5}, zorder=3)
for vertex, (x, y) in positions.items():
ax.scatter(x, y, s=640, facecolors="white", edgecolors=INK, linewidths=1.6, zorder=4)
ax.text(x, y, vertex, ha="center", va="center", fontsize=14, color=INK, zorder=5)
ax.text(0.42, -0.5, "isolated: d(z) = ∞", fontsize=10, color=GRAY, va="center")
ax.set(xlim=(-0.5, 4.9), ylim=(-0.9, 3.65), aspect="equal")
ax.axis("off")
fig.text(0.245, 0.235, "Blue: final route s → b → a → t", ha="center", color=BLUE, fontsize=11)
table_ax = fig.add_axes((0.49, 0.22, 0.48, 0.59))
table_ax.axis("off")
rows = trace()
data = [[operation] + ["∞" if label[v] == float("inf") else str(label[v])
for v in "abtz"] for operation, label, _ in rows]
table = table_ax.table(cellText=data, colLabels=["Relax", "d(a)", "d(b)", "d(t)", "d(z)"],
colWidths=[0.29, 0.1775, 0.1775, 0.1775, 0.1775],
cellLoc="center", bbox=[0, 0, 1, 1])
table.auto_set_font_size(False)
table.set_fontsize(11)
for (row, col), cell in table.get_celld().items():
cell.set_edgecolor("#d7dfe5")
cell.set_linewidth(0.6)
cell.set_text_props(color=INK)
if row == 0:
cell.set_facecolor("#e9eff3")
cell.set_text_props(weight="bold")
else:
cell.set_facecolor("white" if row % 2 else "#f7f9fb")
changed = rows[row - 1][2]
if col and "abtz"[col - 1] == changed:
cell.set_facecolor("#dceef8")
cell.set_text_props(color=BLUE, weight="bold")
fig.text(0.73, 0.835, "Labels after each operation", ha="center", color=INK, fontsize=12)
fig.text(0.5, 0.125, "After b → a: revisit a → t, since 1 + 2 < 8.",
ha="center", fontsize=12, color=INK)
fig.text(0.5, 0.065, "Final cost: 2 − 1 + 2 = 3 | This is a relaxation trace, not Dijkstra's order.",
ha="center", fontsize=11, color=INK)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white", transparent=False)
plt.close(fig)
print("Trace: a=1, b=2, t=3, z=inf; final predecessor route s-b-a-t")
if __name__ == "__main__":
main()