惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
Simon Willison's Weblog
Simon Willison's Weblog
H
Help Net Security
F
Fortinet All Blogs
H
Heimdal Security Blog
S
Schneier on Security
L
LangChain Blog
博客园 - Franky
酷 壳 – CoolShell
酷 壳 – CoolShell
NISL@THU
NISL@THU
P
Palo Alto Networks Blog
J
Java Code Geeks
博客园 - 【当耐特】
The Last Watchdog
The Last Watchdog
W
WeLiveSecurity
www.infosecurity-magazine.com
www.infosecurity-magazine.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost
I
InfoQ
Recorded Future
Recorded Future
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
CERT Recently Published Vulnerability Notes
T
Tenable Blog
腾讯CDC
C
Check Point Blog
量子位
M
MIT News - Artificial intelligence
GbyAI
GbyAI
罗磊的独立博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog
小众软件
小众软件
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CXSECURITY Database RSS Feed - CXSecurity.com
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
P
Privacy & Cybersecurity Law Blog
V2EX - 技术
V2EX - 技术
T
Threatpost
Engineering at Meta
Engineering at Meta
Attack and Defense Labs
Attack and Defense Labs
T
Tailwind CSS Blog
S
Securelist
The Cloudflare Blog
博客园 - 叶小钗
L
LINUX DO - 最新话题
T
Troy Hunt's Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
爱范儿
爱范儿

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
TSP - Travelling Salesman Problem
João Godinho · 2026-05-06 · via DEV Community
Cover image for TSP - Travelling Salesman Problem

João Godinho

Introduction

  • I will talk about P vs NP, NP-complete, and NP-hard, define heuristics in computer science, Hamiltonian cycles, TSP and Metric TSP, approximation algorithms, and optimal vs suboptimal solutions. I will also mention local minima, combinatorial explosion, and why exact solutions become infeasible. Finally, we will see an optimal solution and also an approximation algorithm.
  • I’ll also discuss the limitations of the chosen approximation algorithm, what could be improved, and mention other options like MST-based solutions, k-opt methods, and metaheuristics such as genetic algorithms, and their trade-offs.
  • The project code and analysis were developed in collaboration with Matheus Persch as part of the DSA III class at Federal University of Pelotas (UFPel), Brazil.

Prerequisites

Types of problems

  • Decision problem: You want to answer yes or no.
    • E.g. “Is there any Hamiltonian cycle in this graph G?” (YES/NO)
  • Search problem: You want to find a valid solution (if it exists).
    • E.g. “Find a Hamiltonian cycle in this graph G.”
  • Optimization problem: You want to find the best solution according to some objective (min/max).
    1. “Find the shortest Hamiltonian cycle in this graph G.” (TSP) - minimization problem
    2. “Find the maximum clique in graph G.” - maximization
    3. clique = subset of vertices in a graph that forms a complete subgraph

Time complexity class

  • Informal definition: Set of problems solvable in O(TIME(n)) time.
    • Example: sorting is in P because it has polynomial-time algorithms.
  • Formal definition: TIME(t(n)) is the set of languages decidable by a deterministic Turing machine in O(t(n)) time.
    • Note: “decidable” is formal for languages; for problems like sorting, this feels unnatural, so focus on the informal version for now.

P, NP, NP-Complete, NP-Hard

  • Polynomial time (P): Those problems which are decidable in polynomial time using a deterministic Turing machine.
    • TIME(O(n^k)) → k constant
  • Nondeterministic Polynomial time (NP): Those decision problems whose solutions can be verified in polynomial time by a deterministic Turing machine.
    • Verification: Given a candidate solution (certificate), we check if it is valid.
    • E.g. “Given a graph and a certificate, check if it is a valid Hamiltonian cycle.”
  • NP-Complete (NPC):
    1. is NP
    2. Every problem in NP can be reduced to it in polynomial time
      • One example is the SAT
  • NP-Hard: Problems that are at least as hard as the hardest problems in NP.
    1. Every problem in NP can be reduced to them in polynomial time
    2. Not required to be in NP
      1. ALL NP-complete are NP-hard
      2. But not all NP-hard problems are NP-complete
    3. NP-hard problems are not restricted to be decision problems such as P, NP and NPC.
    4. Example: TSP (optimization version)
  • For more detailed explanations, read the chapters of Michael Sipser’s book or watch his lectures in the references of this post.

Complexity classes

What is the Traveling Salesman problem?

  • Hamiltonian cycle Problem = Does a cycle exist that visits every vertex exactly once?
    • Note: you can't repeat the same edge, but there are variations where you can do it.
  • TSP = Among all Hamiltonian cycles, which one has minimum cost?

k-4 TSP example

