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

如何在Java中实现带权非二分图的最大权匹配?求替代库

Java Solution for Max-Weight (Max-Cardinality) Matching in Weighted Non-Bipartite Graphs

Hey there! I see you've got a solid implementation going in NetworkX for max-cardinality max-weight matching on a weighted non-bipartite graph, and you're stuck finding a Java equivalent after trying JGraphT. Good news—JGraphT does support this use case, you just might have overlooked the right algorithm class. Let's walk through the solution, plus a backup option if you need it:

Option 1: JGraphT Implementation (The Right Way)

JGraphT has the BlossomVAlgorithm class specifically designed for solving max-weight matching problems on general (non-bipartite) graphs, and it lets you prioritize max cardinality exactly like your Python code does with maxcardinality=True.

Full Code Example

import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph;
import org.jgrapht.alg.matching.BlossomVAlgorithm;
import org.jgrapht.alg.matching.MatchingAlgorithm;

import java.util.Set;

public class MaxWeightMatchingDemo {
    public static void main(String[] args) {
        // Initialize weighted undirected graph
        Graph<Integer, DefaultWeightedEdge> graph = new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
        
        // Add vertices
        graph.addVertex(1);
        graph.addVertex(2);
        graph.addVertex(3);
        graph.addVertex(4);
        
        // Add weighted edges (matches your Python graph exactly)
        graph.setEdgeWeight(graph.addEdge(1, 2), 30);
        graph.setEdgeWeight(graph.addEdge(1, 3), 100);
        graph.setEdgeWeight(graph.addEdge(1, 4), 30);
        graph.setEdgeWeight(graph.addEdge(2, 3), 0);
        graph.setEdgeWeight(graph.addEdge(2, 4), 30);
        graph.setEdgeWeight(graph.addEdge(3, 4), 30);
        
        // Set up BlossomV algorithm, enable max-cardinality priority
        BlossomVAlgorithm<Integer, DefaultWeightedEdge> blossomV = new BlossomVAlgorithm<>(graph);
        // Passing `true` here prioritizes maximum cardinality first, then maximum weight
        MatchingAlgorithm.Matching<Integer, DefaultWeightedEdge> matching = blossomV.getMatching(true);
        
        // Output the result
        System.out.println("Max-Cardinality Max-Weight Matching Result:");
        for (DefaultWeightedEdge edge : matching.getEdges()) {
            int u = graph.getEdgeSource(edge);
            int v = graph.getEdgeTarget(edge);
            System.out.printf("(%d, %d)%n", u, v);
        }
    }
}

Maven Dependency

Add this to your pom.xml to pull in JGraphT's core library (use the latest stable version if available):

<dependency>
    <groupId>org.jgrapht</groupId>
    <artifactId>jgrapht-core</artifactId>
    <version>1.5.1</version>
</dependency>

When you run this code, you'll get the exact same output as your Python implementation: (1, 3) and (2, 4).

Option 2: Alternative Library (If JGraphT Still Doesn't Fit)

If you need another option, Apache Commons Graph is a lesser-known but capable library that supports general graph matching algorithms. That said, JGraphT is far more widely used and well-documented, so it's the better default choice.

Quick Note on Your JGraphT Troubles

Chances are you were looking at bipartite matching algorithms (like HopcroftKarpAlgorithm) instead of the general graph-focused BlossomVAlgorithm. Easy mix-up—bipartite matching algorithms won't work for non-bipartite graphs, which is why you hit a wall earlier!

内容的提问来源于stack exchange,提问作者Gevorg Harutyunyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:57:31