Skip to content

Commit bad8a5b

Browse files
GiggleLiuclaude
andauthored
Fix #52: TravelingSalesman to ILP reduction (#60)
* update * Add plan for #52: TravelingSalesman to ILP reduction Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * save makefile and .claude * fix reductions macro missing * feat: add TravelingSalesman to ILP reduction (#52) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add unit tests for TravelingSalesman to ILP reduction (#52) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add TravelingSalesman to ILP reduction rule in paper (#52) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add TravelingSalesman to ILP example (#52) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: regenerate reduction graph and fix clippy in example (#52) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * update issue-to-pr * fix: resolve PR review comments for TSP-to-ILP reduction - Use exact constraint count formula (n³ - n² + 2n + 4mn) instead of approximation - Fix missing "is" in introduction.md - Categorize TravelingSalesman as "graph" with correct doc_path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 65bb77c commit bad8a5b

25 files changed

Lines changed: 1802 additions & 109 deletions

.claude/CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
## Project Overview
44
Rust library for NP-hard problem reductions. Implements computational problems with reduction rules for transforming between equivalent formulations.
55

6+
## Skills
7+
When resolving an issue with pull request, please use [issue-to-pr](skills/issue-to-pr.md) skill to convert the issue into a pull request with a plan.
8+
69
## Commands
710
```bash
811
make help # Show all available targets

.claude/skills/issue-to-pr.md

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ description: Use when you have a GitHub issue and want to create a PR with an im
77

88
Convert a GitHub issue into an actionable PR with a plan that auto-triggers Claude execution.
99

10-
## Usage
11-
12-
```
13-
/issue-to-pr <issue-number-or-url>
14-
```
15-
1610
## Workflow
1711

1812
```dot
@@ -24,15 +18,13 @@ digraph issue_to_pr {
2418
"Research references" [shape=box];
2519
"Write plan file" [shape=box];
2620
"Create branch and PR" [shape=box];
27-
"PR triggers [action]" [shape=doublecircle];
2821
2922
"Receive issue number" -> "Fetch issue with gh";
3023
"Fetch issue with gh" -> "Check the rules to follow";
3124
"Check the rules to follow" -> "Verify completeness";
3225
"Verify completeness" -> "Research references";
3326
"Research references" -> "Write plan file";
3427
"Write plan file" -> "Create branch and PR";
35-
"Create branch and PR" -> "PR triggers [action]";
3628
}
3729
```
3830

@@ -108,6 +100,7 @@ The plan MUST include an **action pipeline** section with concrete steps based o
108100
- Present example in tutorial style (see KColoring→QUBO section for reference)
109101

110102
5. **Regenerate graph**`cargo run --example export_graph`
103+
6. **Push and create PR** — Push the changes and create a pull request with a description of the changes.
111104

112105
**Rules for solver implementation:**
113106
- Make sure at least one solver is provided in the issue template. Check if the solving strategy is valid. If not, reply under issue to ask for clarification.
@@ -140,8 +133,10 @@ The plan MUST include an **action pipeline** section with concrete steps based o
140133
3. **Document** — Update `docs/paper/reductions.typ`:
141134
- Add `display-name` entry
142135
- Add `#problem-def("Name")[definition...]`
136+
4. **Push and create PR** — Push the changes and create a pull request with a description of the changes.
143137

144138
### 6. Create PR
139+
Create a pull request with only the plan file.
145140

146141
```bash
147142
# Create branch
@@ -156,16 +151,15 @@ git commit -m "Add plan for #<number>: <title>"
156151
# Push
157152
git push -u origin issue-<number>-<slug>
158153

159-
# Create PR with [action] at the BEGINNING
160-
gh pr create --title "Fix #<number>: <title>" --body "[action]
154+
# Create PR
155+
gh pr create --title "Fix #<number>: <title>" --body "
161156
162157
## Summary
163158
<Brief description from brainstorming>
164159
165160
Closes #<number>"
166161
```
167162

168-
**CRITICAL:** The PR body MUST start with `[action]` on the first line. This triggers automated plan execution.
169163

170164
## Example
171165

