All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgrapht.io.DIMACSImporter Maven / Gradle / Ivy

/*
 * (C) Copyright 2010-2017, by Michael Behrisch, Joris Kinable, Dimitrios 
 *     Michail and Contributors.
 *
 * JGraphT : a free Java graph-theory library
 *
 * This program and the accompanying materials are dual-licensed under
 * either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation, or (at your option) any
 * later version.
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation.
 */
package org.jgrapht.io;

import org.jgrapht.*;

import java.io.*;
import java.util.*;

/**
 * Imports a graph specified in DIMACS format.
 *
 * 

* See {@link DIMACSFormat} for a description of all the supported DIMACS formats. * *

* In summary, one of the most common DIMACS formats was used in the * 2nd DIMACS challenge and follows * the following structure: * *

 * {@code
 * DIMACS G {
 *    c  ignored during parsing of the graph
 *    p edge  
 *    e  
 *    e  
 *    e  
 *    e  
 *    ...
 * }
 * }
 * 
* * Although not specified directly in the DIMACS format documentation, this implementation also * allows for the a weighted variant: * *
 * {@code 
 * e    
 * }
 * 
* * Note: the current implementation does not fully implement the DIMACS specifications! Special * (rarely used) fields specified as 'Optional Descriptors' are currently not supported (ignored). * * @author Michael Behrisch (adaptation of GraphReader class) * @author Joris Kinable * @author Dimitrios Michail * * @param the graph vertex type * @param the graph edge type */ public class DIMACSImporter extends AbstractBaseImporter implements GraphImporter { private final double defaultWeight; // ~ Constructors ---------------------------------------------------------- /** * Construct a new DIMACSImporter * * @param vertexProvider provider for the generation of vertices. Must not be null. * @param edgeProvider provider for the generation of edges. Must not be null. * @param defaultWeight default edge weight */ public DIMACSImporter( VertexProvider vertexProvider, EdgeProvider edgeProvider, double defaultWeight) { super(vertexProvider, edgeProvider); this.defaultWeight = defaultWeight; } /** * Construct a new DIMACSImporter * * @param vertexProvider provider for the generation of vertices. Must not be null. * @param edgeProvider provider for the generation of edges. Must not be null. */ public DIMACSImporter(VertexProvider vertexProvider, EdgeProvider edgeProvider) { this(vertexProvider, edgeProvider, Graph.DEFAULT_EDGE_WEIGHT); } // ~ Methods --------------------------------------------------------------- /** * Import a graph. * *

* The provided graph must be able to support the features of the graph that is read. For * example if the file contains self-loops then the graph provided must also support self-loops. * The same for multiple edges. * *

* If the provided graph is a weighted graph, the importer also reads edge weights. Otherwise * edge weights are ignored. * * @param graph the output graph * @param input the input reader * @throws ImportException in case an error occurs, such as I/O or parse error */ @Override public void importGraph(Graph graph, Reader input) throws ImportException { // convert to buffered BufferedReader in; if (input instanceof BufferedReader) { in = (BufferedReader) input; } else { in = new BufferedReader(input); } // add nodes final int size = readNodeCount(in); Map map = new HashMap(); for (int i = 0; i < size; i++) { Integer id = Integer.valueOf(i + 1); V vertex = vertexProvider.buildVertex(id.toString(), new HashMap()); map.put(id, vertex); graph.addVertex(vertex); } // add edges String[] cols = skipComments(in); while (cols != null) { if (cols[0].equals("e") || cols[0].equals("a")) { if (cols.length < 3) { throw new ImportException("Failed to parse edge:" + Arrays.toString(cols)); } Integer source; try { source = Integer.parseInt(cols[1]); } catch (NumberFormatException e) { throw new ImportException( "Failed to parse edge source node:" + e.getMessage(), e); } Integer target; try { target = Integer.parseInt(cols[2]); } catch (NumberFormatException e) { throw new ImportException( "Failed to parse edge target node:" + e.getMessage(), e); } String label = "e_" + source + "_" + target; V from = map.get(source); if (from == null) { throw new ImportException("Node " + source + " does not exist"); } V to = map.get(target); if (to == null) { throw new ImportException("Node " + target + " does not exist"); } try { E e = edgeProvider.buildEdge(from, to, label, new HashMap()); graph.addEdge(from, to, e); if (graph.getType().isWeighted()) { double weight = defaultWeight; if (cols.length > 3) { weight = Double.parseDouble(cols[3]); } graph.setEdgeWeight(e, weight); } } catch (IllegalArgumentException e) { throw new ImportException("Failed to import DIMACS graph:" + e.getMessage(), e); } } cols = skipComments(in); } } private String[] split(final String src) { if (src == null) { return null; } return src.split("\\s+"); } private String[] skipComments(BufferedReader input) { String[] cols = null; try { cols = split(input.readLine()); while ((cols != null) && ((cols.length == 0) || cols[0].equals("c") || cols[0].startsWith("%"))) { cols = split(input.readLine()); } } catch (IOException e) { // ignore } return cols; } private int readNodeCount(BufferedReader input) throws ImportException { final String[] cols = skipComments(input); if (cols[0].equals("p")) { if (cols.length < 3) { throw new ImportException("Failed to read number of vertices."); } Integer nodes; try { nodes = Integer.parseInt(cols[2]); } catch (NumberFormatException e) { throw new ImportException("Failed to read number of vertices."); } if (nodes < 0) { throw new ImportException("Negative number of vertices."); } return nodes; } throw new ImportException("Failed to read number of vertices."); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy