patternjavaMinor
Simple data structures for representing graphs in Java
Viewed 0 times
simplegraphsjavafordatastructuresrepresenting
Problem
Motivation
I do a lot of graph-theoretic code, and, by now, I feel substantial need for data structures that can represent weighted graphs, both directed and undirected. Up till now, I was in a habit of writing a graph node type along with the weight function (in my prior posts, something like
Objective
Now, I have this notion that each graph node is represented simply by an integer. For example, in
Implementation
(If you want to run the unit tests, see this.)
AbstractGraph.java:
```
package net.coderodde.graph;
import java.util.Set;
/**
* This class defines the API for graph data structures. The actual nodes are
* represented as integers. The client programmer should always be able to map
* his domain specific nodes to the integers.
*
* Not only the query methods return a boolean value, but any other method
* returns a boolean value indicating whether the structure of the graph has
* changed.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Jan 10, 2016)
*/
public abstract class AbstractGraph {
protected int edges;
/**
* Returns the number of nodes in this graph.
*
* @return the size of this graph.
*/
public abstract int size();
/**
* Returns the number of edges in this graph.
*
* @return the number of edges.
*/
public abstract int getNumberOfEdges();
/**
* Adds the node with ID {@code nodeId} to this graph.
*
* @param nodeId the ID of the node to add.
* @return {@code true} if the structure of this graph has changed, which is
* the same as that the added node was not present in the graph.
*/
public abstract boolean addNode(int nodeId);
I do a lot of graph-theoretic code, and, by now, I feel substantial need for data structures that can represent weighted graphs, both directed and undirected. Up till now, I was in a habit of writing a graph node type along with the weight function (in my prior posts, something like
DirectedGraphNode and DirectedGraphWeightFunction). So, basically, my "graphs" were just silly Lists of DirectedGraphNode.Objective
Now, I have this notion that each graph node is represented simply by an integer. For example, in
DirectedGraph, a node with integer ID of, say, 123 is mapped into two integer lists: one for incoming nodes (parents) and one for outgoing nodes (children).Implementation
(If you want to run the unit tests, see this.)
AbstractGraph.java:
```
package net.coderodde.graph;
import java.util.Set;
/**
* This class defines the API for graph data structures. The actual nodes are
* represented as integers. The client programmer should always be able to map
* his domain specific nodes to the integers.
*
* Not only the query methods return a boolean value, but any other method
* returns a boolean value indicating whether the structure of the graph has
* changed.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Jan 10, 2016)
*/
public abstract class AbstractGraph {
protected int edges;
/**
* Returns the number of nodes in this graph.
*
* @return the size of this graph.
*/
public abstract int size();
/**
* Returns the number of edges in this graph.
*
* @return the number of edges.
*/
public abstract int getNumberOfEdges();
/**
* Adds the node with ID {@code nodeId} to this graph.
*
* @param nodeId the ID of the node to add.
* @return {@code true} if the structure of this graph has changed, which is
* the same as that the added node was not present in the graph.
*/
public abstract boolean addNode(int nodeId);
Solution
I am not sure if using
I would throw illegal argument exception from addEdge() instead of returning false for self-loops. Same with getEdgeWeight() - if user forgets to check returned value that NaN might propagate through lots of code and it will be hard to track where did it come from.
Are you sure that DirectedGraph.clearNode() updates edge count correctly?
You also might consider using internal Node class for DirectedGraph, something like:
instead of
You might also want to extract common set of tests that should be valid for both UndirectedGraph and DirectedGraph instead of having just separate test files.
parent/child for in/out is a good idea. I would throw illegal argument exception from addEdge() instead of returning false for self-loops. Same with getEdgeWeight() - if user forgets to check returned value that NaN might propagate through lots of code and it will be hard to track where did it come from.
Are you sure that DirectedGraph.clearNode() updates edge count correctly?
You also might consider using internal Node class for DirectedGraph, something like:
static class Node {
Map outEdges;
Map inEdges;
}
Map nodes;instead of
Map> parentMap;
Map> childMap;You might also want to extract common set of tests that should be valid for both UndirectedGraph and DirectedGraph instead of having just separate test files.
Code Snippets
static class Node {
Map<Integer, Double> outEdges;
Map<Integer, Double> inEdges;
}
Map<Integer, Node> nodes;Map<Integer, Map<Integer, Double>> parentMap;
Map<Integer, Map<Integer, Double>> childMap;Context
StackExchange Code Review Q#116686, answer score: 2
Revisions (0)
No revisions yet.