I saw the following implementation of topological sort using DFS on Leetcode https://leetcode.com/problems/course-schedule/discuss/58509/18-22-lines-C++-BFSDFS-Solutions
Now the part of this that is confusing me is the representation of the directed graph which is used for the top sort. The graph is created as follows:
vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<unordered_set<int>> graph(numCourses);
for (auto pre : prerequisites)
graph[pre.second].insert(pre.first);
return graph;
}
What is confusing me is this line:
graph[pre.second].insert(pre.first);
Presumably the graph is being represented as an adjacency list; if so why is each node being represented by the incoming edges and not the outgoing edges? Interestingly, if I flip pre.second and pre.first like this:
graph[pre.first].insert(pre.second);
The top sort still works. However, it seems most implementations of the same problem use the former method. Does this generalize to all directed graphs? I was taught in my undergraduate degree that a directed graph's adjacency list should contain a list of each nodes outgoing nodes. Is the choice of incoming vs outgoing node arbitrary for the representation of the adjacency list?
To the specific problem which only requires answering true or false, it doesn't matter if you flip every edge. That's because a graph is topological sortable if and only if it has no loops. But if you want an order of taking, it doesn't work as you can see in the different results of [[0, 1]] and [[1, 0]].
Which way to save the graph depends on how you solve the problem. In this given case, we need to know the indegrees of every node (course) and also to update it every time we delete a node from the graph (take the course), so that we know if we can delete a node (we can do it when the indegree is 0). When updating, we minus 1 to each node that the deleted node direct to. If you apply this method (as most do), it's clear how you should save the graph
I am new to PCL and I would like to get all indices from a branch node in pcl::octree.
So, the root node for instance should provide every single index and each sub-branch node the indices of the points of all leaf nodes within this branch node.
What is the best way of achieving this?
I am using a
pcl::octree::OctreePointCloudSearch<pcl::PointXYZ, pcl::octree::OctreeContainerPointIndices, pcl::octree::OctreeContainerPointIndices>
and hoped with the 3rd template parameter for the BranchContainerT also set to pcl::octree::OctreeContainerPointIndices to be able to call something like
std::vector<int> indices;
auto it = m_octree->breadth_begin();
it.getBranchContainer().getPointIndices(indices)
However, the indices vector is empty.
Of course, I can manually iterate over all the nodes, get the leafs and insert the indices, but maybe I am missing something here .. ?
Ok, what I was missing is that the template parameter for BranchContainerT set to pcl::octree::OctreeContainerPointIndices only provides you the option to store the indices in this kind of container. However adding these indices is something you have to do manually.
Given that it is just a matter of checking each node for its type and collect the indices from the leafs and add them to the branch nodes.
I am trying to find all the possible paths from one node in my graph that will visit all other nodes in the graph. I want the function to produce all possibilities of paths in my n*m graph. Each node in my graph has a vector of all neighbors nodes and a Boolean that check if the node is visited or not.
example:
a b
c d
will produce:
abcd
abdc
acbd
...
I tried the solution in this answer, but only return one path. How can I produce all possible paths?
It seems like in some situations by your description you could have infinite paths and a path of infinite length because you didn't specify that nodes couldn't be revisited.
You should implement depth first search and pass a reference to an array of marked (visited) nodes in your recursive DFS method assuming that you have a count of the number of nodes in your graph. After you visit each node, before you leave that node make sure you set it to false again so that it can be reaccessed via another node.
The implementation of this algorithm is really going to depend on how you implemented your graph structure and without the details all I can do is speculate that you have a linked structure with an adjacency list representing the different nodes. I also have no idea how the different nodes map to characters so that is another detail I have to speculate, but say that the nodes are represented by integers.
You need to pass into a DFS method the following: array of marked nodes, a linked list which contains the path information, starting node, (i.e, current node) and final node
void printAllPaths(LinkedList<Integer> currentPath, boolean[] marked, int current, int last){
for( all nodes adjacent to current, node ){
if(node == last){
currentPath.addLast(last);
System.out.println(currentPath);
currentPath.removeLast();
}else if(!marked[node]){
currentPath.addLast(node);
marked[node] = true;
printAllPaths(currentPath, marked, node, final);
marked[node] = false;
currentPath.removeLast();
}
}
}
This will be the basic idea of the code. I apologize if it doesn't compile in advance, but this should print out all of the paths.
Let me start off with saying that I have very basic knowledge of nodes and graphs.
My goal is to make a solver for a maze which is stored as an array. I know exactly how to implement the algorithm for solving (I'm actually implementing a couple of them) but what my problem is, is that I am very confused on how to implement the nodes that the solver will use in each empty cell.
Here is an example array:
char maze[5][9] =
"#########",
"# # #",
"# ## ## #",
"# # #",
"#########"
My solver starts at the top left and the solution (exit) is at the bottom right.
I've read up on how nodes work and how graphs are implemented, so here is how I think I need to make this:
Starting point will become a node
Each node will have as property the column and the row number
Each node will also have as property the visited state
Visited state can be visited, visited and leads to dead end, not visited
Every time a node gets visited, every directly adjacent, empty and not visited cell becomes the visited node's child
Every visited node gets put on top of the solutionPath stack (and marked on the map as '*')
Every node that led to a dead end is removed from the stack (and marked on the map as '~')
Example of finished maze:
"#########",
"#*~#****#",
"#*##*##*#",
"#****~#*#",
"#########"
Basically my question is, am I doing something really stupid here with my way of thinking (since I am really inexperienced with nodes) and if it is could you please explain to me why? Also if possible provide me other websites to check which implement examples of graphs on real world applications so I can get a better grasp of it.
The answer really depends on what you find most important in the problem. If you're searching for efficiency and speed - you're adding way too many nodes. There's no need for so many.
The efficient method
Your solver only needs nodes at the start and end of the path, and at every possible corner on the map. Like this:
"#########",
"#oo#o o#",
"# ## ## #",
"#o oo#o#",
"#########"
There's no real need to test the other places on the map - you'll either HAVE TO walk thru them, or won't have need to even bother testing.
If it helps you - I got a template digraph class that I designed for simple graph representation. It's not very well written, but it's perfect for showing the possible solution.
#include <set>
#include <map>
template <class _nodeType, class _edgeType>
class digraph
{
public:
set<_nodeType> _nodes;
map<pair<unsigned int,unsigned int>,_edgeType> _edges;
};
I use this class to find a path in a tower defence game using the Dijkstra's algorithm. The representation should be sufficient for any other algorithm tho.
Nodes can be of any given type - you'll probably end up using pair<unsigned int, unsigned int>. The _edges connect two _nodes by their position in the set.
The easy to code method
On the other hand - if you're looking for an easy to implement method - you just need to treat every free space in the array as a possible node. And if that's what you're looking for - there's no need for designing a graph, because the array represents the problem in a perfect way.
You don't need dedicated classes to solve it this way.
bool myMap[9][5]; //the array containing the map info. 0 = impassable, 1 = passable
vector<pair<int,int>> route; //the way you need to go
pair<int,int> start = pair<int,int>(1,1); //The route starts at (1,1)
pair<int,int> end = pair<int,int>(7,3); //The road ends at (7,3)
route = findWay(myMap,start,end); //Finding the way with the algorithm you code
Where findWay has a prototype of vector<pair<int,int>> findWay(int[][] map, pair<int,int> begin, pair<int,int> end), and implements the algorithm you desire. Inside the function you'll probably need another two dimensional array of type bool, that indicates which places were tested.
When the algorithm finds a route, you usually have to read it in reverse, but I guess it depends on the algorithm.
In your particular example, myMap would contain:
bool myMap[9][5] = {0,0,0,0,0,0,0,0,0,
0,1,1,0,1,1,1,1,0,
0,1,0,0,1,0,0,1,0,
0,1,1,1,1,1,0,1,0,
0,0,0,0,0,0,0,0,0};
And findWay would return a vector containing (1,1),(1,2),(1,3),(2,3),(3,3),(4,3),(4,2),(4,1),(5,1),(6,1),(7,1),(7,2),(7,3)
I have a simple, non-dirictional tree T. I should find a path named A and another named B that A and B have no common vertex. The perpuse is to maxmize the Len(A)*Len(B).
I figured this problem is similer to Partition Problem, except in Partition Problem you have a set but here you have a Equivalence set. The solution is to find two uncrossed path that Len(A) ~ Len(B) ~ [n-1/2]. Is this correnct? how should I impliment such algorithm?
First of all. I Think you are looking at this problem the wrong way. As I understand it you have a graph related problem. What you do is
Build a maximum spanning tree and find the length L.
Now, you say that the two paths can't have any vertex in common, so we have to remove an edge to archieve this. I assume that every edge wheight in your graph is 1. So sum of the two paths A and B are L-1 after you removed an edge. The problem is now that you have to remove an edge such that the product of len(a) and len(b) is maximized. You do that by removeing the edge in et most 'middel' of L. Why, the problem is of the same as optimizing the area of a rectangle with a fixed perimeter. A short youtube video on the subject can be found here.
Note if your edge wheights are not equal to 1, then you have a harder problem, because there may exist more than one maximum spanning tree. But you may be able to split them in different ways, if this is the case, write me back, then I will think about a solution, but i do not have one at hand.
Best of luck.
I think there is a dynamic programming solution that is just about tractable if path length is just the number of links in the paths (so links don't have weights).
Work from the leaves up. At each node you need to keep track of the best pair of solutions confined to the subtree with root at that node, and, for each k, the best solution with a path of length k terminating in that node and a second path of maximum length somewhere below that node and not touching the path.
Given this info for all descendants of a node, you can produce similar info for that node, and so work your way up to the route.
You can see that this amount of information is required if you consider a tree that is in fact just a line of nodes. The best solution for a line of nodes is to split it in two, so if you have only worked out the best solution when the line is of length 2n + 1 you won't have the building blocks you need for a line of length 2n + 3.