Fix #122: Add SteinerTree model#192
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a detailed implementation plan document for introducing a new SteinerTree problem model (and associated tests/CLI/docs updates) to the codebase.
Changes:
- Adds an implementation plan covering the
SteinerTreemodel structure, validity checking, and trait impls - Outlines unit tests, CLI integration points, and documentation regeneration steps
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # SteinerTree Model Implementation Plan | ||
|
|
||
| > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. | ||
|
|
||
| **Goal:** Add the SteinerTree problem model — a minimization problem that finds a minimum-weight subtree connecting a set of terminal vertices. | ||
|
|
||
| **Architecture:** Edge-based binary optimization on graphs, following the TravelingSalesman pattern. Each edge variable is 0/1 (include or exclude). Feasibility requires selected edges to form an acyclic connected subgraph spanning all terminals. Uses `edge_weights: Vec<W>` plus a `terminals: Vec<usize>` field. |
There was a problem hiding this comment.
The PR title/description says the SteinerTree model + CLI support are added, but this PR currently only introduces an implementation plan document. Either update the PR metadata to reflect that this is documentation/planning only, or include the actual code/test/CLI/schema changes described in the plan before merging (so it truly fixes #122).
| // Count vertices in the connected component containing terminals | ||
| let component_vertices: usize = visited.iter().filter(|&&v| v && involved.iter().enumerate().any(|(i, &inv)| inv && i == 0).is_none() || v).count(); |
There was a problem hiding this comment.
In the is_valid_steiner_tree snippet, component_vertices is computed with a very complex expression that appears incorrect and wouldn’t compile as Rust (and the variable is unused). Since this is meant to be a copy/paste starting point, consider removing this line entirely or replacing it with the simpler reachable_involved count described immediately below to avoid confusion.
| // Count vertices in the connected component containing terminals | |
| let component_vertices: usize = visited.iter().filter(|&&v| v && involved.iter().enumerate().any(|(i, &inv)| inv && i == 0).is_none() || v).count(); |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #192 +/- ##
==========================================
+ Coverage 96.88% 96.92% +0.03%
==========================================
Files 269 271 +2
Lines 36036 36298 +262
==========================================
+ Hits 34915 35182 +267
+ Misses 1121 1116 -5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Implementation SummaryChanges
Deviations from Plan
Open Questions
|
Review Pipeline Report
🤖 Generated by review-pipeline |
Clean rebase onto current main. Adds SteinerTree<G, W> with edge-based binary variables, BFS+tree validity checker, Dreyfus-Wagner complexity, full CLI integration (create, example, random), paper entry with CeTZ figure, and 18 unit tests including coverage for all public methods. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4a9c585 to
63d99a4
Compare
…le from fixtures - Move SteinerTree display-name entry to correct alphabetical position - Use seeded Fisher-Yates shuffle for random terminal selection instead of always picking first N vertices - Rewrite paper example to use load-model-example() from canonical examples.json fixtures instead of hand-written values - Regenerate example fixtures to include SteinerTree model Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded (v2,v4) reference with data-driven lookup from the canonical example, eliminating the last hardcoded instance value. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Run the final review on this PR with some quick fixes, now claude rate 80% quality. @GiggleLiu |
- Add lcg_choose() utility for Fisher-Yates partial shuffle - Use random terminal selection and random edge weights in SteinerTree random generation - Regenerate examples.json to include SteinerTree canonical example - Fix pre-existing formatting issues from main merge Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prefer reusable lcg_choose() over inlined Fisher-Yates shuffle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, remove unrelated files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add plan for #212: [Model] MultiprocessorScheduling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add plan for #219: [Model] SequencingWithinIntervals Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: implement SequencingWithinIntervals model for #219 Add a satisfaction problem model for scheduling tasks within time windows without overlap (Garey & Johnson SS1, NP-complete). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: update SequencingWithinIntervals for new API Add missing display_name, aliases, dimensions fields to ProblemSchemaEntry. Use 'default sat' prefix in declare_variants! macro. Rename task_lengths CLI field to lengths to avoid clash with FlowShopScheduling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address Copilot review comments - Use checked_add to prevent u64 overflow in constructor - Rename test functions to snake_case (test_sequencing_within_intervals_*) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add missing structural items for SequencingWithinIntervals - Add canonical model example in example_db (satisfaction_example) - Add trait_consistency test entry - Add paper display-name and problem-def block in reductions.typ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: regenerate JSON artifacts for SequencingWithinIntervals Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: consolidate SequencingWithinIntervals re-exports into existing use blocks Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: trigger CI Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: apply rustfmt Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove unreachable deadline check in evaluate() The deadline guard `start + l[i] > d[i]` in evaluate() was dead code: since c < dim = d[i] - r[i] - l[i] + 1, start + l[i] <= d[i] holds by construction. Removing it fixes the 1-line codecov gap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: align with PR #192 standard — use load-model-example, remove unrelated files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add Gantt chart figure, remove plan doc Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add CLI tests, inline dims computation in evaluate() Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: GiggleLiu <cacate0129@gmail.com>
Summary
--terminalsflag)Fixes #122