I needed a graph structure of key ==>> value such as following image:
Numbers in circle are key of its node.
I wanted access to stored value in key 2-7-6-5 and I wanted by 2-7 key retrieve a sub-graph contains collectin of 2, 6-5, 6-11 keys-values , so I wrote my implementation by nested maps and it worked fine but my question is :
Is there any custom Map implementation or third-party library for solve my situation for cleanup my code from manipulation manually such as String.split or loop and condition statements?
If you are really just looking for a 3rd-Party Java Library to work with graphs take a look at JUNG it has plenty of features for graph manipulation. However, it might be overkill for what you are trying to achieve.
take this one - really good for graph manipulations, and also for dispaying graph structure in swing
<dependency>
<groupId>jgraph</groupId>
<artifactId>jgraph</artifactId>
<version>5.13.0.0</version>
</dependency>
http://www.jgraph.com
This is a fairly simple graph construction and traversal problem. You do not need any libraries. You can do it in a simple java class. For e.g.
http://it-essence.xs4all.nl/roller/technology/entry/three_tree_traversals_in_java
It sounds like you'd want to implement nodes as class instances and links as references. Using maps to implement graph edges would be quite complicated and inefficient. Little wonder you'd want to clean up your code. I'm not sure I understand your problem perfectly, but this ought to be close:
// Null nodes are the simplest type. They represent missing children.
class NullNode {
// Get the values of all leaves descended from this node as a set.
Set<Integer> getValues() { return new HashSet(0); }
// Get the values descended from the node at the end of the given
// key path as a set. For a null node, this should not be called.
Set<Integer> getValues(int [] path, int i) { raise new IllegalOperationException(); }
// Initiate the search for values. The only way that's okay
// for null nodes is when the path is empty.
Set<Integer> getValues(int [] path) {
if (path.length == 0)
return new HashSet(0);
else
raise new IllegalOperationException();
}
}
// A regular node is a null node with a key. It should
// never be instantiated. Use Interior or Leaf nodes for that.
abstract class Node extends NullNode {
int key;
// Initiate the search for values. Only descend if the key matches.
Set<Integer> getValues(int [] path) {
return (path.length > 0 && path[0] == key) ? getValues(path, 1) : new HashSet(0);
}
}
// Interior nodes have two children, which may be Null, Interior, or Leaf.
class InteriorNode extends Node {
Node left, right;
Set<Integer> getValues() {
Set<Integer> v = left.getValues();
v.addAll(right.getValues());
return v;
}
Set<Integer> getValues(int [] path, int i) {
if (i + 1 < path.length) {
// Again we only descend if the key matches.
if (path[i + 1] == left.key) return getValues(left, i + 1);
if (path[i + 1] == right.key) return getValues(right, i + 1);
return new HashSet(0);
}
return getValues(); // Get values from both children.
}
}
// A leaf node has no children and a value.
class LeafNode extends Node {
int value;
Set<Integer> getValues() {
HashSet<Integer> v = new HashSet(1);
v.add(value);
return v;
}
Set<Integer> getValues(int [] path, int i) {
return (i + 1 >= path.length) ? getValues() : new HashSet(0);
}
}
The best graph library which I have found is not written in Java but in Scala and makes usage of some powerful scala features not available in Java, such as abstract types.
It is called Graph for Scala and it is extremely comprehensive, but I have to warn you that while Scala and Java they are intercompatible (you can build them in the same project and call a Java class from a Scala class and vice-versa), some problems might rise when calling Scala from Java when it comes to some features which are not available in Java.
http://www.assembla.com/spaces/scala-graph/wiki
Is there any custom Map implementation or third-party library for solve my situation for cleanup my code from manipulation manually such as String.split or loop and condition statements?
If you want to remove the freedom to written manipulate code then you can create your own libraries. You can easily create libraries in Eclipse by exporting your classes into a Jar file, which I would presume is a trivial task in NetBeans.
If you want to protect against changes to the graph after construction then you need to create an immutable data structure. With an immutable graph structure you have to view the Graph as a Universe, and each operation is a GraphOperation. You can never modify a Graph, only create a new Graph that results from crossing the Graph with your list of GraphOperations. Presuming your Graph structure holds unique node values, this will not pose too much of a problem, since you can happily describe relations using values. Your code will look something like this:
Graph graph2 = graph1.process(graph1.GetTopNode().RemoveLeft());
graph2 = graph2.process(graph2.GetNode(7).AddRight(8));
GetTopNode() returns an object that only provides a view of the nodes. RemoveLeft() returns a GraphOperation object, which Graph.process() uses to create a new graph from the operation. If you want, it could just return a Graph implementation that internally stores a link to graph1, and the list of GraphOperation instances that have been passed into it, allowing you to avoid copying the graph structures too often (pretty much like a string buffer).
If you are looking for Graph database and manipulation in Java, Neo4j might help you. This can be more than what you have bargained for if you are looking for a perfect Graph DB and manipulation API.
It gives you very advanced options to traverse the graph nodes, relationships, auditing. Neo4j is being used across organizations to store very complex hierarchical data, the performance by Neo4j is far better than oracle based R-DB's for complex hierarchical databases.
Related
I have a fairly demanding task and unfortunately I can't get any further. Maybe you have a tip for me:
Goal:
Create a lot of edges with apache gremlin with only with one message
to the gremlin server (kind of bulk operation for creating edges).
The sourceId, the targetId and the type is saved in a list of JAVA pojos.
Use gremlin for java
Do not use IDs from the underlying engine, use some constant property PROP_ID for storing the user-given id
My current approach was:
create a list of map because gremlin java can only inject objects when they're maps or arrays
Object[] edgesMap = edges.stream().map(edge -> {
Map<String, String> m = new HashMap<>();
m.put("sourceId", edge.sourceId);
m.put("targetId", edge.targetId);
m.put("type", edge.type);
return m;
}).collect(Collectors.toList()).toArray();
Now i wanted to inject the object into a traversal and iterate the map. For every value i wanted to create an edge.
GraphTraversal<Vertex, Vertex> traversal = g.withSideEffect("edgeList", edgesMap).V().limit(1).sideEffect(
select("edgeList").unfold().as("edge").sideEffect(
g.V().has(PROP_ID, select("edge").select("targetId")).addE(select("edge").select("type")).from(select("edge").select("sourceId"))
)
);
traversal.iterate();
But unfortunately i cannot use .has in the anonymous traversal because .select(...).select(...) does not inject some constant value but returns a traversal. So i was told in the tinkerpop community that the has-traversal will always be true for every node and as a result for every node some edge is created.
I was told to use the where()-traversal to only get the node that fits with the property PROP_ID and the iterated value from the map. But the where()-function expects some P<String> predicate and with my current knowledge, i'm unable to get the select(...)-values into that predicate.
Maybe someone can help me so that I can either rewrite the traversal or someone has an idea how I can implement the requirements. Thanks! :)
I know similar questions have been asked already, but every time the answers revolve around "use a Map instead".
In my case, I HAVE to use a List. More precisely, I can use other data structures for treatment, but the information will be stored ultimately in the form of a List.
Here is the situation : I have an object, which I will call Sequence, containing a List of objects I will call Phase.
Among other properties, the Phase object is given a UUID through ObjectId
During a given treatment, I have to replace an existing Phase inside the List<Phase> contained in Sequence by another Phase. The input for this are the replacement Phase object and a String value of the ObjectId of the Phase to replace
I was hoping to be able to do something like this using Java8 :
public void replacePhase(Sequence sequence, Phase replacementPhase, String idPhaseToBeReplaced) {
List<Phase> phaseList = sequence.getPhaseslist();
Phase phaseToBeReplaced = phaseList.stream().filter(p -> p.getId().toString().equalsIgnoreCase(idPhaseToBeReplaced)).findFirst().orElse(null);
if (phaseToBeReplaced != null) {
phaseToBeReplaced = replacementPhase;
}
And voilĂ , the List<Phase> would be updated.
I know something like this will work :
public void replacePhase(Sequence sequence, Phase replacementPhase, String idPhaseToBeReplaced) {
List<Phase> phaseList = sequence.getPhaseslist();
Phase phaseToBeReplaced = phaseList.stream().filter(p -> p.getId().toString().equalsIgnoreCase(idPhaseToBeReplaced)).findFirst().orElse(null);
if (phaseToBeReplaced != null) {
int i = phaseList.indexOf(phaseToBeReplaced );
phaseList.set(i, replacementPhase);
phaseToBeReplaced = replacementPhase;
}
But it doesn't seem more efficient that using a for loop on phaseList with a break when finding a Phase with the desired UUID.
So my question is : is there a way, using List data structure, to find an object based on a (in this case, unique) property and then replace said object inside the List by another (of the same type), preserving order? Preferably without iterating over the whole List and using Java8 functionnalities?
In order to make your replace functionality work in short-circuit fashion, use ListIterator:
ListIterator<Phase> iterator = phaseList.listIterator();
while(iterator.hasNext()){
Phase phase = iterator.next();
if(phase.getId().toString().equalsIgnoreCase(idPhaseToBeReplaced)){
iterator.set(replacementPhase);
break;
}
}
In case the id is not unique, just remove the break. Or use List::replaceAll.
You seem to be looking for List#replaceAll such as :
sequence.getPhasesList()
.replaceAll(phase -> phase.getId().toString()
.equalsIgnoreCase(idPhaseToBeReplaced) ? replacementPhase : phase);
If you keep the list sorted you can find the item using binary search, that would be faster than iterating the list.
Collections.binarySearch
If you need to keep it sorted by insertion order, use a LinkedHashMap
I have a hierarchical Data. something like:
The following are the characteristics:
A node can have any number of children
The nodes can be marked as special. Once a node is marked special, the whole subtree starting from that node becomes special.
The following are the operations I want to perform:
Tree.get("a.b.d.g") should give me node g
Tree.set("a.b.d.g",value) which set node g's value
at any node I should know who is the root node
at any node I should if I'm part of special subtree
I should be able to copy/move a subtree in to another tree
I can add new nodes or delete new nodes at every level
I should be able to serialize this data
I can currently think of "hashmap of hashmaps" kind of data structure. I can always cache answer to operations 3 and 4 at every node. Of course I need to clear that cache when I do copy or move etc...
Are there any other ways of implementation to achieve best performance from above operations with minimal memory footprint.
For basic modeling, you should use a Composite pattern:
public class TreeNode {
private String id;
private TreeNode parent;
private List<TreeNode> treeNodes = new ArrayList<>();
...
}
Each node has a String id, a reference to its parent, and references its children.
You can get the top root by iterating on getParent() until its null (use recursion).
For parsing the path imagine something like:
public TreeNode get(final String path) {
if (!path.isEmpty()) {
for (TreeNode treeNode : treeNodes) {
if (path.startsWith(treeNode.getId())) {
return treeNode.get(path.substring(...));
}
}
}
return this;
}
Now if you are looking for a way to store this kind of data (graph like) and to have performant queries on it, you can consider using a graph database as #sebgymn mentioned: Neo4j is a great database for that in java.
It is about using a Connected Data Model with NOSQL. Nodes store data in properties, relationships are also stored and explicitly named in Neo4j and acts as links between nodes. You can then execute queries on a Node (properties, relationships to others...).
Here is link to a presentation: http://fr.slideshare.net/neo4j/data-modeling-with-neo4j
A great tutorial: http://technoracle.blogspot.fr/2012/04/getting-started-with-neo4j-beginners.html
A test graph database to execute queries: http://www.neo4j.org/learn/cypher
For instance: you can try implementing a multi-level pattern tree in neo4j (as in your case it is important to check the top root: so it seems your model has different levels on the tree).
This is a design problem. I'm struggling to create a conceptual model for a problem I'm facing.
I have a graph of a number of objects (<1000). These objects are connected together in a myriad of ways. Each of these objects have some attributes.
I need to be able to access these object via both their connections and their attributes.
For example let us assume following objects -
{name: A, attributes:{black, thin, invalid}, connections: {B,C}}
{name: B, attributes:{white, thin, valid}, connections: {A}}
{name: C, attributes:{black, thick, invalid}, connections: {A,B}}
Now I should be able to query this graph in following ways -
Using attributes -
black - yields [A,C]
black.thick - yields C
Using connections -
A.connections[0].connections[0] - yields A
Using combination thereof -
black[0].connections[0] - yields B
My primary language is Java. But I don't think Java is capable of handling these kinds of beasts. Thus I'm trying to implement this in a dynamic language like Python.
I have also thought about using expression language evaluation like OGNL, or a Graph database. But I'm confused. I'm not interested in coding solutions. But what is the correct way to model such a problem?
It sounds like you have some object model which you want to query in different ways. One solution would be to use Java to create your model and then use a scripting language to support querying against this model in different ways. e.g: Java + Groovy would be my recommendation.
You could use the following Java class for the model.
public class Node {
private String name;
private final Set<String> attributes = new HashSet<String>();
private final List<Node> connections = new ArrayList<Node>();
// getter / setter for all
}
You should then populate a list of such objects with 'connections' property properly populated.
To support different kinds of scripting what you need to do is create a context for the scripts and then populated this context. Context is basically a map. The keys of the map become variables available to the script. The trick is to populate this context to support your querying requirements.
For example in groovy the binding is the context (refer http://groovy.codehaus.org/Embedding+Groovy). So if you populate it the following way your querying needs will be taken care of
Context/Binding Map
1. <Node name(String), Node object instance(Node)>
2. <Attribute name(String), list of nodes having this attribute(List<Node>)>
when you evaluate a script saying 'A.connections[0]', in the binding the object stored against key 'A' would be looked up. Then the returned objects 'connections' property will be accessed. Since that is a list the '[0]' syntax on that is permitted in groovy. This will return the object at index 0. Likewise to support your querying requirements you need to populate the context.
It depends where you want your performance to be.
If you want fast queries, and don't mind a bit of extra time/memory when adding an object, keeping an array/list of pointers to objects with specific attributes might be a good idea (particularly if you know during design-time what the possible attributes could be). Then, when adding a new object, say:
{name: A, attributes:{black, thin, invalid}, connections: {B,C}}
add a new pointer to the black list, the thin list, and the invalid list. Quick queries on connections will probably require keeping a list/array of pointers as a member of the object class. Then when you create an object, add pointers for the correct objects.
If you don't mind slower queries and want to optimize performance when adding objects, a linked list might be a better approach. You can just loop through all of the objects, checking at each one if it satisfies the condition of the query.
In this case, it would still be a good idea to keep member pointers for the connections, if (as your question would seem to indicate) you're looking to do multiple-level queries (i.e. A.connections[0].connections[0]. This will result in extremely poor performance if done via nested loops.)
Hopefully that helps, it really kind of depends on what kind of queries you're expecting to call most frequently.
There is no problem expressing this in Java. Just define classes representing nodes sets of nodes. Assuming that there is a fixed set of attributes, it could look like:
enum Attribute {
BLACK, WHITE, THIN, VALID /* etc. */ ;
}
class Node {
public final String name;
public final EnumSet<Attribute> attrs
= EnumSet.noneOf(Attribute.class);
public final NodeSet connections
= new NodeSet();
public Node(String name)
{
this.name = name;
}
// ... methods for adding attributes and connections
}
and then a class that represents a set of nodes:
class NodeSet extends LinkedHashSet<Node> {
/**
* Filters out nodes with at least one of the attributes.
*/
public NodeSet with(Attribute... as) {
NodeSet out = new NodeSet();
for(Node n : this) {
for(a : as)
if (n.attrs.contains(a)) {
out.add(n);
break;
}
}
return out;
}
/**
* Returns all nodes connected to this set.
*/
public NodeSet connections() {
NodeSet out = new NodeSet();
for(Node n : this)
out.addAll(n.connections);
return out;
}
/**
* Returns the first node in the set.
*/
public Node first() {
return iterator().next();
}
}
(I haven't checked that the code compiles, it's just a sketch.) Then, assuming you have a NodeSet all of all the nodes, you can do things like
all.with(BLACK).first().connections()
I think that solving this problem with a graph makes sense. You mention the possibility of using a graph database which I think will allow you to better focus on your problem as opposed to coding infrastructure. A simple in-memory graph like TinkerGraph from the TinkerPop project would be a good place to start.
By using TinkerGraph you then get access to a query language called Gremlin (also see GremlinDocs)which can help answer the questions you posed in your post. Here's a Gremlin session in the REPL which show how to construct the graph you presented and some sample graph traversals that yield the answers you wanted...this first part simple constructs the graph given your example:
gremlin> g = new TinkerGraph()
==>tinkergraph[vertices:0 edges:0]
gremlin> a = g.addVertex("A",['color':'black','width':'thin','status':'invalid'])
==>v[A]
gremlin> b = g.addVertex("B",['color':'white','width':'thin','status':'valid'])
==>v[B]
gremlin> c = g.addVertex("C",['color':'black','width':'thick','status':'invalid'])
==>v[C]
gremlin> a.addEdge('connection',b)
==>e[0][A-connection->B]
gremlin> a.addEdge('connection',c)
==>e[1][A-connection->C]
gremlin> b.addEdge('connection',a)
==>e[2][B-connection->A]
gremlin> c.addEdge('connection',a)
==>e[3][C-connection->A]
gremlin> c.addEdge('connection',b)
==>e[4][C-connection->B]
Now the queries:
// black - yields [A,C]
gremlin> g.V.has('color','black')
==>v[A]
==>v[C]
// black.thick - yields C
gremlin> g.V.has('width','thick')
==>v[C]
// A.connections[0].connections[0] - yields A
gremlin> a.out.out[0]
==>v[A]
// black[0].connections[0] - yields B
gremlin> g.V.has('color','black')[0].out[0]
==>v[B]
While this approach does introduce some learning curve if you are unfamiliar with the stack, I think you'll find that graphs fit as solutions to many problems and having some experience with the TinkerPop stack will be generally helpful for other scenarios you encounter.
I have a class called Edge, which has attribute source id, target id and weight. I want to store this edge in a set data structure, so in the set there won't be duplicates of edges (i.e: edges with the same source and target id).
The problem is this:
I want to add an Edge to this data-structure. If an edge already exist in the data-structure I don't need to add it again, I just need to add the weight of the existing edge with the edge that I am trying to add.
I am pretty sure that I have to override the add function of the set. Can someone give me a pointer on this? What's the best data structure to use in java for this?
A few suggestions.
The underlying data structure you want is probably a map (with HashMap probably being the best concrete implementation), not a set. The key should be the (source, target) pair, and the value can be your Edge object. If you're super concerned about duplication, there are ways of dealing with that, one of which is to actually store only weight as the value.
Second, this is calling out for a Graph class. If you design the interface well, it hides the internal implementation details. I recommend highly using composition rather than inheritance. In other words, your Graph has-a map, rather than is-a map.
Also take a look at existing code such as JGraphT, which already has a weighted directed graph, the same beast as you describe above. Sometimes it's better not to reinvent things from scratch.
Good luck.
An alternative is to wrap the set of edges in your own class, which provides exactly the interface you wish to support.
This is a specific case of choosing between composition and inheritance. In general, composition is preferred to inheritance, though that too has its place.
For example, here's a rough sketch of a possible class (EDIT: using a Map)
public class Edge { ... }
public class EdgeData {
public Edge getEdge() { ... }
public float getWeight() { ... }
}
public class Edges {
private Map<Edge,EdgeData> m_edges = new HashMap<Edge,EdgeData>();
public addEdge( EdgeData edge ) {
// Do what you've said above.
}
public Map<Edge,EdgeData> getEdges() { return Collections.unmodifiableMap( m_edges ); }
}
Well, the Set.add() method returns a boolean value indicating if a new item was successfully added to the set. If it returns false is because the item was already there. Based on that you could easily write your algorithm. The ugly part is having to iterate the set to update the value, right?
if(!edges.add(newEdge)){
Iterator<Edge> iter = edges.iterator();
while(iter.hasNext()){
Edge edge = iter.next();
if(edge.equals(newEdge)){
edge.updateWeight(newEdge.getWeight()); //this.weight+=moreWeight
}
}
}
Based on this, I assume that what you want is just a way to beautify all this iteration boilerplate code.
A solution that I like is using LambdaJ Collections to update the weight of an existing Edge.
if (!edges.add(newEdge)) {
with(edges).first(is(newEdge)).updateWeight(newEdge.getWeight());
}
I do not know what you are looking for, but this approach would be just three lines of code. Quite simple from my point of view.
I wrote a small example to illustrate better the idea:
Jedi obiwan = new Jedi("Obiwan", 30, 40); // name, age and power
Jedi luke = new Jedi("Luke", 18, 25);
Jedi mace = new Jedi("Mace-Windu", 100, 450);
Jedi yoda = new Jedi("Yoda", 150, 1000);
Jedi obiAgain = new Jedi("Obiwan", 11, 40);
Set<Jedi> jedis = new HashSet<Jedi>(asList(obiwan, luke, mace, yoda));
if (!jedis.add(obiAgain)) {
with(jedis).first(is(obiAgain)).updatePower(obiAgain.getPower());
}
System.out.println(jedis);