@@ -181,17 +175,15 @@ All required info is present. I'll create the plan...
181175
182176
[Writes docs/plans/2026-02-09-independentset-to-qubo.md]
183177
[Creates branch, commits, pushes]
184-
[Creates PR with body starting with "[action]"]
178+
[Creates PR]
185179
186-
Created PR #45: Fix #42: Add IndependentSet → QUBO reduction
187-
The [action] trigger will automatically execute the plan.
180+
Created PR #45: Fix #42: Add IndependentSet → QUBO reduction, description: ...
188181
```
189182

190183
## Common Mistakes
191184

192185
| Mistake | Fix |
193186
|---------|-----|
194187
| Issue template incomplete | Ask contributor to fill in missing sections before proceeding |
195-
| `[action]` not at start | PR body must BEGIN with `[action]` |
196188
| Including implementation code in initial PR | First PR: plan only |
197189
| Generic plan | Use specifics from the issue |

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,4 @@ docs/paper/examples/
7777

7878
# Claude Code logs
7979
claude-output.log
80+
.worktrees/

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ compare: rust-export
165165
INSTRUCTIONS ?=
166166
OUTPUT ?= claude-output.log
167167
AGENT_TYPE ?= claude
168+
PLAN_FILE ?= $(shell ls -t docs/plans/*.md 2>/dev/null | head -1)
168169

169170
run-plan:
170-
PLAN_FILE ?= $(shell ls -t docs/plans/*.md 2>/dev/null | head -1)
171171
@NL=$$'\n'; \
172172
BRANCH=$$(git branch --show-current); \
173173
if [ "$(AGENT_TYPE)" = "claude" ]; then \
@@ -182,6 +182,7 @@ run-plan:
182182
PROMPT="$${PROMPT}$${NL}$${NL}## Process$${NL}$${PROCESS}$${NL}$${NL}## Rules$${NL}- Tests should be strong enough to catch regressions.$${NL}- Do not modify tests to make them pass.$${NL}- Test failure must be reported."; \
183183
echo "=== Prompt ===" && echo "$$PROMPT" && echo "===" ; \
184184
claude --dangerously-skip-permissions \
185-
--model claude-opus-4-6 \
185+
--model opus \
186+
--verbose \
186187
--max-turns 500 \
187188
-p "$$PROMPT" 2>&1 | tee "$(OUTPUT)"

docs/paper/reductions.typ

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,25 @@ The following reductions to Integer Linear Programming are straightforward formu
806806
_Construction._ Variables: $x_v in {0, 1}$ for each $v in V$. Constraints: $x_u + x_v <= 1$ for each $(u, v) in.not E$ (non-edges). Objective: maximize $sum_v x_v$. Equivalently, IS on the complement graph. _Solution extraction:_ $K = {v : x_v = 1}$.
807807
]
808808

809+
#reduction-rule("TravelingSalesman", "ILP",
810+
example: true,
811+
example-caption: [Weighted $K_4$: the optimal tour $0 arrow 1 arrow 3 arrow 2 arrow 0$ with cost 80 is found by position-based ILP.],
812+
)[
813+
The traveling salesman problem reduces to binary ILP with $n^2 + 2 m n$ variables via position-based encoding with McCormick linearization.
814+
][
815+
_Construction._ For graph $G = (V, E)$ with $n = |V|$ and $m = |E|$:
816+
817+
_Variables:_ Binary $x_(v,k) in {0, 1}$ for each vertex $v in V$ and position $k in {0, ..., n-1}$. Interpretation: $x_(v,k) = 1$ iff vertex $v$ is at position $k$ in the tour.
818+
819+
_Auxiliary variables:_ For each edge $(u,v) in E$ and position $k$, introduce $y_(u,v,k)$ and $y_(v,u,k)$ to linearize the products $x_(u,k) dot x_(v,(k+1) mod n)$ and $x_(v,k) dot x_(u,(k+1) mod n)$ respectively.
820+
821+
_Constraints:_ (1) Each vertex has exactly one position: $sum_(k=0)^(n-1) x_(v,k) = 1$ for all $v in V$. (2) Each position has exactly one vertex: $sum_(v in V) x_(v,k) = 1$ for all $k$. (3) Non-edge consecutive prohibition: if ${v,w} in.not E$, then $x_(v,k) + x_(w,(k+1) mod n) <= 1$ for all $k$. (4) McCormick: $y <= x_(v,k)$, $y <= x_(w,(k+1) mod n)$, $y >= x_(v,k) + x_(w,(k+1) mod n) - 1$.
822+
823+
_Objective:_ Minimize $sum_((u,v) in E) w(u,v) dot sum_k (y_(u,v,k) + y_(v,u,k))$.
824+
825+
_Solution extraction._ For each position $k$, find vertex $v$ with $x_(v,k) = 1$ to recover the tour permutation; then select edges between consecutive positions.
826+
]
827+
809828
== Unit Disk Mapping
810829

811830
#reduction-rule("MaximumIndependentSet", "GridGraph")[
@@ -918,6 +937,7 @@ The following table shows concrete variable overhead for example instances, gene
918937
"kcoloring_to_ilp", "factoring_to_ilp",
919938
"maximumsetpacking_to_ilp", "minimumsetcovering_to_ilp",
920939
"minimumdominatingset_to_ilp", "maximumclique_to_ilp",
940+
"travelingsalesman_to_ilp",
921941
)
922942

923943
#let examples = example-files.map(n => {

0 commit comments

Comments
 (0)