Metric TSP

  • Metric TSP is formulated on a complete graph with distances satisfying the triangle inequality.
  • Metric TSP contains the following properties:
    • nodes= (x,y,z); distance = d
    • d(x,y) ≥ 0 (not negative)
    • d(x,y) = d(y,x) (symmetric → undirected)
    • d(x,y) + d(y,z) ≥ d(x,z) (triangle inequality)

Triangle inequality

Why finding the optimal TSP solution is infeasible in practice

  • Because it is NP-hard, it means there is no known polynomial-time solution for it.
  • There are multiple exact (optimal) algorithms, but brute force is the simplest and has time complexity of O(n!)
    • Example: n = 40 n! ~= 8.1591528 * 10^47 ~= 10^47 tours required
    • Imagine you can compute 1 billion tours per second: 10^9 tours
    • 10^47 / 10^9 = 10^38 seconds ~= 3 * 10^30 years required to run it
    • age of universe ^= 13.8 * 10^10 years
    • It would take far longer than the age of the universe.
  • What I’ve shown above is called “combinatorial explosion”.
    • For first city you have n options
    • For second you have n-1 options
    • And so on
    • It is factorial: n * (n - 1) * (n - 2) * ... * 1 = n!

How to solve something that requires this amount of time?

  • As mentioned, it would require literally more time than is possible in this universe for a small n. To solve this type of problem, one possible approach is using approximation algorithms, which will provide you an approximate solution instead of the optimal one.

Heuristics in Computer Science

  • Hromkovič, J. (2004), Chapter 6, defines: ‘A heuristic algorithm in a very general sense is a consistent algorithm for an optimization problem that is based on some transparent (usually simple) strategy of searching in the set of all feasible solutions, and that does not guarantee finding any optimal solution’.
  • They must be much faster than the optimal solution, otherwise you would choose the optimal one.
  • Types of heuristics:
    • Constructive: Build a solution following a set of pre defined rules.
    • Improvement: Start with a feasible solution (any one), and apply successive small changes to improve it.
    • Compound: Use both, constructive solution and then an improvement phase.

Approximation algorithms

  • If an optimization problem is NP-hard such as the TSP one, there is no polynomial-time algorithm to solve it, unless P=NP (something we don’t know yet).
    • Optimal solution = the best solution using a non-approximation algorithm, for example, in TSP using brute force to test all possible tours would provide us for sure the cheapest Hamiltonian cycle.
    • Suboptimal solution = an approximate solution, isn’t the optimal one, but is close to it.
  • What an approximation algorithm does is exactly this: instead of trying to get an optimal solution for an NP-hard problem until the universe ends, we use an approximation algorithm to achieve an approximate solution with much faster execution time.
  • k-approximate approximation algorithm = Means that it is no worse than k times the optimal solution.
    • for minimization: optimal = 1; 2-approximate = 2 (2*opt)
    • for maximization: optimal = 2; 2-approximate = 1 (1/2*opt)
    • As you can see, an approximation algorithm is never better than the optimal; otherwise it would be the optimal one.
    • It can even be equal to the optimal solution in some cases (but not always).
  • Note: To develop approximation algorithms we generally use heuristics (defined in the prerequisites).

k-approximate chart interval

k-approximate chart example

Optimal solution for the TSP

  • There are many optimal solutions, all of them are too slow since this is an NP-hard problem.
  • We call brute force solution a solution that relies on exhaustive search.
  • The one I'll show you today is the Branch-and-Bound solution, that consists in backtracking plus pruning unnecessary paths before opening them.
  • If you don't understand backtracking check this Github (Code) - Backtracking playground

Branch-and-Bound for Metric TSP:

  • Branch = check new paths (permutations)
  • Bound = check the upper/lower bound and cut if already worse to avoid unnecessary paths
    • lower if is a minimization problem
    • upper if is a maximization problem
  • We fix the starting position as 0
  • Then we start checking permutations, such as (01230, 02130, 02310, …).
  • If we can identify that, before reaching the end, the current path is already worse than our current best, we do not need to continue (prune), and we stop exploring this path.
    1. Since TSP is a minimization problem, if our currCost is already worse than our bestCost (lower bound), there is no reason to continue exploring that path.
  • When we reach the end of a path, we return to start and check if currCost < bestCost

Branch-and-Bound code

