Applying the visitor pattern for detecting cycles in a graph - java

i need to detect if in a directed graph there is a cycle , something likes the topological sort , but i wanna use the visitor pattern.. Do you have some ideas ? I can use the arraylist of nodes , and edges or other structures (not array) .

The visitor pattern really can't achieve such a thing in its purest form.
Remember that a visitor pattern typically has the "visitor" travelling the web of objects, but the web of objects "directing" the visitor. Since the visitor is effectively path-unaware, it prevents certain kinds of breakage.
from the wikipedia example of the Visitor pattern (in Java)
class Car implements CarElement {
CarElement[] elements;
public Car() {
//create new Array of elements
this.elements = new CarElement[] { new Wheel("front left"),
new Wheel("front right"), new Wheel("back left") ,
new Wheel("back right"), new Body(), new Engine() };
}
public void accept(CarElementVisitor visitor) {
for(CarElement elem : elements) {
elem.accept(visitor);
}
visitor.visit(this);
}
}
note the Car accept method. It ensures that all the sub-elements of the car are covered, encapsulating navigation, yet exposing the ability to apply external functions against the entire data structure.
Since your code requires knowledge of how the data structure is wired together, the visitor pattern is poorly suited to the task. If a visitor encounters a circular data structure, the future visitors will get stuck in the same loop, not visiting some of the data, breaking the contract between the Visitor and the VisitAcceptors.
Now you might be able to somewhat achieve the goal, provided you had "possibly circular" links in the visiting path not followed. You'd still have to ensure all nodes of the graph were followed in the visiting path, just by other branches of the visiting path. Then your visitor would basically become a large collection of nodes that could be hit by the non-travelled back links, but by the time you implemented such an odd solution, you'd wonder why you bothered with the visitor part.

Related

Farmer, Wolf, Goat and Cabbage Breadth-first and Depth-first Search in Java

So, I started this problem where I have to bring a cabbage, wolf, and goat across the river without leaving the cabbage with the goat or the wolf and goat by themselves on the same side.
I started and got sorely confused about how to approach this. Basically I was thinking of adding a bunch of vertexes that would lead to the correct outcome, and just have the program demonstrate breadth-first and depth-first searching without having a complex vertices generation process. Am I thinking about this correctly, or is there a better approach?
Here is my code for the main method so far.
package project3;
import java.util.*;
import java.io.*;
public class Project3 extends Network{
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Project3().run();
} //main method
public void run()
{
String start ="fwgcR",
finish = "Rfwgc";
addVertex(start);
addVertex("fwgRc");
addVertex("fwcRg");
addVertex(finish);
//Breadth First iterator
Iterator<String> itr = network.breadthFirstIterator (start);
while (itr.hasNext())
System.out.print (itr.next() + " ");
//Depth First Iterator
itr = network.depthFirstIterator (start);
while (itr.hasNext())
System.out.print (itr.next() + " ");
} // method run
}
The usual approach for problem-solving search is to develop a state space representation. You seem to want to explicitly represent all the states and transitions in a graph, but the more common approach is to design a state representation and then a process that will generate the successor states from a given state. The search process then relies on the successor state generator to expand a current state and carry out the search.
I strongly recommend using a state generating function rather than building a complete state graph from the start.
In your case, the state representation might be as simple as the current side of the river for each object (farmer, wolf, goat, and cabbage). The successor states for a given state are the farmer and possibly one of the objects currently on the same side as the farmer switching sides. You would probably want to filter out inadmissible states as part of the successor generation function. I don't recommend a string to represent the states, although it could work. An array of four booleans (each representing, say, "right side of the river") would be easier to work with.
I don't know why you want to use both breadth-first and depth-first search, but yes, either of those can be used to find the correct order of steps to a solution.
Using strings to represent the nodes in your graph is a bad idea. It will be much more trouble than necessary to generate the outgoing vertices from each node, and to avoid adding redundant nodes.
The next thing you need to do is define a class to represent each node on the graph, and write a function to find adjacent nodes, filtering out any nodes with the goat and cabbage or goat and wolf on the same side of the river and alone.

Implementing search functionality in a tree structure with many different types of nodes

