I'm trying to create a structure for a graph. So far I'm trying to make up how I should create some classes for edges.
Edges in graphs can be
Regular,
Directed, Weighted (or any of the above).
So what do you think is the best way to organize this class, I was thinking of creating a interface IEdge, and then create the classes
public interface IEdge{
}
public class DirectedEdge implements IEdge{}
public class WeightedEdge implements IEdge{}
But now I've come with a problem, it's not very flexible, what if I want the following
public class DirectedWeightedEdge implements IEdge{}
How would you code this?
This is no OOP exercise -- I mean, use logic first and then look at the patterns. A directed and an undirected graphs are very different beasts. A directed edge has a start and an end, an undirected one has just two nodes. You may call them start and end in order to get a common base, but there's no such thing as directedness to be added to an edge.
At the same time, edges may have colors, weights, prices, length, capacity, etc. Do you really want to implement ColoredWeightedPricedHavingLenghtCapacityLimitedEdge? Or do you want to use 5 decorators? I hope you don't.
My first point is that the "directedness" doesn't fit nicely in any pattern. You could use an attribute "isDirected" or whatever, and maybe you don't need it at all as most graphs don't mix different kinds of edges. So a single attribute per Graph should do. Quite often, an undirected edge gets represented by a pair of two directed ones.
My second point is that things like weight should in general not be forcibly put in the edge. Using a Map<IEdge, Double> as a property of the Graph does a better job. You can still use objects like Edge and Node, which precludes confusing them (what could easily happen in C where you'd probably use their ids), but keep their properties external.
Why would you explicitly create edges at all? In every graph implementation I've done so far edges existed just implicitly in the node objects. In every node you'll want an array of adjacent nodes - if you need them weighted just add an integer.
Direction follows quite naturally from that as well (well a bidirectional graph is easily represented by a unidirectional..). Obviously you could also save them as an adjacency matrix if the graph is small enough - that's quite nice for parallel algorithms.. but then if performance is important we're talking about sizes where the complete matrix is unuseable.
Edit: After comments I think I should clarify that a bit: Using an Edge class that keeps additional information about the edge (color, weight) is fine, but I'd always use it as part of a specific node: I.e. something like this - in C I'd use a struct for that.
class Node {
List<Edge> children;
class Edge {
int weight;
Color color;
Node dest;
}
}
I'd use a mixture of inheritance and the aforementioned decorator pattern.
Directed and undirected edges behave quite differently, they are mandatory and are mutually exclusive. Therefore they should be the only two implementations of the Edge interface.
Weights, however, are just something you can bolt on an existing edge, so the decorator pattern is the most appropiate for them.
But to return to square one for a moment, depending on how much shared code directed and undirected edges will have, maybe an Edge abstract class would be better than an interface. Of course the "correct" solution is to have both: an interface, implemented by an abstract class, extended by two concrete classes. But in this case this sounds like overengineering.
Use of the decorator pattern may be appropriate here:
http://en.wikipedia.org/wiki/Decorator_pattern
basically, you would have a base class implementing IEdge, and DirectedEdgeDecorator and WeightedEdgeDecorator classes that also implement the IEdge interface. The *Decorator classes would 'wrap' the base edge class and add the additional functionality to it. With this pattern, you can stack multiple decorators on an IEdge, one over the other to modify its behavior in different ways.
You could separate the edge information from the adjacency information. That means you don't duplicate edge data and instead store them in an adjacency list.
public class Node<TEdge> {
class AdjacencyInfo {
Node<TEdge> node;
TEdge edge;
public AdjacencyInfo(Node<TEdge> node, TEdge edge) {
// ....
}
}
bool isDiGraph;
List<AdjacencyInfo> adj;
///.... constructor, other methods
public TEdge ConnectTo(Node<TEdge> node) {
TEdge e = new TEdge();
AdjacencyInfo a0 = new AdjacencyInfo(node, e);
this.adj.Add(a0);
if (!isDiGraph) {
AdjacencyInfo a1 = new AdjacencyInfo(this, e);
node.adj.Add(a1);
}
return e; // return the edge so caller is able to set edge properties (weight, color, etc)
}
}
Something like this should work and clearly solves the directed/non-directed problem. I'm not aware of how much of this can be accomplished using Java generics as they're mostly unusable for other things than avoiding typecasts in containers, but in case you need to be able to handle only weighted edges then you can avoid generics by setting the weight to 1 or whatever makes sense.
one type, with two properties
type Edge
boolean directed = false;
number weight = 1;
Related
I'm studying for technical interviews and graphs are kind of hard for me. I'm easy with adjacency matrix but confused with implementation of adjacency lists.
Problem is that most of the implementations of adjacency lists, that I see online (Example1, Example2 and Example3) don't use nodes at all. They just use a HashMap of ints and LinkedLists. Is this even correct? Because the definition (Wikipedia) says that it consists of vertices or nodes. Moreover most implementations of graphs using Adjacency matrix use nodes as opposed to ints. Example4. Am I missing something is this puzzle?
I understand that using ints as opposed to nodes is more space efficient, however it leads to many more complications. For Example, check out this piece of code from example1 -
// add edge from vertices v1 to v2
void addEdge(int v1,int v2){
adj.get(v1).add(v2);
}
its purpose is to add an edge from v1 to v2. It completely ignores the possibility that there may be more than one vertices with same int value, in which case it leaves open the possibility that the method addEdge() can add an edge between unintended vertices.
So are implementations of Adjacency lists in Example1,2,3 wrong? If they are right, will it be bad if I implement an adjacency list using nodes instead of ints? I don't want my interviewers to think I'm some idiot lol
You can use Node(that contains the datatype) or use the datatype (in your examples Integer) straight away and they will both work
Using Node however is a better choice for several reasons
Avoid the problems you rightly mentioned with duplicate data values
Using a Node is more object oriented. It allows the Graph class to work with any datatype that the Node holds. This makes the code more portable since the graph can work with String, Long, Integer etc
To take advantage of the portability I mentioned above, a Node class should be defined like this
class Node<T>{
T data;
}
Therefore you should always use a Node (containing the datatype) in interviews as it looks better and shows you care about designing proper code.
Hope it helps!
This is sort of an follow up to the first post I made, lets say I got two classes:
public class Carinfo {
private String carname;
//The Carinfo[] value is set when making a new car
//so for the object ford the array holds 3 null pointers
private Carinfo [] value;
Carinfo (String someCar, int carValue) {
this.carname = someCar;
this.value = new Carinfo[carValue];
}
}
And the second class:
public class CarPark {
HashMap<String, Carinfo> carGarage;
CarPark() {
carGarage = new HashMap<String, CarInfo>();
Carinfo ford = new Carinfo("Ford", 3);
Carinfo audi = new Carinfo("Audi", 2);
carGarage.put("Ford", ford);
carGarage.put("Audi", audi);
}
}
So let's say for whatever reason I want the object ford who has 3 null pointers
in its Carinfo array, to point at the object audi.
Meaning I can go through the Carinfo objects and list the pointers each car
has to other cars.
Think of it as a family, I want to see what cars are related to each other.
I am having a hard time creating a method that will point to other objects
in my Carinfo HashMap.
Any "pointers"? If anything is unclear please let me rephrase or try to explain it better.
Cheers
I don't really understand what you're trying to do. One way to realize that is to provide a specific method to add a relation. For example, with your array you could do that:
public class CarInfo {
private Carinfo[] value;
public void addCarInfo(CarInfo carInfo, int position) {
value[position] = carInfo;
}
}
Anyway, it is not a good idea to have an array, you should use a List.
I would recommend not storing the relationships between cars inside the Carinfo objects themselves. Instead, you should use a general-purpose graph library (or write your own general-purpose graph library).
As you probably know, a graph is a set of nodes and edges, and each edge represents a relationship between two nodes. The notion that your current code describes is really just a directed graph: each car is a node, and each car can hold some number of references to the other cars, where each reference represents an edge pointing out from that car.
Graphs are such a common abstraction in math and computer science that plenty of libraries have been implemented to represent graphs, with the side benefit that several popular problems are solved for any code that uses the libraries (for instance, finding a multistep relationship between two cars using the fewest number of edges, or finding the smallest number of edges needed in the graph to ensure that all the cars are still indirectly connected). I would recommend searching for already-implemented graph libraries, and then using the one with the best features for your overall problem. If this is a homework assignment, though, you should probably implement your own graph library. This isn't too hard: you need to store nodes and edges somehow (you can just keep a list of nodes, and you could use an edge list or adjacency matrix to store edges), and you will need to provide the algorithms you care about in a somewhat more general form. This may seem like more work, but the benefits of making your code more modular will pay off quickly. You'll create fewer bugs in the first place, since each part of your code performs only one job, and you'll be able to fix bugs more easily and quickly, probably saving you time overall.
For starters you'll need accessing methods on your CarInfo object in order to play with the value array you've set up.
public CarInfo[] getCarValue() {
return value;
}
Now, when you're playing in a method you can call it as follows:
CarInfo[] fordValueArray = carGarage.get("Ford").getCarValue();
This array now points to the one you created on the 3rd command of CarPark().
With that we can do:
fordValueArray[0] = audi;
Now, that all said, it seems a little unclear why you'd set up a class relation like this. The naming of value is seemingly non-intuitive because at face value what you've asked is how we can have a car's value relate to a number of other cars independantly. Ford's first value is an Audi? What are the other two values? Why would we be limited to 3 at all?
I'm implementing some algorithms to teach myself about graphs and how to work with them. What would you recommend is the best way to do that in Java? I was thinking something like this:
public class Vertex {
private ArrayList<Vertex> outnodes; //Adjacency list. if I wanted to support edge weight, this would be a hash map.
//methods to manipulate outnodes
}
public class Graph {
private ArrayList<Vertex> nodes;
//algorithms on graphs
}
But I basically just made this up. Is there a better way?
Also, I want it to be able to support variations on vanilla graphs like digraphs, weighted edges, multigraphs, etc.
Each node is named uniquely and knows who it is connected to. The List of connections allows for a Node to be connected to an arbitrary number of other nodes.
public class Node {
public String name;
public List<Edge> connections;
}
Each connection is directed, has a start and an end, and is weighted.
public class Edge {
public Node start;
public Node end;
public double weight;
}
A graph is just your collection of nodes. Instead of List<Node> consider Map<String, Node> for fast lookup by name.
public class Graph {
List<Node> nodes;
}
If you need weighted edges and multigraphs, you might want to add another class Edge.
I would also recommend using generics to allow specifying which sub-class of Vertex and Edge are currently used. For example:
public class Graph<V extends Vertex> {
List<V> vertices;
...
}
When it comes to implementing graph algorithms, you could also define interfaces for your graph classes on which the algorithms can operate, so that you can play around with different implementations of the actual graph representation. For example, simple graphs that are well-connected might be better implemented by an adjacency matrix, sparser graphs might be represented by adjacency lists - it all depends...
BTW Building such structures efficiently can be quite challenging, so maybe you could give us some more details on what kind of job you would want to use them for? For more complex tasks I would suggest you have a look at the various Java graph libraries, to get some inspiration.
Take a look at the http://jung.sourceforge.net/doc/index.html graph library. You can still practice implementing your own algorithms (maybe breadth-first or depth-first search to start), but you don't need to worry about creating the graph structure.
Why not keep things simple and use an adjacency matrix or an adjacency list?
Time ago I had the same problem and did my own implementation. What I suggest you is to implement another class: Edge. Then, a Vertex will have a List of Edge.
public class Edge {
private Node a, b;
private directionEnum direction; // AB, BA or both
private int weight;
...
}
It worked for me. But maybe is so simple. There is this library that maybe can help you if you look into its code: http://jgrapht.sourceforge.net/
I'd recommend graphviz highly when you get to the point where you want to render your graphs.
And its companions: take a look at Laszlo Szathmary's GraphViz class, along with notugly.xls.
Even at the time of this question, over 3 years ago, Sage (which is completely free) existed and was pretty good at graph theory. But, in 2012 it is about the best graph theory tool there is. Thus, Sage already has a huge amount of graph theory material built in, including other free and open source stuff that is out there. So, simply messing around with various things to learn more is easy as no programming is required.
And, if you are interested in the programming part as well, first Sage is open source so you can see any code that already exists. And, second, you can re-program any function you want if you really want to practice, or you can be the first to program something that does not already exist. In the latter case, you can even submit that new functionality and make Sage better for all other users.
At this time, this answer may not be that useful to the OP (since it has been 3 years), but hopefully it is useful to any one else who sees this question in the future.
Adjacency List implementation of Graph is appropriate for solving most of the graph related problems.
Java implementation of the same is here on my blog.
class Graph<E> {
private List<Vertex<E>> vertices;
private static class Vertex<E> {
E elem;
List<Vertex<E>> neighbors;
}
}
A simple representation written by 'Robert Sedgwick' and 'Kevin Wayne' is available at http://algs4.cs.princeton.edu/41graph/Graph.java.html
Explanation copied from the above page.
The Graph class represents an undirected graph of vertices
named 0 through V - 1.
It supports the following two primary operations: add an edge to the graph,
iterate over all of the vertices adjacent to a vertex. It also provides
methods for returning the number of vertices V and the number
of edges E. Parallel edges and self-loops are permitted.
By convention, a self-loop v-v appears in the
adjacency list of v twice and contributes two to the degree
of v.
This implementation uses an adjacency-lists representation, which
is a vertex-indexed array of Bag objects.
All operations take constant time (in the worst case) except
iterating over the vertices adjacent to a given vertex, which takes
time proportional to the number of such vertices.
When learning algorithms, the programming language (Java) should not be considered in deciding the representation. Each problem could benefit from a unique representation, and moreover designing it can add a bit of learning. Solve the problem first without relying on a particular language, then the representation for any particular language will flow naturally.
Of course, general representations and libraries are useful in real-world applications. But some of them could benefit from some customization as well. Use the other answers to know the different techniques available, but consider customization when appropriate.
class Vertex {
private String name;
private int score; // for path algos
private boolean visited; // for path algos
List<Edge> connections;
}
class Edge {
private String vertex1Name; // same as Vertex.name
private String vertex2Name;
private int length;
}
class Graph {
private List<Edge> edges;
}
I'm implementing a graph (as in Vertices, Edges, not cartesian). I'm modelling the graph as a physical collection of Nodes (a class I've made).
I want to have a collection of Forces, as Vectors (in the Maths sense), to represent the forces acting upon each node, and ideally I would like to be able to perform a lookup with a Node as a key, which sounds to me like some kind of Hash Lookup Table.
What's a good collection to use, or will I have to make my own?
If anything needs clarifying, just ask.
Thanks
If I have understood your needs correctly, you basically want to do a one-to-many mapping of Node->Vector.
Provided your Node properly implements hashCode() and equals(), you could use a Multimap from Google Guava. This provides the Map<Node,Collection<Vector>> mapping automatically.
The benefit of using Multimap is that you don't need to do this:
Collection<Vector> vectors = nodeToVectorMapping.get(node);
if (vectors == null) {
vectors = new HashSet<Vector>();
nodeToVectorMapping.put(node, vectors);
}
vectors.add(vector);
instead, you only need to do this:
nodeToVectorMapping.put(node,vector);
The Multimap takes care of checking whether the inner Collection exists or not. If you find yourself going into a multithreaded environment, the 'do it by hand' approach would involve synchronising to ensure that two threads didn't create the Collection at the same time, and so-on. Google's Guava helps a lot with all of that, and a lot more besides.
As a big fan of Google Collections (the original home of Multimap before it was absorbed into the larger Guava project), I should also point you in the direction of MapMaker, which has all sorts of amazing goodness in it that you will perhaps find useful - size limitations, concurrency levels, lazy initialisation of Values based upon keys, that sort of thing. I've used these in a highly-concurrent application and they've saved my life on many an occasion! :)
You could simply add the vector as a field in your Node class.
public class Node {
private ForceVector force = ForceVector.getZeroForceVector();
public ForceVector getForceVector() {
return force;
}
public void addForceVector(ForceVector forceToAdd) {
force = force.add(forceToAdd);
}
}
I'm imagining ForceVector to be some (immutable) class you have written to describe a force vector.
If you have several forces acting on each node, you need to map a node to a collection of fources, for instance by using a HashMap<Node, Set<Vector>>. Just remember to properly implement equals and hashCode for your Nodes.
Others may suggest to you, to put the forces acting on a node, in a field in the node class. This may or may not be a good alternative. If you aim to have a graph-framework reusable in other applications, you may be better off with a separate node-to-forces-map.
I want to implement in Java a class for handling graph data structures. I have a Node class and an Edge class. The Graph class maintains two list: a list of nodes and a list of edges. Each node must have an unique name. How do I guard against a situation like this:
Graph g = new Graph();
Node n1 = new Node("#1");
Node n2 = new Node("#2");
Edge e1 = new Edge("e#1", "#1", "#2");
// Each node is added like a reference
g.addNode(n1);
g.addNode(n2);
g.addEdge(e1);
// This will break the internal integrity of the graph
n1.setName("#3");
g.getNode("#2").setName("#4");
I believe I should clone the nodes and the edges when adding them to the graph and return a NodeEnvelope class that will maintain the graph structural integrity. Is this the right way of doing this or the design is broken from the beginning ?
I work with graph structures in Java a lot, and my advice would be to make any data member of the Node and Edge class that the Graph depends on for maintaining its structure final, with no setters. In fact, if you can, I would make Node and Edge completely immutable, which has many benefits.
So, for example:
public final class Node {
private final String name;
public Node(String name) {
this.name = name;
}
public String getName() { return name; }
// note: no setter for name
}
You would then do your uniqueness check in the Graph object:
public class Graph {
Set<Node> nodes = new HashSet<Node>();
public void addNode(Node n) {
// note: this assumes you've properly overridden
// equals and hashCode in Node to make Nodes with the
// same name .equal() and hash to the same value.
if(nodes.contains(n)) {
throw new IllegalArgumentException("Already in graph: " + node);
}
nodes.add(n);
}
}
If you need to modify a name of a node, remove the old node and add a new one. This might sound like extra work, but it saves a lot of effort keeping everything straight.
Really, though, creating your own Graph structure from the ground up is probably unnecessary -- this issue is only the first of many you are likely to run into if you build your own.
I would recommend finding a good open source Java graph library, and using that instead. Depending on what you are doing, there are a few options out there. I have used JUNG in the past, and would recommend it as a good starting point.
It isn't clear to me why you are adding the additional indirection of the String names for the nodes. Wouldn't it make more sense for your Edge constructor's signature to be something like public Edge(String, Node, Node) instead of public Edge (String, String, String)?
I don't know where clone would help you here.
ETA: If the danger comes from having the node name changed after the node is created, throw an IllegalOperationException if the client tries to call setName() on a node with an existing name.
In my opinion you should never clone the element unless you explicitly state that your data structure does that.
The desired functionality of most things needs the actual object to be passed into the data structure by-reference.
If you want to make the Node class safer, make it an inner class of the graph.
Using NodeEnvelopes or edge/node Factories sounds like overdesign to me.
Do you really want to expose a setName() method on Node at all? There's nothing in your example to suggest that you need that. If you make both your Node and Edge classes immutable, most of the integrity-violation scenarios you're envisioning become impossible. (If you need them to be mutable but only until they're added to a Graph, you could enforce this by having an isInGraph flag on your Node/Edge classes that is set to true by Graph.Add{Node, Edge}, and have your mutators throw an exception if called after this flag is set.)
I agree with jhkiley that passing Node objects to the Edge constructor (instead of Strings) sounds like a good idea.
If you want a more intrusive approach, you could have a pointer from the Node class back to the Graph it resides in, and update the Graph if any critical properties (e.g., the name) of the Node ever change. But I wouldn't do that unless you're sure you need to be able to change the names of existing Nodes while preserving Edge relationships, which seems unlikely.
Object.clone() has some major problems, and its use is discouraged in most cases. Please see Item 11, from "Effective Java" by Joshua Bloch for a complete answer. I believe you can safely use Object.clone() on primitive type arrays, but apart from that you need to be judicious about properly using and overriding clone. You are probably better off defining a copy constructor or a static factory method that explicitly clones the object according to your semantics.
In addition to the comments by #jhkiley.blogspot.com, you can create a factory for Edges and Nodes that refuses to create objects with a name that was already used.