// Time Complexity: O(V!)
// Space complexity: O(V)
unsigned int Graph::runTSPBranchAndBound(TSPState state) const {
  int pathSize = state.path.size();
  int vertices = getVertices();

  if(pathSize == vertices) {
    int lastUsedPos = state.path.back();
    unsigned int totalCost = state.currCost + getDistance(lastUsedPos, 0);
    return totalCost < state.bestCost ? totalCost : state.bestCost;
  }

  for(int i = 0; i < vertices; i++) {
    if(state.visited[i]) {
      continue;
    }

    // key diff from brute-force version
    int currDist = getDistance(state.path.back(), i);
    int newCost = state.currCost + currDist;
    if(newCost >= state.bestCost) { // cleaning unnecessary paths (prune = Branch-and-Bound)
      continue;
      // if I use a specific graph where pruning never happens, it becomes as bad as brute force because
      // it ends up exploring the entire search space without cutting any branches
      // fortunately, this is not the case in most situations
    }

    state.currCost += currDist;
    state.visited[i] = true;
    state.path.push_back(i);

    state.bestCost = std::min(state.bestCost, runTSPBranchAndBound(state));

    state.path.pop_back();
    state.visited[i] = false;
    state.currCost -= currDist;
  }

  return state.bestCost;
}

Enter fullscreen mode Exit fullscreen mode

  • But it is still too slow. Since TSP is an NP-hard problem, we still require an approximation algorithm to get a faster, approximate solution for that problem.

Approximation Algorithm for TSP

  • The difference between a heuristic and an approximation algorithm is that an approximation algorithm has a proven bound on how far its solution can be from the optimal one.
  • For example, a 2-approximation algorithm guarantees that in the worst case it will return a solution at most twice as bad as the optimal one. This is proven mathematically.
  • There are multiple approximation algorithms for the same problem, and this also happens in TSP, where you can solve it using, for example, the MST double-tree algorithm, Christofides algorithm, and more.

The Nearest Insertion Solution (2-approximate algorithm)

nearest insertion

Running Time Comparisons

  • Just some examples, on a random computer of ours.

Optimal: time O(V!)

optimal algorithms running time

  • Branch-And-Bound is already 10x faster than pure brute force for the 11x11 graph. Even though both algorithms have the same worst case, since branch-and-bound prunes some unnecessary paths.
  • But as we can see, running it for 15x15 would already take too much time so we didn't.

Approximate: time O(V^2)

approximate algorithm running time

  • And obviously the approximation is much faster and has a worst-case 2-approximation guarantee, and in our files the worst was not 2 but only ~11.45% worse than the optimal.

Extra: Metaheuristic and Genetic algorithm for TSP

Metaheuristics in Computer science

  • A metaheuristic is a high-level framework with some guidelines to build a heuristic (abstract idea to solve high-level).
  • A Genetic heuristic is made of:
    1. populations
    2. select
    3. crossover
    4. mutate (small percentage)
    5. improve
    6. repeat
  • It still requires problem specific solutions, where we use heuristics, for example:
    • crossover operator (e.g., EAX for TSP)
    • local search heuristics (2-opt, k-opt, …)

Genetic Algorithm with Edge Assembly Crossover (EAX-GA)

  • It is a TSP approximation algorithm that does the following:
  • Populations
    • N Hamiltonians cycles: [(A→B→C→D→E→A), ham cycle 2, …, ham cycle N]
  • Select (parents)
    • Choose randomly X pairs of hamiltonians cycle within your population
  • Crossover (Edge Assembly Crossover)
    • Combine the pair parent1 and parent2 (both hamiltonian cycles) to generate a child hamiltonian cycle.
  • Mutate
    • Here we select a small rate such as 5% of the generated children and we try to improve them by mutating
  • Local Search (apply one heuristic to improve)
    • child = improve_with_2opt_or_LK(child)
  • Repeat N times until reaching the stop condition (time or iterations)
    • Now you have a new population of children, you can even get some of the best parents to put in your population and remove the “worst children”.
      • read best as smaller cost and worst as biggest cost to travel
      • “Keep best solutions within parents and children and repeat.”
    • And within this population, select, crossover, mutate, and improve with local search once again until reaching the stop condition.

More solutions for the TSP

  • There are multiple solutions for the TSP:
    • 2-opt: swap two edges (small neighborhood), fast but weak
    • k-opt: swap k (constant) edges (larger neighborhood), better solutions, but slower
    • Lin–Kernighan heuristic (LK): adaptive k-opt, usually best trade-off between solution approximation and running time.
    • MST-based: build a Minimum Spanning Tree (MST), then do a preorder DFS traversal and shortcut repeated nodes (works for Metric TSP, gives a 2-approximation)
  • Some of those such as the 2-opt stop in the local minimum, it means that it gets stuck with the best local solutions but it doesn’t mean it’s the global optimal solution.
    • That means: for every pair of edges you try to swap, but the total distance does not decrease.
    • It can’t improve anymore but there may exist better solution.
    • The problem isn’t getting stuck in a local minimum, but how good that local minimum is.

References