I have a tree structure that consists of dozens of types of nodes (each type of node inherits from a NodeBase class).
I would like to perform searches on the tree to return a reference to a specific node. For example, suppose there is some Company tree, which contains Department nodes amongst other types of nodes. Department nodes consist of Employee nodes. It is assumed that an employee must be part of a department, and can be in exactly one department.
Currently, it is designed so that each node has a list of child nodes of type NodeBase. A tree can become quite large, with hundreds of thousands of nodes at times. Insertion/deletion operations are seldom used, while search operations should not take "too long" for these big trees.
Suppose I want to get a reference to an employee node whose employee ID field equals some string that I provide. I don't know which department the employee is in, so I'd have to perform a search through all of the nodes hoping to find a match. Not all nodes have an employee ID field; departments, for example, do not have them.
I am not sure what is the best way to implement the search functionality, given this tree structure design.
There are probably better ways to design how the data is stored in the first place (eg: using a database?) but currently I am stuck with a tree.
Data structures are the way you organize your data, and the way you organize data depends on how you actually use those pieces of information.
A tree is the right data structure to answer questions like "get all descendents of node X", but doesn't help you to solve the problem of "find me the object with the property X set to Y" (at least not your tree: you could certainly use a tree internally to keep a sorted index as I explain later).
So I think the best way to solve this is using two separate data structures to organize the data: a tree made of NodeBase objects to reflect the hierarchical relationship among NodeBase's, and a sorted index to make the searches with a decent performance. This will introduce a synchronization problem, though, because you'll have to keep the two data structures in sync when nodes are added/removed. If it doesn't happen too frequently, or simply the search performance is critical, then this may be the right way.
Assuming that your tree is DAG (directed acyclic tree), use DFS or BFS, for example. Here's a simple BFS:
public NodeBase findEmployee (NodeBase root, Integer employeeId) {
Queue<NodeBase> q= new LinkedList<NodeBase>();
q.add(root);
while (!q.isEmpty()) {
NodeBase node= q.poll();
if (node instanceof Employee) {
if (((Employee)node).getId().equals(employeeId))
return node;
}
for (NodeBase child : node.getChildren())
q.add(child);
}
}
}
EDIT: Visitor pattern
Or as Brabster suggested, you can use a visitor pattern. A NodeBase should implement an accept(IVisitor visitor) method:
public class NodeBase {
//your code
public void accept(IVisitor visitor) {
visitor.visit(this);
for (NodeBase node : getChildren()) {
node.accept(visitor);
}
}
}
IVisitor is just an intercace:
public interface IVisitor {
public void visit(NodeBase node);
}
And you need a proper implementation that will do the search:
public class SearchVisitor implements IVisitor {
private Integer searchId;
public SearchVisitor(Integer searchId) {
this.searchId= searchId;
}
#Override
public void visit(NodeBase node) {
if (node instanceof Employee) {
if (((Employee)node).getId().equals(searchId)) {
System.out.println("Found the node " + node.toString() + "!");
}
}
}
}
And now, you just simply call it:
NodeBase root= getRoot();
root.accept(new SearchVisitor(getSearchId()));
It looks like there are two parts to this question -- decomposition of class hierarchies and the implementation of the search algorithm.
In the Java world there are two possible solutions to the problem of decomposition:
Object oriented decomposition, which has a local nature, and
Type checking decomposition using instanceof and type casting.
Functional languages (including Scala) offer pattern matching, which is really a better approach to implement the type checking decomposition.
Due to the fact that there is a need to work with a data structure (tree) where elements (nodes) can be of varying types, the nature of the decomposition is definitely not local. Thus, the second approach is really the only option.
The search itself can be implemented using, for example, binary search tree algorithm. Such tree would need to be constructed out of your data, where the decision where to place a certain node should depend on the actual search criterion. Basically, this means you'd need to have as many trees as there are different search criteria, which is in essence a way to build indexes. The database engines use more sophisticated structures than the binary search tree. For example, red-black trees, but the idea is very similar.
BTW the binary search tree would have a homogeneous nature. For example, if the search pertains to Employee by Department, then the search tree would consist only of nodes associated with Employee instances. This removes the decomposition problem.

Creating a Graph Query Language (Node/Edge/HyperEdge)

