{"id":51030735,"url":"https://github.com/jtompuri/lin-kernighan-heuristic-algorithm","last_synced_at":"2026-06-22T00:02:00.783Z","repository":{"id":293459592,"uuid":"984104241","full_name":"jtompuri/lin-kernighan-heuristic-algorithm","owner":"jtompuri","description":"Python implementation of Lin-Kernighan Heuristic Algorithm based on the book \"The Traveling Salesman Problem: A Computational Study\" by Applegate \u0026 Co.","archived":false,"fork":false,"pushed_at":"2026-05-13T13:45:41.000Z","size":29127,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-13T15:36:50.710Z","etag":null,"topics":["lin-kernighan","traveling-salesman-problem","tsp-problem","tsp-solver","tsplib95"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jtompuri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-15T12:01:53.000Z","updated_at":"2026-05-13T14:02:20.000Z","dependencies_parsed_at":"2025-05-15T13:23:21.277Z","dependency_job_id":"f4397202-8431-41b4-83a9-28c6ed08700a","html_url":"https://github.com/jtompuri/lin-kernighan-heuristic-algorithm","commit_stats":null,"previous_names":["jtompuri/lin-kernighan-heuristic-algorithm"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jtompuri/lin-kernighan-heuristic-algorithm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtompuri%2Flin-kernighan-heuristic-algorithm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtompuri%2Flin-kernighan-heuristic-algorithm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtompuri%2Flin-kernighan-heuristic-algorithm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtompuri%2Flin-kernighan-heuristic-algorithm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jtompuri","download_url":"https://codeload.github.com/jtompuri/lin-kernighan-heuristic-algorithm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtompuri%2Flin-kernighan-heuristic-algorithm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34629658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-21T02:00:05.568Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lin-kernighan","traveling-salesman-problem","tsp-problem","tsp-solver","tsplib95"],"created_at":"2026-06-22T00:01:58.085Z","updated_at":"2026-06-22T00:02:00.774Z","avatar_url":"https://github.com/jtompuri.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lin-Kernighan Heuristic for the Traveling Salesperson Problem (TSP)\n\nA Python implementation of the Lin-Kernighan (LK) heuristic for solving the Traveling Salesperson Problem. This solver processes TSPLIB format instances with Euclidean 2D geometry and provides high-quality approximate solutions using a chained version of the LK algorithm.\n\n**Key Features:**\n- Multiple starting cycle algorithms (natural, random, nearest neighbor, greedy, Borůvka, quick-Borůvka)\n- Parallel and sequential processing modes\n- Automatic gap calculation against optimal tours (when available)\n- Tour visualization and saving in TSPLIB format\n- Comprehensive test coverage and helper tools\n\n**Requirements:** Python 3.12+ (uses modern features like f-strings, pathlib, and extensive type hinting)\n\n## Table of Contents\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [Example Output](#example-output)\n- [Development](#development)\n- [Configuration](#configuration)\n- [References \u0026 Course Documentation](#references--course-documentation)\n\n## Quick Start\n\n### Installation \u0026 Usage\n\n```bash\n# 1. Setup\npython -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\npip install -r requirements.txt\n\n# 2. Run with default settings (processes all TSPLIB95 instances)\npython -m lin_kernighan_tsp_solver\n\n# 3. Process specific files\npython -m lin_kernighan_tsp_solver problems/tsplib95/berlin52.tsp\n\n# 4. Customize settings (visualization enabled by default)\npython -m lin_kernighan_tsp_solver --time-limit 10.0 --starting-cycle greedy\n```\n\n### System Dependencies (Optional)\n\n**For interactive plotting on Ubuntu/Debian**:\n```bash\nsudo apt-get update\nsudo apt-get install python3-tk  # Enables interactive plot windows\n```\n\n**Note**: The solver automatically detects `tkinter` availability and enables plotting by default:\n- **With `tkinter`**: Shows interactive plot windows  \n- **Without `tkinter`**: Automatically saves plots to `solutions/plots/`\n\n## Usage\n\n### Basic Commands\n\n```bash\n# Process all instances in problems/tsplib95/ (default)\npython -m lin_kernighan_tsp_solver\n\n# Process specific files\npython -m lin_kernighan_tsp_solver file1.tsp file2.tsp\n\n# Use different starting algorithm\npython -m lin_kernighan_tsp_solver --starting-cycle greedy\n\n# Set time limit (plots generated by default)\npython -m lin_kernighan_tsp_solver --time-limit 20.0\n\n# Process with default settings (tours saved and plots generated by default)\npython -m lin_kernighan_tsp_solver\n```\n\n### Key Options\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--starting-cycle` | Algorithm: `natural`, `random`, `nearest_neighbor`, `greedy`, `boruvka`, `qboruvka` | `qboruvka` |\n| `--time-limit` | Time limit per instance (seconds) | `5.0` |\n| `--workers` | Number of parallel workers | All CPU cores |\n| `--sequential` | Force sequential processing | Parallel |\n| `--no-save-tours` | Don't save heuristic tours | **Tours saved by default** |\n| `--save-plot` | Force saving plots to files (even with GUI) | Interactive if `tkinter` available |\n| `--no-plot` | Disable all plot generation | **Plots enabled by default** |\n\n### Starting Cycle Algorithms\n\n- **`qboruvka`** (default): Best balance of speed and quality\n- **`greedy`**: Highest quality, slower for large instances  \n- **`natural`**: Fastest, lowest quality\n- **`nearest_neighbor`**: Good compromise\n- **`boruvka`**, **`random`**: Alternative options\n\n**Performance:** `natural` \u003e `random` \u003e `nearest_neighbor` \u003e `qboruvka` \u003e `boruvka` \u003e `greedy`  \n**Quality:** Often `greedy` ≥ `qboruvka` ≥ `boruvka` ≥ `nearest_neighbor` \u003e `random` \u003e `natural`\n\n### Tour Visualization\n\nThe solver automatically generates visualization plots showing optimal and heuristic tours:\n\n```bash\n# Default behavior: generate plots (interactive if `tkinter` available, otherwise saved to file)\npython -m lin_kernighan_tsp_solver problems/tsplib95/berlin52.tsp\n\n# Force saving plots to files (useful for servers/CI)\npython -m lin_kernighan_tsp_solver problems/tsplib95/berlin52.tsp --save-plot\n\n# Disable plotting entirely\npython -m lin_kernighan_tsp_solver problems/tsplib95/berlin52.tsp --no-plot\n```\n\n### Weighted Voronoi Stippling Workflow\n\nUse this workflow to generate stipple points, solve with LK, and visualize the LK tour:\n\n```bash\n# 1) In weighted-voronoi-stippling: generate a TSPLIB .tsp instance\npython stippling.py images/photo.jpg --stipples 10000\n\n# 2) In this repository: run LK with tour saving enabled (default)\npython -m lin_kernighan_tsp_solver /path/to/weighted-voronoi-stippling/stipplings/tsp/photo_10000.tsp\n\n# 3) In weighted-voronoi-stippling: visualize with the saved heuristic tour\npython visualize.py --tsp /path/to/weighted-voronoi-stippling/stipplings/tsp/photo_10000.tsp --tour solutions/tours/photo_10000.heu.tour\n```\n\nSaved heuristic tours use the `.heu.tour` suffix and are written in TSPLIB `TOUR` format.\nNode IDs in the file are 1-based (TSPLIB convention), and are read back as 0-based internally.\n\n## Example Output\n\n![Example output plots](/images/lin-kernighan-example-output-20s-parallel.png)\n\n```\nFound 18 TSP instances.\nProcessing using 12 parallel workers...\n\nConfiguration parameters:\n  TIME_LIMIT  = 20.00\n  STARTING_CYCLE = qboruvka\n\nInstance     OptLen   HeuLen   Gap(%)  Time(s)\n----------------------------------------------\nberlin52    7544.37  7544.37     0.00     0.45\neil51        429.98   428.98     0.00    20.00\nkroA100    21285.44 21285.44     0.00     4.07\n...\n----------------------------------------------\nSUMMARY    910625.92 1104939.02     3.52    15.20\n```\n\n## Development\n\n### Installation\n```bash\npip install -r requirements-dev.txt  # Includes testing, linting tools\n```\n\n### Testing\n```bash\npython -m pytest                              # Run all tests\npython -m pytest --cov=lin_kernighan_tsp_solver --cov-report=html --cov-report=term-missing  # With coverage\n```\n\n### Helper Tools\n```bash\n# Create random TSP instances with defaults\npython helpers/create_tsp_problem.py 20                           # Creates rand20.tsp in problems/random/\npython helpers/create_tsp_problem.py 15 --name custom --seed 123  # Custom name with seed\n\n# Exact brute-force solver for small instances  \npython helpers/exact_tsp_solver.py                                # Process problems/random/*.tsp\npython helpers/exact_tsp_solver.py --input-dir problems/custom    # Custom input directory\n\n# Simple k-opt TSP solver with time limits\npython helpers/simple_tsp_solver.py                               # Process problems/tsplib95/*.tsp  \npython helpers/simple_tsp_solver.py --save-tours                 # Save tours and show plots (plots enabled by default)\npython helpers/simple_tsp_solver.py --input-dir problems/random --time-limit 10  # Custom config\n```\n\n## Configuration\n\n- **TSP files**: Place `.tsp` files in `problems/tsplib95/` (default) or update `TSP_FOLDER_PATH` in `lin_kernighan_tsp_solver/config.py`\n- **Optimal tours**: Place `.opt.tour` files alongside `.tsp` files for gap calculation\n- **Output folders**: \n  - Lin-Kernighan heuristic tours: `solutions/lin_kernighan/` (saved by default, disable with `--no-save-tours`)\n  - Tour visualization plots: `solutions/plots/` (automatically created, named by problem)\n  - Helper tools: `solutions/simple/` for simple TSP solver output\n- **Input folders**: `problems/tsplib95/`, `problems/random/`, `problems/custom/` for organized problem storage\n- **Algorithm parameters**: Modify `LK_CONFIG` and `STARTING_CYCLE_CONFIG` in `config.py`\n\n## References \u0026 Course Documentation\n\n**Algorithm based on:**\n- Applegate, D.L., Bixby, R.E., Chvatál, V. \u0026 Cook, W.J. (2006): _The Traveling Salesman Problem: A Computational Study_, Princeton University Press\n- Lin, S. \u0026 Kernighan, B.W. (1973): \"An Effective Heuristic Algorithm for the Traveling-Salesman Problem\", Operations Research, Vol. 21, No. 2, pp. 498–516\n\n**Course documentation (Finnish):**\n[Määrittelydokumentti](/documentation/requirements_specification.md) | [Toteutusdokumentti](/documentation/implementation_specification.md) | [Testausdokumentti](/documentation/testing_specification.md)\n\n**Weekly reports:** [Week 1](/documentation/reports/weekly_report_1.md) | [Week 2](/documentation/reports/weekly_report_2.md) | [Week 3](/documentation/reports/weekly_report_3.md) | [Week 4](/documentation/reports/weekly_report_4.md) | [Week 5](/documentation/reports/weekly_report_5.md) | [Week 6](/documentation/reports/weekly_report_6.md) | [Week 7](/documentation/reports/weekly_report_7.md) | [Week 8](/documentation/reports/weekly_report_8.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtompuri%2Flin-kernighan-heuristic-algorithm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjtompuri%2Flin-kernighan-heuristic-algorithm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtompuri%2Flin-kernighan-heuristic-algorithm/lists"}