I'am trying to develop an algorithm using Pseudo code to display all possible routes between 2 Nodes. I have looked at the dijkstra algorithm but I'am having some difficulty trying to create an algorithm using only Pseudo Code.
Possible Routes Between node 7 and 5
I have identified all the possible Routes (Without passing the same node twice)
7 -> 4 -> 5
7 -> 6 -> 2 ->1 -> 8 -> 5
7-> 6 -> 4 -> 5
7 -> 6 -> 2 -> 1 -> 3 -> 5
Set of Nodes: 1,2,3,4,5,6,7,8
Link between Nodes 1+2, 1+3, 1+8, 2+6, 3+5, 4+5, 4+6, 4+7, 5+8, 6+7.
Using DFS: The idea is to do Depth First Traversal of given directed
graph. Start the traversal from source. Keep storing the visited
vertices in an array say ‘path[]’. If we reach the destination vertex,
print contents of path[]. The important thing is to mark current
vertices in path[] as visited also, so that the traversal doesn’t go
in a cycle.
Java Implementation:
// Prints all paths from
// 's' to 'd'
public void printAllPaths(int s, int d)
{
boolean[] isVisited = new boolean[v];
ArrayList pathList = new ArrayList<>();
//add source to path[]
pathList.add(s);
//Call recursive utility
printAllPathsUtil(s, d, isVisited, pathList);
}
// A recursive function to print
// all paths from 'u' to 'd'.
// isVisited[] keeps track of
// vertices in current path.
// localPathList<> stores actual
// vertices in the current path
private void printAllPathsUtil(Integer u, Integer d,
boolean[] isVisited,
List localPathList) {
// Mark the current node
isVisited[u] = true;
if (u.equals(d))
{
System.out.println(localPathList);
}
// Recur for all the vertices
// adjacent to current vertex
for (Integer i : adjList[u])
{
if (!isVisited[i])
{
// store current node
// in path[]
localPathList.add(i);
printAllPathsUtil(i, d, isVisited, localPathList);
// remove current node
// in path[]
localPathList.remove(i);
}
}
// Mark the current node
isVisited[u] = false;
}
You can check another ways here https://efficientcodeblog.wordpress.com/2018/02/15/finding-all-paths-between-two-nodes-in-a-graph/
Related
I am looking at the following Geeks for Geeks problem:
Given two sorted linked lists consisting of N and M nodes respectively. The task is to merge both of the list (in-place) and return head of the merged list.
Example 1
Input:
N = 4, M = 3
valueN[] = {5,10,15,40}
valueM[] = {2,3,20}
Output: 2 3 5 10 15 20 40
Explanation: After merging the two linked
lists, we have merged list as 2, 3, 5,
10, 15, 20, 40.
Below answer is the GFG answer. I don't understand how its space complexity is O(1). We are creating a new node, so it must be O(m+n).
Node* sortedMerge(Node* head1, Node* head2)
{
struct Node *dummy = new Node(0);
struct Node *tail = dummy;
while (1) {
if (head1 == NULL) {
tail->next = head2;
break;
}
else if (head2 == NULL) {
tail->next = head1;
break;
}
if (head1->data <= head2->data){
tail->next = head1;
head1 = head1->next;
}
else{
tail->next = head2;
head2 = head2->next;
}
tail = tail->next;
}
return dummy->next;
}
Could someone explain how the space complexity is O(1) here?
I can't understand how it's space complexity is O(1). Since we are creating a new node so it must be O(m+n).
Why should it be O(m+n) when it creates one node? The size of that node is a constant, so one node represents O(1) space complexity. Creating one node has nothing to do with the size of either of the input lists. Note that the node is created outside of the loop.
It is actually done this way to keep the code simple, but the merge could be done even without that dummy node.
I'm doing a nested iteration over two lists, in which I am populating some StringBuffers, like this:
var int_list = [1, 2, 3];
var letters_list = ['a', 'b', 'c'];
var row_strings = List.filled(3, StringBuffer());
var single_buffer = StringBuffer();
int_list.asMap().forEach((int_index, column) {
letters_list.asMap().forEach((letter_index, letter) {
// debug the writing operation
print('writing $letter_index - $letter');
row_strings[letter_index].write(letter);
// try a buffer not in a list as a test
if (letter_index == 0) {
single_buffer.write(letter);
}
});
});
print(single_buffer);
print(row_strings);
What I expect to happen is that in the list of StringBuffers, buffer 0 gets all the 'a's, buffer 1 gets all the 'b's, and buffer 3 the 'c'.
The debug output confirms that the writing operation is doing the right thing:
writing 0 - a
writing 1 - b
writing 2 - c
writing 0 - a
writing 1 - b
writing 2 - c
writing 0 - a
writing 1 - b
writing 2 - c
and the single string buffer gets the right output:
aaa
But the output of the list is this:
[abcabcabc, abcabcabc, abcabcabc]
What is going on here? There seems to be some strange behaviour when the StringBuffers are in a list.
Your problem is this line:
var row_strings = List.filled(3, StringBuffer());
This constructor is documented as:
List.filled(int length, E fill, {bool growable: false})
Creates a list of the given length with fill at each position.
https://api.dart.dev/stable/2.10.5/dart-core/List/List.filled.html
So what you are doing is creating a single StringBuffer instance and uses that on every position in your row_strings list.
What you properly want, is to create a new StringBuffer for each position in the list. You need to use List.generate for that:
List.generate(int length,E generator(int index), {bool growable: true})
Generates a list of values.
Creates a list with length positions and fills it with values created by calling generator for each index in the range 0 .. length - 1 in increasing order.
https://api.dart.dev/stable/2.10.5/dart-core/List/List.generate.html
Using that, we end up with:
final row_strings = List.generate(3, (_) => StringBuffer());
We don't need the index argument in our generator so I have just called it _. The function (_) => StringBuffer() will be executed for each position in the list and saved. Since out function returns a new instance of StringBuffer each time it is executed, we will end up with a list of 3 separate StringBuffer instances.
I'm currently working on a graph where nodes are connected via probabilistic edges. The weight on each edge defines the probability of existence of the edge.
Here is an example graph to get you started
(A)-[0.5]->(B)
(A)-[0.5]->(C)
(B)-[0.5]->(C)
(B)-[0.3]->(D)
(C)-[1.0]->(E)
(C)-[0.3]->(D)
(E)-[0.3]->(D)
I would like to use the Neo4j Traversal Framework to traverse this graph starting from (A) and return the number of nodes that have been reached based on the probability of the edges found along the way.
Important:
Each node that is reached can only be counted once. -> If (A) reaches (B) and (C), then (C) need not reach (B). On the other hand if (A) fails to reach (B) but reaches (C) then (C) will attempt to reach (B).
The same goes if (B) reaches (C), (C) will not try and reach (B) again.
This is a discrete time step function, a node will only attempt to reach a neighboring node once.
To test the existence of an edge (whether we traverse it) we can generate a random number and verify if it's smaller than the edge weight.
I have already coded part of the traversal description as follows. (Here it is possible to start from multiple nodes but that is not necessary to solve the problem.)
TraversalDescription traversal = db.traversalDescription()
.breadthFirst()
.relationships( Rels.INFLUENCES, Direction.OUTGOING )
.uniqueness( Uniqueness.NODE_PATH )
.uniqueness( Uniqueness.RELATIONSHIP_GLOBAL )
.evaluator(new Evaluator() {
#Override
public Evaluation evaluate(Path path) {
// Get current
Node curNode = path.endNode();
// If current node is the start node, it doesn't have previous relationship,
// Just add it to result and keep traversing
if (startNodes.contains(curNode)) {
return Evaluation.INCLUDE_AND_CONTINUE;
}
// Otherwise...
else {
// Get current relationhsip
Relationship curRel = path.lastRelationship();
// Instantiate random number generator
Random rnd = new Random();
// Get a random number (between 0 and 1)
double rndNum = rnd.nextDouble();
// relationship wc is greater than the random number
if (rndNum < (double)curRel.getProperty("wc")) {
String info = "";
if (curRel != null) {
Node prevNode = curRel.getOtherNode(curNode);
info += "(" + prevNode.getProperty("name") + ")-[" + curRel.getProperty("wc") + "]->";
}
info += "(" + curNode.getProperty("name") + ")";
info += " :" + rndNum;
System.out.println(info);
// Keep node and keep traversing
return Evaluation.INCLUDE_AND_CONTINUE;
} else {
// Don't save node in result and stop traversing
return Evaluation.EXCLUDE_AND_PRUNE;
}
}
}
});
I keep track of the number of nodes reached like so:
long score = 0;
for (Node currentNode : traversal.traverse( nodeList ).nodes())
{
System.out.print(" <" + currentNode.getProperty("name") + "> ");
score += 1;
}
The problem with this code is that although NODE_PATH is defined there may be cycles which I don't want.
Therefore, I would like to know:
Is there is a solution to avoid cycles and count exactly the number of nodes reached?
And ideally, is it possible (or better) to do the same thing using PathExpander, and if yes how can I go about coding that?
Thanks
This certainly isn't the best answer.
Instead of iterating on nodes() I iterate on the paths, and add the endNode() to a set and then simply get the size of the set as the number of unique nodes.
HashSet<String> nodes = new HashSet<>();
for (Path path : traversal.traverse(nodeList))
{
Node currNode = path.endNode();
String val = String.valueOf(currNode.getProperty("name"));
nodes.add(val);
System.out.println(path);
System.out.println("");
}
score = nodes.size();
Hopefully someone can suggest a more optimal solution.
I'm still surprised though that NODE_PATH didn't not prevent cycles from forming.
Traversal API is giving different result for seemingly same declaration. In method 1. I took method 1 sample from neo4j's site. And tried to restructure it in method 2. However, apparently there is not difference, both methods are producing different output. Method2 is completely skipping LIKE relationship. Even if I change the sequence in method1 like putting depthFirst() in last, the output changes.
It will be great if someone could please help me understand this different output?
Method 1:
void depthFirst() {
GraphDatabaseBuilder graphDbBuilder = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder(storeDir);
GraphDatabaseService graphDb = graphDbBuilder.newGraphDatabase();
String output = "";
int i = 0;
try (Transaction tx = graphDb.beginTx()) {
Node node = graphDb.findNode(LabelTyeps.Person, "name", "Joe");
for (Path position : graphDb.traversalDescription().depthFirst()
.relationships(RelationshipTypes.KNOWS)
.relationships(RelationshipTypes.LIKES, Direction.INCOMING)
.evaluator(Evaluators.toDepth(5)).traverse(node)) {
output += position.toString() + ":"
+ (String) position.endNode().getProperty("name")
+ "\n";
}
System.out.println(output);
}
graphDb.shutdown();
}
Output of method 1:
(3):Joe
(3)<--[LIKES,1]--(8):Lisa
(3)<--[LIKES,1]--(8)--[KNOWS,2]-->(4):Lars
(3)<--[LIKES,1]--(8)--[KNOWS,2]-->(4)--[KNOWS,4]-->(7):Dirk
(3)<--[LIKES,1]--(8)--[KNOWS,2]-->(4)--[KNOWS,4]-->(7)--[KNOWS,5]-->(6):Peter
(3)<--[LIKES,1]--(8)--[KNOWS,2]-->(4)--[KNOWS,4]-->(7)--[KNOWS,5]-->(6)--[KNOWS,7]-->(5):Sara
(3)<--[LIKES,1]--(8)--[KNOWS,2]-->(4)<--[KNOWS,3]--(9):Ed
Method 2 (Just changed the way travDesc is structured)
try (Transaction tx = graphDb.beginTx()) {
Node node = graphDb.findNode(LabelTyeps.Person, "name", "Joe");
TraversalDescription travDesc = graphDb.traversalDescription();
travDesc.depthFirst();
travDesc.relationships(RelationshipTypes.KNOWS);
travDesc.relationships(RelationshipTypes.LIKES, Direction.INCOMING);
travDesc.evaluator(Evaluators.toDepth(5));
for (Path position : travDesc.traverse(node)) {
// System.out.println("Loop count: " + ++i);
output += position.toString() + ":"
+ (String) position.endNode().getProperty("name")
+ "\n";
// System.out.println(output);
}
System.out.println(output);
}
Output of method 2
(3):Joe
(3)--[KNOWS,6]-->(5):Sara
(3)--[KNOWS,6]-->(5)<--[KNOWS,7]--(6):Peter
(3)--[KNOWS,6]-->(5)<--[KNOWS,7]--(6)<--[KNOWS,5]--(7):Dirk
(3)--[KNOWS,6]-->(5)<--[KNOWS,7]--(6)<--[KNOWS,5]--(7)<--[KNOWS,4]--(4):Lars
(3)--[KNOWS,6]-->(5)<--[KNOWS,7]--(6)<--[KNOWS,5]--(7)<--[KNOWS,4]--(4)<--[KNOWS,3]--(9):Ed
(3)--[KNOWS,6]-->(5)<--[KNOWS,7]--(6)<--[KNOWS,5]--(7)<--[KNOWS,4]--(4)<--[KNOWS,2]--(8):Lisa
Sample data:
create (:Person {name:"Joe"})
,(:Person{name:"Lars"})
,(:Person{name:"Sara"})
,(:Person{name:"Peter"})
,(:Person{name:"Dirk"})
,(:Person{name:"Lisa"})
,(:Person{name:"Ed"})
match (a:Person{name:"Lisa"}), (b:Person{name:"Joe"}) create (a) - [:LIKES] -> (b)
match (a:Person{name:"Lisa"}), (b:Person{name:"Lars"}) create (a) - [:KNOWS] -> (b)
match (a:Person{name:"Ed"}), (b:Person{name:"Lars"}) create (a) - [:KNOWS] -> (b)
match (a:Person{name:"Lars"}), (b:Person{name:"Dirk"}) create (a) - [:KNOWS] -> (b)
match (a:Person{name:"Dirk"}), (b:Person{name:"Peter"}) create (a) - [:KNOWS] -> (b)
match (a:Person{name:"Joe"}), (b:Person{name:"Sara"}) create (a) - [:KNOWS] -> (b)
match (a:Person{name:"Peter"}), (b:Person{name:"Sara"}) create (a) - [:KNOWS] -> (b)
TraversalDescription is a immutable fluent API, quoting form http://neo4j.com/docs/java-reference/current/javadocs/org/neo4j/graphdb/traversal/TraversalDescription.html
A traversal description is immutable and each method which adds or modifies the behavior returns a new instances that includes the new modification, leaving the instance which returns the new instance intact.
I am learning linked list operations and have a question related to parameter passing.
Question 1:
I am creating a simple linked list with three values 1->2->3. And am trying to print it.
Below is my code. I am creating a node "first" in my main and am passing it to the method "createlinkedlist". I am using a pointer "head" and updating it within the method. But I see that the values of "head" are retained correctly outside the method "createlinkedlist". I dont understand how this is happening. I was thinking I should use referencial parameter passing like
void createLinkedList(struct node * & head) or void createLinkedList(struct node ** head)
instead of
void createLinkedList(struct node * head)
to get the correct values reflected outside the function. What am I missing here? Why am I able to see the correct values inside the printList method?
struct node
{
int data;
struct node * next;
};
void createLinkedList(struct node * head)
{
struct node * second = (node *)malloc(sizeof(node));
struct node * third = (node *)malloc(sizeof(node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
}
void printList(struct node * first)
{
struct node * current = first;
while(current)
{
printf("%d",current->data);
current = current->next;
}
}
void main()
{
struct node * first = (node *)(malloc(sizeof(node)));
createLinkedList(first);
printList(first);
}
Question 2: I am using the same program as above , but adding a push function
void push(struct node *& first, int data)
{
struct node * newnode = (node*)malloc(sizeof(node));
newnode->data = data;
newnode->next = first;
first = newnode;
}
Now I see that unless I use a "&" for the first parameter in the push(), I am not able to see the updations in the printList method. It makes sense to me because we usually need to use a referncial parameter to make the local function changes seen outside the function. So if the list expects a referencial parameter here, why does it behave differently in the question 1 case.?
Pls. let me know.
Regarding Question 1)
You are not changing the pointer head in your createLinkedList method; you are changing the contents of the node that head points to. So of course you see that change after having called createLinkedList.
Regarding Question 2)
In the second case, you are actually adding a new node and you need to change the head pointer to point to the new head of the linked list, whereas in the first case, you keep the head of the list stable and add new nodes to the tail of the list. So you don't need to get the new address of the head of the list back to the caller, since the address of the head didn't change.
I would also create a node constructor function:
struct node * make_node(int data)
{
struct node * tmp = (node *)malloc(sizeof(node));
if (!tmp) {
/* error handling for malloc failure */
}
tmp->next = NULL;
tmp->data = data;
return tmp;
}
And another point:
If I were you, if I wrote a push function that added nodes to the head of the list, I would return the new head of the list explicitly:
struct node * push(const struct node * head, int data) {
struct node * fresh = make_node(data)
fresh->next = head;
return fresh;
}
Calling this like so:
struct node * head = make_node(1);
head = push(head, 2);
This is easier to understand than figuring out that push(head, 1) changes the head. But it's a question of style.
Change
struct node * first = (node *)(malloc(sizeof(node)));
struct node * second = (node *)(malloc(sizeof(node)));
struct node * third = (node *)(malloc(sizeof(node)));
parts to
struct node * first = (struct node *)(malloc(sizeof(struct node)));
struct node * second = (struct node *)(malloc(sizeof(struct node)));
struct node * third = (struct node *)(malloc(sizeof(struct node)));
. Since you initialized "node" without "typedef", "struct" needs to written before usage of "node" every time.
Since you're talking about references I'll assume you're using C++.
You would want to pass in struct node *& head if you're going to modify the pointer to head, but in your example you want to only modify the head node itself, and not the pointer to it, which is why you simply pass a pointer to it to let you look up the address. When you dereference the pointer via head->... you are looking up the location of head in memory and then moving to its data or next field. Alternatively, you could pass in the head as a reference: struct node & head, and modify things like head.data directly.
Your push needs to have either a reference to the first pointer (struct node *& first), or a pointer to the "first" pointer (struct node **first) so that you can actually modify the pointer itself. This is what's happening on the line:
first = newnode;
Alternatively, if you used struct node **first, you would do:
*first = newnode;
Both cases here for push are modifying a pointer to a struct node, as opposed to modifying a struct node itself.