You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JGraphT中SimpleGraph的哈密顿路径与环检测及获取方案咨询

解决JGraphT中非完全图的哈密顿路径/环问题

嘿,刚好对JGraphT里的哈密顿问题有研究,给你几个不用转完全图、也不用自己实现算法的实用方案:

一、找哈密顿环:直接用BacktrackingHamiltonianCycle

这个类完全踩中你的需求——它不需要输入完全图,直接在你的SimpleGraph上通过回溯算法搜索哈密顿环,完全不用额外添加大量冗余边。

用法超级直观,实例化后调用findHamiltonianCycle方法就行,存在环时返回GraphPath对象,不存在则返回null。代码示例:

import org.jgrapht.Graph;
import org.jgrapht.alg.tour.BacktrackingHamiltonianCycle;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleGraph;

public class HamiltonianCycleDemo {
    public static void main(String[] args) {
        // 初始化你的SimpleGraph
        Graph<String, DefaultEdge> graph = new SimpleGraph<>(DefaultEdge.class);
        graph.addVertex("A");
        graph.addVertex("B");
        graph.addVertex("C");
        graph.addVertex("D");
        graph.addEdge("A", "B");
        graph.addEdge("B", "C");
        graph.addEdge("C", "D");
        graph.addEdge("D", "A");
        graph.addEdge("A", "C");

        // 查找哈密顿环
        BacktrackingHamiltonianCycle<String, DefaultEdge> cycleFinder = new BacktrackingHamiltonianCycle<>();
        GraphPath<String, DefaultEdge> hamiltonianCycle = cycleFinder.findHamiltonianCycle(graph);

        if (hamiltonianCycle != null) {
            System.out.println("找到哈密顿环:" + hamiltonianCycle.getVertexList());
        } else {
            System.out.println("该图不存在哈密顿环");
        }
    }
}

需要注意的是,回溯算法的时间复杂度是O(n!),所以这个方法更适合中小规模的图(比如顶点数n < 20),如果是超大图,效率会比较受限。

二、找哈密顿路径:基于虚拟顶点的巧妙转化

JGraphT目前没有直接的非完全图哈密顿路径现成实现,但我们可以基于上面的BacktrackingHamiltonianCycle做个小技巧转化:

  1. 创建临时图,在原SimpleGraph基础上添加一个虚拟顶点,让它和所有原有顶点相连
  2. 查找临时图的哈密顿环——这个环必然会经过虚拟顶点
  3. 从环中移除虚拟顶点,剩下的顶点序列就是原Graph的哈密顿路径

这种方式只需要添加n条边(n是原顶点数),远少于转完全图需要的边数,完全在可接受范围内。代码示例:

import org.jgrapht.Graph;
import org.jgrapht.alg.tour.BacktrackingHamiltonianCycle;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleGraph;
import java.util.List;

public class HamiltonianPathDemo {
    public static void main(String[] args) {
        // 初始化原SimpleGraph
        Graph<String, DefaultEdge> originalGraph = new SimpleGraph<>(DefaultEdge.class);
        originalGraph.addVertex("A");
        originalGraph.addVertex("B");
        originalGraph.addVertex("C");
        originalGraph.addVertex("D");
        originalGraph.addEdge("A", "B");
        originalGraph.addEdge("B", "C");
        originalGraph.addEdge("C", "D");
        originalGraph.addEdge("A", "D");

        // 创建临时图并添加虚拟顶点
        Graph<String, DefaultEdge> tempGraph = new SimpleGraph<>(DefaultEdge.class);
        String dummyVertex = "DUMMY";
        tempGraph.addVertex(dummyVertex);

        // 复制原顶点和边到临时图
        for (String vertex : originalGraph.vertexSet()) {
            tempGraph.addVertex(vertex);
            tempGraph.addEdge(dummyVertex, vertex);
        }
        tempGraph.addEdgeSet(originalGraph.edgeSet());

        // 查找临时图的哈密顿环
        BacktrackingHamiltonianCycle<String, DefaultEdge> cycleFinder = new BacktrackingHamiltonianCycle<>();
        GraphPath<String, DefaultEdge> tempCycle = cycleFinder.findHamiltonianCycle(tempGraph);

        if (tempCycle != null) {
            List<String> pathVertices = tempCycle.getVertexList();
            // 移除虚拟顶点,得到原Graph的哈密顿路径
            pathVertices.remove(dummyVertex);
            System.out.println("找到哈密顿路径:" + pathVertices);
        } else {
            System.out.println("该图不存在哈密顿路径");
        }
    }
}

三、补充:针对特殊图的优化方案

如果你的图满足Chvatal条件(n≥3的图,按顶点度数从小到大排序v₁≤v₂≤…≤vₙ,对于所有k < n/2,要么vₖ的度数>k,要么vₙ₋ₖ的度数≥n−k),可以用ChvatalHamiltonianCycle类,它能高效构造哈密顿环,且不需要完全图。不过这个方法的适用范围有限,只适合满足特定条件的图。

内容的提问来源于stack exchange,提问作者Jens Schauder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:08:47