Documentation
¶
Overview ¶
Example 15_task_assignment — two bipartite assignment algorithms side by side over one seeded, scale-parametrised worker/task instance: search.Hungarian computes the globally cheapest one-to-one assignment over the full cost matrix, and search.HopcroftKarp computes the largest matching once a feasibility rule prunes the edges.
The two algorithms answer different questions over the same instance. Hungarian minimises total cost across the full n×m cost matrix and may legally use any pair, however unsuitable. Hopcroft-Karp ignores cost and instead maximises how many workers can be staffed once each worker is restricted to the tasks they are competent for — the "feasible" pairs whose cost falls at or below a percentile threshold. Reporting both, and relating them, is the point of the example.
Model ¶
The instance is a skilled-workforce / task-dispatch problem with a latent competency model. Each worker carries a hidden skill vector and each task a hidden requirement vector, both in [0,1]^skills drawn from the seeded RNG. The cost of worker i taking task j is a weighted under-qualification deficit — a worker pays only for the skills a task needs and they lack, never for surplus skill — plus a little idiosyncratic noise, scaled and rounded to a clean integer:
cost(i,j) = round( SCALE · ( Σ_k w_k·max(0, req_j[k] − skill_i[k]) + ε ) )
Costs are integers held as float64, so the optimal total cost is an exact integer the regression test can assert. The structure (low-rank affinity plus noise) makes the optimal assignment non-trivial: the per-worker cheapest task frequently collides, so resolving the collisions optimally needs the global Hungarian trade-off rather than a greedy pick.
Feasibility pruning ¶
The Hopcroft-Karp graph keeps only the pairs a worker is competent for: edge (i,j) survives when cost(i,j) is at or below the feasiblePct-th percentile of all n·m costs. A percentile (rather than an absolute constant) is self-calibrating — it stays in the interesting regime as the scale, skill count, or noise change. At the default ~30% retention the cheap edges cluster on the easy tasks, so by Hall's theorem the maximum matching falls strictly short of min(workers, tasks): some workers cannot be staffed at all under the rule. That shortfall, and how the willing roster's cost compares to the unconstrained optimum, is what the example surfaces.
Scale ¶
Run with no flags the example uses a small, fast, deterministic default (200 workers, 240 tasks, 6 skills). Every dimension is a flag, so the same binary scales up to where the O(V^3) Hungarian cost and the matching structure become observable:
go run ./examples/15_task_assignment -workers 1000 -tasks 1200 -seed 7
Hungarian requires at least as many tasks as workers (workers ≤ tasks); validate rejects a configuration that violates it. The deterministic facts — the optimal total cost and the maximum matching size — are reproducible for a fixed -seed; only the telemetry (lines prefixed with "# ") varies between runs and machines.
Why in-memory ¶
The example measures assignment-algorithm wall-clock and live-heap footprint, so it builds the instance in memory and never touches the WAL/recovery stack. The persistence path is demonstrated by examples 04, 17, 24 and 25.