In such a network we assume distance vector routing algorithm used. If the link goes down from A to B, A will change its distance vector B and will advertise its neighbor C about that. The question is that since A uses node B to reach D, will A change its distance vector to D?
Yes. If A lost the link to B, A will set all the paths via B by infinity, and wait to recalculate the shortest paths by receiving new broadcast.
In your case, after A lost the link to B, it will set the distance vector (via B to B) and (via B to D) by infinty, and broadcast this to C. After C broadcasts it has (via D to D) = 4 and (via B to B) = 6 to A, A will recalculate and get the new shortest paths (via C to D) = 6 and (via C to B) = 8.
Related
In a directed acyclic graph describing a set of tasks to process, i need to find all tasks that can be processed concurrently. The graph has no loops and is quite small (~1000 nodes, ~2000 edges), performance is not a primary concern.
Examples with desired result:
[] is a group. All tasks in a group must be processed before continuing
[x & y] means x and y can be processed concurrently (x and y in parallel)
x -> y means x and y must be processed sequentially (x before y)
1
a -> [b & c] -> c
2
[a & e] -> b -> c -> [d & f]
3
[ [a -> b] & [e -> f] ] -> [ [c -> d] & g ]
I do not want to actually execute the graph, but rather build a data structure that is as parallel as possible, while maintaining the order. The nomenclature and names of algorithms is not that familiar to me, so i'm having a hard time trying to find similar problems/solutions online.
Mathematically, I would frame this problem as finding a minimally defined series-parallel partial order extending the given partial order.
I would start by transitively reducing the graph and repeatedly applying two heuristics.
If x has one dependent y, and y has one dependency x, merge them into a new node z = [x → y].
If x and y have the same dependencies and dependents, merge them into a new node z = [x & y].
Now, if the input is already series-parallel, the result will be one node. In general, however, this will leave a graph that embeds an N-shaped structure like b → c, b → g, f → g from the last example in the question. This structure must be addressed by adding one or more of b → f, c → f, c → g, f → b, f → c, g → c. But in a different instance, this act would in turn create new N-shaped structures. There's no obvious notion of a closure, which is why this problem feels hard to me.
Some of these choices seem worse than others. For example, c → f forces the sequence b → c → f → g, whereas f → c is the only choice that doesn't increase the length of the critical path.
I guess what I'd try is,
If heuristics 1 and 2 have no targets, form a graph with edges x--y if and only if x and y have either a common dependent or a common dependency, compute the connected components of this graph, and &-merge the smallest component that isn't a singleton, followed by another transitive reduction.
Here's a solution i came up with (pseudocode):
sequence = []
for each (node, depth) in depthFirstSearch(graph)
sequence[depth].push(node)
return sequence
The sequence defines the order to process the graph. If an item in it contains more than one node, they can be processed concurrently.
While this allows for some concurrency, it does not advance as fast as it could. For example, f in the 3rd example in the question would require a to be completed first (as it will be at depth 1, when a and e are depth 0). Ideally work on f could start when e is done.
I'm trying to represent the paths in a railroad as a data structure but I am having a hard time representing turnouts.
This feels like a graph problem, but there is a difference compared to regular graphs.
A railway turnout is a vertex connected to three other vertices. A, B and C.
But, in a railway system the graph is traversed with a direction.
So, you are able to take the path B -> turnout -> A and C -> turnout -> A, but are not able to take the path B -> turnout -> C.
Is there a (graph) data structure which allows for representing paths with directions?
This data structure would provide the base for a software system to automate a small model railroad.
You can represent the turnout as 2 vertices - one for each state of the turnout. So if you have source A and destinations B and C and turnout which can switch between B and C - you will have 2 vertices for this turnout: TB and TC. Also you will have following edges: A->TB, TB->B, A->TC, TC->C
This allows you to travel from A -> TB -> B and from A -> TC -> C. And since you will have no edge between TB and TC - you will not be able to travel from B -> C directly
Each path can be considered as a vertice and a connection between two paths as an edge.
B ->
A
C ->
This can be represented as a graph in a Go map,
Take a look at the following,
In your example directional connection exists from B -> A and C -> A. This can be represented in a map as follows.
graph := map[string][]string{
"B": []string{"A"},
"C": []string{"A"},
}
Each key in the map represents the starting path of a directional connection. Each value in the array of the corresponding key is the destination path.
I find the below code in C++ that insert and traverse a XOR linklist.
How do we remove a node ? As it seems when we remove a node, all the address of the node in the list need to get updated ?
Or my intuition is not correct this time ?
https://en.wikipedia.org/wiki/XOR_linked_list
https://www.geeksforgeeks.org/xor-linked-list-a-memory-efficient-doubly-linked-list-set-1/
https://www.geeksforgeeks.org/xor-linked-list-a-memory-efficient-doubly-linked-list-set-2/
No, you don't update all of the addresses, merely the adjacent ones. Look at the example list; let's extend it two more nodes:
z A B C D E F
<–> z⊕B <–> A⊕C <-> B⊕D <-> C⊕E <-> D⊕F <->
The only values that use the address of C are those for B and D. If we remove C, we need only alter those values by the next ones moving in:
B.link = B.link ⊕ C ⊕ D
D.link = D.link ⊕ C ⊕ B
This gives us
z A B D E F
<–> z⊕B <–> A⊕D <-> B⊕E <-> D⊕F <->
Do you see how that works? There's very little additional work involved: we have already traversed the list to C to find the item to remove; all we need do is keep the back-pointer as we move along (to operate on B), and then take one more step to access D.
I'm having some trouble with a homework question involving using Tarjan's algorithm on a provided graph to find the particular SCC's for that graph. While (according to my professor) I have found the correct SCC's by using the pseudo-code algorithm found here, some of the nodes in my SCC's do not share the same lowest-link number as the root node for that SCC.
From what I can gather from the pseudo-code, this is because if an un-referenced node i (which is the input node for the current recursive call to the algorithm) has an arc to an already visited node i + 1 which is not the root node, then the algorithm sets is LL = MIN(i.LowestLink, (i + 1).index), and (i + 1).index may not be equal to its own lowest-link value anymore.
For example (this is similar to a part of the graph from the problem I'm trying to solve): if we have nodes in N = {a, b, c, d}, and arcs in E = {a ⇒ c, c ⇒ b, c ⇒ d, b ⇒ a, d ⇒ b}, and our root node which we start the algorithm from is a, then:
1.1) We set a.index = 1 (using 1 rather than 0), a.LL = 1, and push a onto the stack; a has a single arc to c, so we check c; finding that it is undiscovered, we call the algorithm on c.
2.1) We set c.index = 2, c.LL = 2, and push c onto the stack; c has two arcs, one to b, and one to d. Assume our for loop checks b first; b is undiscovered, and so we call the algorithm on b.
3.1) We set b.index = 3, b.LL = 3, and push b onto the stack; b has one arc to a; checking a we find that it is already on the stack, and so (by the pseudo-code linked above) we set b.LL = MIN(b.LL, a.index) = a.index = 1; b has no further arcs, so we exit our for loop, and check if b.LL = b.index, it does not, so we end this instance of the algorithm.
2.2) Now that the recursive call on b has ended, we set c.LL = MIN(c.LL, b.LL) = b.LL = 1. c still has the arc from c to d remaining; checking d we find it is undefined, so we call the algorithm on d.
4.1) d.index is set to 4, d.LL is set to 4, and we push d onto the stack. d has one arc from d to b, so we check b; we find that b is already in the stack, so we set d.LL = MIN(d.LL, b.index) = b.index = 3. d has no further arcs, so we exit our for loop and check if d.LL = d.index; it does not, so we end this instance of the algorithm.
2.3) With the recursive call on d ended, we again set c.LL = MIN(c.LL, d.LL) = c.LL = 1. c has no further arcs, and so we end our for loop. We check to see if c.LL = c.index; it does not, so we end this instance of the algorithm.
1.2) With the recursive call on c ended, we set a.LL = MIN(a.LL, c.LL) = 1. a has no further arcs, so we end our for loop. We check if a.LL = a.index; they are equal, so we have found a root node for this SCC; we create a new SCC, and pop each item in the stack into this SCC until we find a in the stack (wich also goes into this SCC).
After these steps all the nodes in the graph are discovered, so running the algorithm with the other nodes initially does nothing, we have one SCC = {a, b, c, d}. However, d.LL = 3 which is not equal to the rest of the nodes lowest-links (which are all 1).
Have I done something wrong here? Or is it possible in this situation to have an SCC with differing lowest-links among its nodes?
I have seen some similar questions here, but the answers dont solve my problem.
I want to draw a graph. I write some code like this:
digraph {
{rank = same a b c d e f }
a -> b -> c -> d -> e -> f
a -> f
b -> d -> f
b -> f
}
but the result is that some of the edges overlapped each other.
So my question is how can I fix the edge to make it not overlap
and I also wanna know how can I give the node a fixed position? There is no problem this graph. But some times when I wanna a graph with a sequence of
a b c d e f
but when i create some edges and the sequence will change like:
a->e b c d f
You can use the attribute pos of a node or edge to specify coordinates. To see where dot places your nodes and edges you can simply run dot myinputfile.dot without any output parameter. This will produce the dot file with added coordinates (among other additions).
Based on this you can force dot to place some or all nodes at certain coordinates.