this is the result of my python script using pydot that tries to draw a logic gate graph, I am having trouble getting the edges to enter and exit in the correct position on the node. Due to this, the edges seem to enter and leave a node with no rhyme or reason in regard to the position. Is there a way for me to dictate how the edges enter and leave a node
Graph image
Related
My assignment asks:
In a game, a set of nodes is connected via some set of one-way edges.
At every node there is an object to pick up. Design an algorithm to find a path that you can follow to collect all objects, if this is possible. To make your task easier, you know that starting from any node, no matter what path you follow, you will never get back to the same node.
My idea here is if I start a node at the beginning, then simply I can follow the path to collect all the nodes. However, I'm stuck on which method should I used to find the starting point. Since the question mentions all the edges are one-way which means this is direct graph. If I starting from a node in the middle, how is that possible to go through all the nodes without going back to the same node.
In addition, could someone explain what exactly one-way edges means, because I'm not sure I understand correctly on this question.
As it is an assignment, here is a hint only - as the graph is acyclic, then the only case where you would be able to visit every node is if there is a path through each node in order.
a--->b--->c
\ /
\->d--/
There is no path than goes through all of a,b,c and d.
a--->b----->c
\ \ /
\--->d--/
there is an order a,b,d,c which goes through all nodes.
So you need to look for a means to order nodes in an acyclic graph in a before/after relationship.
I came across this problem at a coding site and I have no idea on how to solve it. The editorial is not available nor was I able to find any related article online. So I am asking this here.
Problem:
You have a graph G that contains N vertices and M edges. The vertices are numbered from 1 through N. Also each node is colored either Black or White. You want to calculate the shortest path from 1 to N such that the difference of black and white nodes is at most 1.
As obvious as it is, applying straight forward Dijkstra's Algorithm will not work. Any help is appreciated. Thank you!
We can consider a modified graph and run Dijkstra on this one:
For each node in the original graph, the modified graph will have multiple meta vertices (theoretically, infinitely many) that each correspond to a different black-white difference. You only need to create the nodes as you explore the graph with Dijkstra. Thus, you won't need infinitely many nodes.
The edges are then pretty simple (you can also create them while exploring). If you are currently at a node with black-white difference d and the original graph has an edge to a white node, then you create an edge to the respective node with black-white difference d-1. If the original graph has an edge to a black node, you create an edge in the modified graph to the respective node with black-white difference d+1. You don't necessarily need to treat them as different nodes. You can also store the Dijkstra variables in the node grouped by black-white difference.
Running Dijkstra in this way will give you the shortest paths to any node with any black-white difference. As soon as you reach the target node with an acceptable black-white difference, you are done.
While I was in the shower today, I had a thought - How difficult would it be to write an algorithm to traverse a weighted di-graph and find the shortest path while allowed to skip a fixed number of edges s. I started thinking about even one skip, and for the brute force method it seems to multiply the problem by the number of edges in your graph, as you have to find the shortest path for each case where an edge is set to 0 cost and then compare across all graphs. I don't know if there are any algorithms that do this, but a cursory search of google didn't show any.
My first question would be for skipping the most costed edge(s), but it's also an interesting problem to examine having to find a path assuming you skip the least costed edge(s).
This is just to satisfy my curiosity, so no rush.
Thanks!
What follows is the logic of how to solve this problem. The way to solve this type of problem is to consider a graph composed of two copies of the original graph you want to traverse, which I'll describe how to create. For your sake, draw a small graph, and then draw it topologically sorted (which helps with the visualization, but is not necessary in the program.) Next, draw a copy of that graph a few inches above the original. You're in the bottom section of this graph when you have not yet used your skip, and you're in the top part when you have used your skip. Let's call the nodes in the bottom graph A1, A2, A3 ... and the nodes in the top graph B1, B2, B3 ... If, in your original graph, node 1 is connected to nodes 2, then your new graph has edges A1->A2, B1->B2, and a free connection, A1->B2 (with edge cost 0).
Consider the following original graph, where you start at the black node, and desire to end up at the blue node.
Your new graph will look like the following, where you again start at black and wish to go to the blue node.
At each location in the bottom half of the graph, you have not used your skip, and thus can either skip (moving to the top part of the graph) or can move normally, going to another node in the bottom graph.
You can then use any of the standard graph traversal algorithms.
I'm not sure exactly sure what the correct terminology is for my question so I'll just explain what I want to do. I have a directed graph and after I delete a node I want all independently related nodes to be removed as well.
Here's an example:
Say, I delete node '11', I want node '2' to be deleted as well(and in my own example, they'll be nodes under 2 that will now have to be deleted as well) because its not connected to the main graph anymore. Note, that node '9' or '10' should not be deleted because node '8' and '3' connect to them still.
I'm using the python library networkx. I searched the documentation but I'm not sure of the terminology so I'm not sure what this is called. If possible, I would want to use a function provided by the library than create my own recursion through the graph(as my graph is quite large).
Any help or suggestions on how to do this would be great.
Thanks!
I am assuming that the following are true:
The graph is acyclic. You mentioned this in your comment, but I'd like to make explicit that this is a starting assumption.
There is a known set of root nodes. We need to have some way of knowing what nodes are always considered reachable, and I assume that (somehow) this information is known.
The initial graph does not contain any superfluous nodes. That is, if the initial graph contains any nodes that should be deleted, they've already been deleted. This allows the algorithm to work by maintaining the invariant that every node should be there.
If this is the case, then given an initial setup, the only reason that a node is in the graph would be either
The node is in the root reachable set of nodes, or
The node has a parent that is in the root reachable set of nodes.
Consequently, any time you delete a node from the graph, the only nodes that might need to be deleted are that node's descendants. If the node that you remove is in the root set, you may need to prune a lot of the graph, and if the node that you remove is a descendant node with few of its own descendants, then you might need to do very little.
Given this setup, once a node is deleted, you would need to scan all of that node's children to see if any of them have no other parents that would keep them in the graph. Since we assume that the only nodes in the graph are nodes that need to be there, if the child of a deleted node has at least one other parent, then it should still be in the graph. Otherwise, that node needs to be removed. One way to do the deletion step, therefore, would be the following recursive algorithm:
For each of children of the node to delete:
If that node has exactly one parent: (it must be the node that we're about to delete)
Recursively remove that node from the graph.
Delete the specified node from the graph.
This is probably not a good algorithm to implement directly, though, since the recursion involved might get pretty deep if you have a large graph. Thus you might want to implement it using a worklist algorithm like this one:
Create a worklist W.
Add v, the node to delete, to W.
While W is not empty:
Remove the first entry from W; call it w.
For each of w's children:
If that child has just one parent, add it to W.
Remove w from the graph.
This ends up being worst-case O(m) time, where m is the number of edges in the graph, since in theory every edge would have to be scanned. However, it could be much faster, assuming that your graph has some redundancies in it.
Hope this helps!
Let me provide you with the python networkX code that solves your task:
import networkx as nx
import matplotlib.pyplot as plt#for the purpose of drawing the graphs
DG=nx.DiGraph()
DG.add_edges_from([(3,8),(3,10),(5,11),(7,11),(7,8),(11,2),(11,9),(11,10),(8,9)])
DG.remove_node(11)
connected_components method surprisingly doesn't work on the directed graphs, so we turn the graph to undirected, find out not connected nodes and then delete them from the directed graph
UG=DG.to_undirected()
not_connected_nodes=[]
for component in nx.connected_components(UG):
if len(component)==1:#if it's not connected, there's only one node inside
not_connected_nodes.append(component[0])
for node in not_connected_nodes:
DG.remove_node(node)#delete non-connected nodes
If you want to see the result, add to the script the following two lines:
nx.draw(DG)
plt.show()
I'm having trouble finding an algorithm for my problem.
I have a grid of 8x8 blocks, each block has a value ranging from 0 to 9. And I want to find collections of connected blocks that match a total value of for example 15. My first approach was to start of at the border, that worked fine. But when starting in the middle of the grid my algorithm gets lost.
Would anyone know a simple algorithm to use or can you point me in the right direction?
Thanks!
As far as I know, no simple algorithm exists for this. As for pointing you in the right direction, an 8x8 grid is really just a special case of a graph, so I'd start with graph traversal algorithms. I find that in cases like this, it sometimes helps to think how you would solve the problem for a smaller grid (say, 3x3 or 4x4) and then see if your algorithm scales up to "full size."
EDIT :
My proposed algorithm is a modified depth-first traversal. To use it, you'll have to convert your grid into a graph. The graph should be undirected, since connected blocks are connected equally in both directions.
Each graph node represents a single block, containing the block's value and a visited variable. Edge weights represent their edges' resistance to being followed. Set them by summing the values of the nodes they connect. Depending on the sum you're looking for, you may be able to optimize this by removing edges that are guaranteed to fail. For example, if you're looking for 15, you can delete all edges with weight of 16 or greater.
The rest of the algorithm will be performed as many times as there are blocks, with each block serving as the starting block once. Traverse the graph by following the lowest-weighted edge from the current node, unless that takes you to a visited node. Push each visited node onto a stack and set its visited variable to true. Keep a running sum for every path followed.
Whenever the desired sum is reached, save the current path as one of your answers. Do not stop traversal, because the current node could be connected to a zero.
Whenever the total exceeds the desired sum, backtrack by setting visited to false and popping the current node off the stack.
Whenever all edges for a given node have been explored, backtrack.
After every possible path from a given starting node is analyzed, every answer that includes that node has been found. So, remove all edges touching the starting node and choose a new starting node.
I haven't fully analyzed the efficiency/running time of this algorithm yet, but... it's not good. (Consider the number of paths to be searched in a graph containing all zeroes.) That said, it's far better than pure brute force.