【问题标题】:Java JGrapht Bipartite graphJava JGrapht 二分图
【发布时间】:2014-03-26 18:12:34
【问题描述】:

我看到了 jgraph 和 jgrapht 的示例,并且很容易理解,但现在确定我将如何使用 CompleteBipartiteGraph?实例化图的语法是怎样的?

http://jgrapht.org/javadoc/

http://jgrapht.org/javadoc/org/jgrapht/generate/CompleteBipartiteGraphGenerator.html

【问题讨论】:

  • 看起来使用起来非常简单。 (当然,这种印象可能是错误的,但是)看起来你只是创建了这个生成器的一个实例,然后用一个(最初为空的)图调用generateGraph,该图接收由给定创建的顶点和边工厂。您能否指出到目前为止您尝试了什么以及遇到了什么问题?
  • 让我问你这个。我有每个顶点的列表和对应顶点的相应顶点。所以图表的一侧应该有多条线通往右侧的多个顶点。这个概念和结构对于绘制二分图是否正确?我应该使用什么数据结构,数组列表?所以它看起来像这样.....V -> V1,V2,V3。
  • 我不明白你的问题。使用这个带有参数 (5,3) 的生成器应该会创建一个完整的二分图,就像在 en.wikipedia.org/wiki/Complete_bipartite_graph 的示例(右上图)...
  • 我在想这个。 en.wikipedia.org/wiki/Bipartite_graph我还能用这个生成器吗?
  • 也许这可能更容易? Bipartite Solver for Java

标签: java bipartite jgrapht jgraph


【解决方案1】:

回答评论中的问题“我还能使用这个生成器吗?”:您仍然可以使用它来创建一个完整的二分图,然后随机删除一些边。

但更直接的方法是简单地生成两组顶点并在它们之间插入一些随机边。事实上,这如此很容易,我不得不假设存在您直到现在才提到的其他限制。我插入了另一种方法,确保二分图不包含孤立的顶点(我的水晶球被告知要这样做......)

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.jgrapht.Graph;
import org.jgrapht.UndirectedGraph;
import org.jgrapht.VertexFactory;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleGraph;

public class BipartiteGraphTest
{
    public static void main(String[] args)
    {
        UndirectedGraph<String, DefaultEdge> graph =
            new SimpleGraph<String, DefaultEdge>(DefaultEdge.class);

        VertexFactory<String> vertexFactory = new VertexFactory<String>()
        {
            int n = 0;
            @Override
            public String createVertex()
            {
                String s = String.valueOf(n);
                n++;
                return s;
            }
        };
        int numVertices0 = 10;
        int numVertices1 = 15;
        int numEdges = 20;
        generateGraph(graph, numVertices0, numVertices1, numEdges, vertexFactory);

        System.out.println(graph);
    }

    // Creates a bipartite graph with the given numbers 
    // of vertices and edges
    public static <V, E> void generateGraph(Graph<V, E> graph,
        int numVertices0, int numVertices1, int numEdges,
        final VertexFactory<V> vertexFactory)
    {
        List<V> vertices0 = new ArrayList<V>();
        for (int i = 0; i < numVertices0; i++)
        {
            V v = vertexFactory.createVertex();
            graph.addVertex(v);
            vertices0.add(v);
        }
        List<V> vertices1 = new ArrayList<V>();
        for (int i = 0; i < numVertices1; i++)
        {
            V v = vertexFactory.createVertex();
            graph.addVertex(v);
            vertices1.add(v);
        }

        // Create edges between random vertices
        Random random = new Random(0);
        while (graph.edgeSet().size() < numEdges)
        {
            int i1 = random.nextInt(vertices1.size());
            V v1 = vertices1.get(i1);
            int i0 = random.nextInt(vertices0.size());
            V v0 = vertices0.get(i0);
            graph.addEdge(v0, v1);
        }

    }

    // Creates a bipartite graph with the given numbers
    // of vertices and edges without isolated vertices
    public static <V, E> void generateGraphNoIsolatedVertices(
        Graph<V, E> graph, int numVertices0, int numVertices1, int numEdges,
        final VertexFactory<V> vertexFactory, 
        List<V> vertices0, List<V> vertices1)
    {
        int minNumEdges = Math.max(numVertices0, numVertices0);
        if (numEdges < minNumEdges)
        {
            System.out.println("At least " + minNumEdges + " are required to " +
                "connect each of the " + numVertices0 + " vertices " +
                "to any of the " + numVertices1 + " vertices");
            numEdges = minNumEdges;
        }

        for (int i = 0; i < numVertices0; i++)
        {
            V v = vertexFactory.createVertex();
            graph.addVertex(v);
            vertices0.add(v);
        }
        for (int i = 0; i < numVertices1; i++)
        {
            V v = vertexFactory.createVertex();
            graph.addVertex(v);
            vertices1.add(v);
        }

        // Connect each vertex of the larger set with
        // a random vertex of the smaller set
        Random random = new Random(0);
        List<V> larger = null;
        List<V> smaller = null;


        if (numVertices0 > numVertices1)
        {
            larger = new ArrayList<V>(vertices0);
            smaller = new ArrayList<V>(vertices1);
        }
        else
        {
            larger = new ArrayList<V>(vertices1);
            smaller = new ArrayList<V>(vertices0);
        }
        List<V> unmatched = new ArrayList<V>(smaller);
        for (V vL : larger)
        {
            int i = random.nextInt(unmatched.size());
            V vS = unmatched.get(i);
            unmatched.remove(i);
            if (unmatched.size() == 0)
            {
                unmatched = new ArrayList<V>(smaller);
            }
            graph.addEdge(vL, vS);
        }

        // Create the remaining edges between random vertices
        while (graph.edgeSet().size() < numEdges)
        {
            int i0 = random.nextInt(vertices0.size());
            V v0 = vertices0.get(i0);
            int i1 = random.nextInt(vertices1.size());
            V v1 = vertices1.get(i1);
            graph.addEdge(v0, v1);
        }

    }


}

【讨论】:

  • 谢谢。我要为此努力。它是使用库的直接方法,可能是我将使用的方法。我正在解析一个药库,并使作为字符串的药物 IDS 显示彼此酶之间的关系,它们也有用于 ID 的字符串。所以图表不进行字符串比较我将不得不自己做然后像你做的那样迭代并制作顶点和边?
  • @MAXGEN 如果这是一个问题,您应该尝试改写它。至少,我没看懂。
  • 如果您能提供帮助,我会提出另一个问题,这可能更有意义。 stackoverflow.com/questions/22703918/…
猜你喜欢
  • 1970-01-01
  • 2015-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多