I'm creating an API that encapsulates JPA objects with additional properties and helpers. I do not want the users to access the database, because I have to provide certain querying functionality for the consumers of the API.
I have the following:
Node1(w/ attributes) -- > Edge1(w/ attr.) -- > Node2(w/ attr.)
and
Node1(w/ attributes) -- > |
Node2(w/ attributes) -- > | -- > HyperEdge1(w/ attr.)
Node3(w/ attributes) -- > |
Basically a Node can be of a certain type, which would dictate the kind of attributes available. So I need to be able to query these "paths" depending on different types and attributes.
For example: Start from a Node, and find a path typeA > typeB & attr1 > typeC.
So I need to do something simple, and be able to write the query as a string, or maybe a builder pattern style.
What I have so far, is a visitor pattern set up to traverse the Nodes/Edges/HyperEdges, and this allows for a sort of querying, but it's not very simple, since you have to create a new visitor for new types of queries.
This is my implementation so far:
ConditionImpl hasMass = ConditionFactory.createHasMass( 2.5 );
ConditionImpl noAttributes = ConditionFactory.createNoAttributes();
List<ConditionImpl> conditions = new ArrayList<ConditionImpl>();
conditions.add( hasMass );
conditions.add( noAttributes );
ConditionVisitor conditionVisitor = new ConditionVisitor( conditions );
node.accept( conditionVisitor );
List<Set<Node>> validPaths = conditionVisitor.getValidPaths();
The code above, does a query that checks if the starting node has a mass of 2.5 and a linked node (child) has no attributes. The visitor does a condition.check( Node ) and returns a boolean.
Where do I start with creating a querying language for a graph that is simpler?
Note: I do not have the option of using an existing graph library and I will have hundreds of thousands of nodes, plus the edges..
Personally, I like the idea of the visitor pattern, however it might turn out to expensive to visit all nodes.
Query Interface: If users / other developers are using it, I would use a builder style interface, with readable method names:
Visitor v = QueryBuilder
.selectNodes(ConditionFactory.hasMass(2.5))
.withChildren(ConditionFactory.noAttributes())
.buildVisitor();
node.accept(v);
List<Set<Node>> validPaths = v.getValidPaths();
As pointed out above, this is more or less just syntactic sugar for what you already have (but sugar makes all the difference). I would separate the code for "moving on the graph" (like "check whether visited node fulfills condition" or "check whether connected nodes fulfill condition") from the code that actually checks (or is) a condition. Also, use composites on conditions to build and/or:
// Select nodes with mass 2.5, follow edges with both conditions fulfilled and check that the children on these edges have no attributes.
Visitor v = QueryBuilder
.selectNodes(ConditionFactory.hasMass(2.5))
.withEdges(ConditionFactory.and(ConditionFactory.freestyle("att1 > 12"), ConditionFactory.freestyle("att2 > 23"))
.withChildren(ConditionFactory.noAttributes())
.buildVisitor();
(I used "freestyle" because of missing creativity right now, but the intention of it should be clear) Node that in general this might be two different interfaces in order to not build strange queries.
public interface QueryBuilder {
QuerySelector selectNodes(Condition c);
QuerySelector allNodes();
}
public interface QuerySelector {
QuerySelector withEdges(Condition c);
QuerySelector withChildren(Condition c);
QuerySelector withHyperChildren(Condition c);
// ...
QuerySelector and(QuerySelector... selectors);
QuerySelector or(QuerySelector... selectors);
Visitor buildVisitor();
}
Using this kind of syntactic sugar makes the queries readable from the source code without forcing you to implement your own data query language. The QuerySelector implementations would than be responsible for "moving" around the visited nodes whereas the Conditition implementation would check whether the condition match.
The clear downside of this approach is, that you need to foresee most of the queries in interfaces and need to implement them already.
Scalability with number of nodes: You might need to add some kind of index to speed up finding "interesting" nodes. One idea which is popping up is to add (for each index) a layer to the graph in which each nodes models one of the different attribute settings for the "indexed variable". The normal edges could then connect these index nodes with the nodes in the original graph. The hyper edges on the index could then build a network which is smaller to search on. Of course there is still the boring way of storing the index in a map-like structure with a attributeValue -> node mapping. Which probably is much more performant than the idea above anyway.
If you have some kind of Index make sure that the index can as well receive a visitor such that it does not have to visit all nodes in the graph.
It sounds like you have all the pieces except some syntactic sugar.
How about an immutable style where you create the whole list above like
Visitor v = Visitor.empty
.hasMass(2.5)
.edge()
.node()
.hasNoAttributes();
You can create any kind of linear query pattern using this style; and if you add a some extra state you could even do branching queries by e.g. setName("A") and later .node("A") to return to that point of the query.

Is a Map that contains values that have references to other keys in the Map the simplest form of a directed graph?

Map<K,V<List<K>> graph = new HashMap<K,V<List<K>>();
Are there any major obstacles to using this to represent a directed graph that can be cyclical?
EDIT:
This was more confusing than it probably should have been. This is a conversation graph for an RPG, and here is what I have so far. I was trying to determine if I could refactor this into a simpler form:
Initialized for an NPC:
public interface ConversationGraphI {
void init();
Map<String, DialogueNodeI> getConversation();
void setConversation(Map<String, DialogueNodeI> conversation);
}
A piece of dialogue, with response options:
public interface DialogueNodeI {
String getText();
void setText(String text);
List<ResponseChoiceI> getResponseChoices();
void setResponseChoices(List<ResponseChoiceI> responseChoices);
}
A response choice that can then loop back to another piece of dialogue in the map:
public interface ResponseChoiceI {
String getResponseText();
void setResponseText(String responseText);
String getDialogueKey();
void setDialogueKey(String dialogueKey);
}
I think the main issue with it is that you might not be able to store data about each edge easily. It depends on whether an object of type V will give you that. Still, I agree with Andrei LED's comment that it'd be better to use an explicit Edge type:
Map<K,Collection<Edge<K>>>
If you don't need to store edge metadata at all, then you could go even simpler:
Map<K,Collection<K>>
As an alternative to the all-in-one approach, I've seen graphs represented by two separate collections, one for nodes and one for edges. If N is a node, then something like this:
Collection<N> // nodes
Collection<Edge<N>> // edges between nodes
Well I guess you'd have to use a TreeMap to have your keys ordered by their natural order. If not then it would be an undirect graph now wouldn't it? Other than that, whether it will respect all the other criterias of a direct graph will depend on what actual implementation you give to the Keys and Values objects you put in there.

Java: Object Oriented Design; LinkedList and Stack

I am writing a BFS and DFS in Java. What I was hoping to do was create one class like this:
/** Preforms BFS and DFS on ...
*/
public class Search{
private XXX toSearch;
// where XXX is an interface of Stack and LinkedList that has
// remove() and add() methods.
public Search(boolean isBFS){
if(isBFS)
toSearch = new LinkedList();
else
toSearch = new Stack();
}
public void preformSearch(){
while(toSearch.size() > 0){
preformSearchOn(toSearch.remove()); // <----- KEY LINE
}
}
private void preformSearchOn(...){...}
}
This class can perform BFS and DFS depending on how it is initialized. What is XXX? I don't think that it exists.
I thought that the entire point of object oriented programing is being able to do cool stuff like this.
What is the cleanest way to handle this?
I think you're looking for the Strategy pattern. The way to do this is not Java specific, or other "cool stuff" for this matter. These types of things transcend languages.
To be more concrete, develop two more classes named BfsStrategy and DfsStrategy. Require that each class implement a certain Strategy interface. Use the class you posted to perform operations on them transparently. (Change class/interface names to be more suitable if you need to.)
For example:
public final class Seeker<E, K> {
private final E structure;
private final SearchStrategy strategy;
public Seeker(final E aStructure, final SearchStrategy aStrategy) {
structure = aStructure;
strategy = aStrategy;
}
public boolean search(K aKey) {
return strategy.search(structure, key); //Pretty generic.
}
}
As far as breadth-first and depth-first searches go, one way to unify both would be to write java.util.Iterator implementations for each one. Let that be your unifying abstraction; it's already part of the JDK.
The common interface is java.util.Queue.
As a first-in-first-out queue you can use (for instance) java.util.LinkedList or java.util.ArrayDeque.
As last-in-first-out queue, you can wrap any Deque using java.util.Collections.asLifoQueue.
Stack, together with is superclass Vector, is deprecated, because it synchronizes all method access, which is often unnecessary. I suspect that's why it doesn't implement Queue.
XXX should be of type java.util.AbstractList as both LinkedList and Stack are derived from it.
But that will not solve you're problem, as the remove() method for each class will behave the same way. In order to get different behaviour you will actual need to call the different removale methods: remove() or pop(). And as method these remove() and pop() are both implemented on java.util.Linkedlist (see Queue interface) there is no need to use the java.util.Stack class either.
You could do call the different methods pop() and remove() with in an if statement, but that would be definitly be an OO anti pateern. An basic OO solution would be to implement 3 classes:
Abstract parent named Search Class
BfsSearch: works with remove() in it's search.
DfsSearch: works with pop() in it's search.
This way, the user of this class can work with Search without needing to know if he is using BfsSearch or DfsSearch.
An even more advanced and flexible OO approach would be to use the Strategy pattern as described by mike. But for simple solutions that don't need this kind of flexibility it might be overkill.
BTW an excelent book on OO design that will explain all these kind of choices and patterns is Larman:
Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition)

Categories