codexmatching-greedy-middle-edge-trap.py
matching-greedy-middle-edge-trap.py
"""Original P4 example: greedy middle edge versus maximum matching.
Tested with Python 3.14.4 and matplotlib 3.10.7 (project dependencies).
Run from _media; saves its own basename PNG to the current directory.
"""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
EDGES = ((1, 2), (2, 3), (3, 4))
GREEDY = {(2, 3)}
MAXIMUM = {(1, 2), (3, 4)}
BLUE = "#1765a8"
GRAY = "#a4abb2"
def draw_path(ax, selected, title, note):
used = {v for edge in selected for v in edge}
for u, v in EDGES:
ax.plot([u, v], [0, 0], color=BLUE if (u, v) in selected else GRAY,
linewidth=6 if (u, v) in selected else 2.3, zorder=1,
linestyle="-" if (u, v) in selected else "--")
for v in range(1, 5):
ax.add_patch(Circle((v, 0), 0.13, facecolor="white",
edgecolor=BLUE if v in used else "#333333",
linewidth=2.5, zorder=3))
ax.text(v, 0, str(v), ha="center", va="center", fontsize=14, zorder=4)
if v not in used:
ax.text(v, -0.33, "free", ha="center", fontsize=12)
ax.set_title(title, fontsize=15, weight="bold", pad=12)
ax.text(2.5, -0.65, note, ha="center", fontsize=12)
ax.set(xlim=(0.55, 4.45), ylim=(-0.92, 0.53), aspect="equal")
ax.axis("off")
def main():
plt.rcParams.update({"font.family": "DejaVu Sans", "font.size": 13})
fig, axes = plt.subplots(1, 2, figsize=(9, 3.9), dpi=120, facecolor="white")
fig.subplots_adjust(left=0.03, right=0.97, top=0.72, bottom=0.23, wspace=0.24)
fig.suptitle("Greedy pairing can stop too early on P₄", fontsize=18,
weight="bold", y=0.96)
draw_path(axes[0], GREEDY, "Middle first: maximal, size 1",
"Neither outer edge can be added.")
draw_path(axes[1], MAXIMUM, "Outer edges: maximum, size 2",
"Four vertices allow at most two pairs.")
fig.text(0.5, 0.16, "Blue solid: selected edge Gray dashed: unselected edge",
ha="center", fontsize=12)
fig.text(0.5, 0.075, "Replacing the middle edge allows both outer edges to be selected.",
ha="center", fontsize=12)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"),
facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()