使用graphml和jung加载自定义节点和边

时间:2017-11-17 20:03:29

标签: java graph bigdata jung graphml

当我试图用JUNG读取和写入文本文件时,我遇到了问题。情况如下:给定的是一个包含多图的坐标及其权重的文件。

一个例子是:

6346    6728    5911    156 5
6346    6728    6599    156 10
6346    6728    8555    156 5

我已经用JUNG编写了一个转换器,它读取包含数百万个这样的行的文件并构造一个

DirectedSparseMultigraph<Node, Edge>

节点和边缘是下面列出的自定义类

class Node {
    int id; // good coding practice would have this as private

    public Node(int id) {
        this.id = id;
    }
    public String toString() { // Always a good idea for debuging
        return "V"+id;
   // JUNG2 makes good use of these.
    }        
}

class Edge { 
    Context context;  
    Time time;
    Value value;
    int id;
    public Edge(int id, Context context, Time time, Value value) {
        this.id = id; // This is defined in the outer class.
        this.context = context;
        this.time = time;
        this.value = value;
    } 
    public String toString() { // Always good for debugging
        return "E"+id;
    }
}

从这些数据构建内存中的图形工作正常。我们更接近这个问题。重要的是要注意使用方法save()保存构造的图形到磁盘  DirectedSparseMultigraph对象。在下一步中,构造的DirectedSparseMultigraph通过以下代码行从磁盘加载

    GraphMLReader<DirectedSparseMultigraph<Node, Edge>, Node, Edge> gmlr = null;

    try
    {
        gmlr = new GraphMLReader<DirectedSparseMultigraph<Node, Edge>, Node, Edge>();
    } catch (ParserConfigurationException e1)
    {
        e1.printStackTrace();
    } catch (SAXException e1)
    {
        e1.printStackTrace();
    }

    DirectedSparseMultigraph<Node, Edge> g_new = null;
    try
    {
        gmlr.load("bla.sh", g_new);
    } catch (IOException e)
    {
        e.printStackTrace();
    }

这就是问题出现的地方。错误消息如下:

Exception in thread "main" java.lang.IllegalArgumentException: If no edge factory is supplied, edge id may not be null: {source=V6818, target=V2472}
at edu.uci.ics.jung.io.GraphMLReader.createEdge(GraphMLReader.java:693)
at edu.uci.ics.jung.io.GraphMLReader.startElement(GraphMLReader.java:299)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1343)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2786)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:333)
at edu.uci.ics.jung.io.GraphMLReader.parse(GraphMLReader.java:241)
at edu.uci.ics.jung.io.GraphMLReader.load(GraphMLReader.java:192)
at edu.uci.ics.jung.io.GraphMLReader.load(GraphMLReader.java:201)
at main.Graph.main(Graph.java:99)

如果您有任何想法或提示如何解决此问题,我真的很期待您的留言。 问候 J Bug

1 个答案:

答案 0 :(得分:1)

GraphMLReader有两种方法可以解析您的文件:

(1)您提供节点和边缘工厂;在这种情况下,您的节点和边缘类型可以是您想要的任何内容。 (constructor with factories

(2)您不提供节点和边缘工厂;在这种情况下,您的节点和边缘类型必须是String s。 (constructor without factories

您的代码不提供节点和边缘工厂,而您的Edge类型与String的分配不兼容,因此它会爆炸。不可否认,这在错误消息中并不是非常明显,但在the code中相当清楚。

在这种情况下,您无法真正提供NodeEdge工厂(无需重新设计它们),因为您没有no-arg构造函数。所以你需要重新设计这些类,或者使用两个阶段的过程,即:使用简单的字符串键解析图形节点和边缘+填充元数据,然后根据数据结构构建新的图形GraphMLReader提供。