graysonarts / graysonarts/aboutface
Place one Face per Cell with LAPJV and a movement penalty
- Dominant language
- Rust
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## What to build
The placement half of ADR-0003, in `aflayout`. The Window's Faces are assigned bijectively to the Grid's Cells by solving a linear assignment problem over the cost matrix:
```
cost(f, c) = cosine_distance(embedding(f), prototype(node_at(c)))
+ λ · movement_penalty(current_cell(f), c)
```
The movement penalty is the reason not to place greedily. Without it an optimal-by-similarity solution teleports a Face across the wall to save a trivial amount of distance, and the Re-solve reads as chaos rather than as the crowd reorganizing.
`afcore::Assignment` already refuses to put one Face in two Cells. This produces one.
ADR-0003 checked the cost rather than assuming it: LAPJV on a 1000x1000 dense matrix finishes in tens of milliseconds, so exact optimal assignment is affordable across the whole Grid range. Confirm that on real hardware rather than trusting the ADR.
λ is a parameter here. Putting it in the operator config and tuning it is #15.
## Acceptance criteria
- [ ] Solving over a cost matrix produces a bijective `Assignment` of the Window's Faces onto the Grid's Cells
- [ ] The solution is optimal: a test with a hand-computed small matrix asserts the exact total cost
- [ ] With λ = 0 the result is the best-by-similarity placement, and raising λ demonstrably reduces total movement
- [ ] A Face with no current Cell (newly Captured) is placed without special-casing the caller
- [ ] Total assignment cost and total movement are both reported, so the placement can be evaluated on its own
- [ ] Solve time at the top of the Grid range is measured and recorded against the tens-of-milliseconds claim in ADR-0003
## Blocked by
- #11
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by resolving the #11 dependency, then read ADR-0003 and inspect the placement code in `aflayout`, along with `afcore::Assignment`. Verify the cost-matrix and movement-penalty behavior with a small hand-computed case and measure the largest Grid solve on real hardware. Done means a bijective optimal assignment, support for newly Captured Faces, reported cost and movement totals, and recorded timing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-vision
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100