I am working on a project where I am given a list of edges with a weight of either A or B. I need eventually determine if it is possible to create a spanning tree with 'x' number of A edges.
Right now I am trying to make a list of all the edges that are used in creating the minimally spanning tree and am doing that by making a list of the vertices that I have used. If two of the vertices have been used then that edges is discarded. The problem I am having is that once I get to the end my graph, I am often left with two halves of graphs that are not connected because the edge that would connect the two halves have already been used. Any thoughts on how I can fix this problem, or is the overall approach wrong?
struct Edge{
int start;
int end;
char letter;
bool used;
};
void PrimWhite(...)
{
vector<int> usedVertices;
int count,maxNum,begin,end;
int totalVertexs = 0;
maxNum = whiteEdge.size();
Edge temp;
Edge *point = &temp;
Edge *usedorNah;
for (count = 0;count < maxNum; count++)
{
temp = whiteEdge[count];
usedorNah = &whiteEdge[count];
begin = point->start;
end = point->end;
if ( (find(usedVertices.begin(), usedVertices.end(), begin) == usedVertices.end()) && (find(usedVertices.begin(), usedVertices.end(), end) == usedVertices.end()))
{
usedVertices.push_back(begin);
usedVertices.push_back(end);
totalVertexs = totalVertexs + 2;
usedorNah->used = true;
}
else if ((find(usedVertices.begin(), usedVertices.end(), begin) == usedVertices.end()) && (find(usedVertices.begin(), usedVertices.end(), end) != usedVertices.end()))
{
usedVertices.push_back(begin);
totalVertexs++;
usedorNah->used = true;
}
else if ((find(usedVertices.begin(), usedVertices.end(), begin) != usedVertices.end()) && (find(usedVertices.begin(), usedVertices.end(), end) == usedVertices.end()) )
{
usedVertices.push_back(end);
totalVertexs++;
usedorNah->used = true;
}
Just use the criterion that Kruskal's algorithm uses: Add an edge to the graph if it does not form a loop. To check this, you have to check if the two incident nodes are connected to the same connected component. This can be done efficiently with the Union-Find data structure. I.e. whenever you add an edge, unite the components of both vertices. Before adding an edge, check if the two components are the same.
Related
I am trying to fill everything that is outside a contour using a queue implementation of flood fill. However i have some problems deducing the starting point to add to the queue.
I define a new double of 400*400 named tmpSlice and fill it with zeroes. Then i map the contour with label value 1.0. This part works just fine.
The problem occurs when i have to push a starting point onto the queue the best scenario would be to push the top left corner or point 0.
However i can not push 0 as a starting point without getting a segmentation fault. I am currently pushing 160000 which is the size of tmpSlice this is the only number i have been able to insert without errors.
However when i am pushing 160000 onto the queue and after the flood fill has executed i run the loop(at bottom of code) that runs from 0-160000.
This loop should color everything which has value 0 and 1 as one and everything that has value 2 should be zero. But currently everything inside the tmpSlice has value 0 except the original contour that has value 1.
For clarification 2 represents the outside of the contour, 1 represents the border of the contour and 0 represents whats inside the contour
So basically the flood fill does nothing on my dataset tmpSlice. I think it is because of the starting point inserted onto the queue but i haven't been able to insert any values that will work.
Thoughts?
PS.
I am limited to use the new double because a vector::std doesn't work with some functions from the minc library that i am using.
/* Flood fill */
//Colour we are looking for as background
int TargetColour = 0.0;
//The new colour we will write
int NewColour = 2.0;
//create set to secure unique entries into the queue, otherwise we etc. insert the 9th element in a 3x3 array 6 times.
set < int > Set;
//Create queue
queue < int > MyQue;
//Insert first point into the queue
MyQue.push(sizes[1]*sizes[2]);
int Node;
//While loop for iterating over the nodes.
while (!MyQue.empty()){
//Set front element to Node, and pop the front element from queue
Node = MyQue.front();
MyQue.pop();
//Change the colour to newcolour
tmpSlice[Node] = NewColour;
//Define the Node directions
int WestNode = Node-1;
int EastNode = Node+1;
//sizes are the lengths x,y
int NorthNode = Node-sizes[1];
int SouthNode = Node+sizes[2];
//Boundary checks
EastNodeBoundaryCheck = floor((Node-sizes[1]*sizes[2]*floor(Node/(sizes[1]*sizes[2])))/sizes[1]) == floor((EastNode-sizes[1]*sizes[2]*floor(EastNode/(sizes[1]*sizes[2])))/sizes[1]);
SouthNodeBoundaryCheck = floor(Node / (sizes[1]*sizes[2])) == floor(SouthNode / (sizes[1]*sizes[2]));
WestNodeBoundaryCheck = floor((Node-sizes[1]*sizes[2]*floor(Node/(sizes[1]*sizes[2])))/sizes[1]) == floor((WestNode-sizes[1]*sizes[2]*floor(WestNode/(sizes[1]*sizes[2])))/sizes[1]);
NorthNodeBoundaryCheck = floor(Node / (sizes[1]*sizes[2])) == floor(NorthNode / (sizes[1]*sizes[2]));
//East Node
if (Set.insert(EastNode).second) {
if (tmpSlice[EastNode] == TargetColour && EastNodeBoundaryCheck == 1){
MyQue.push(EastNode);
}
}
//South Node
if (Set.insert(SouthNode).second) {
if (tmpSlice[SouthNode] == TargetColour && SouthNodeBoundaryCheck == 1){
MyQue.push(SouthNode);
}
}
//West Node
if (Set.insert(WestNode).second) {
if (tmpSlice[WestNode] == TargetColour && WestNodeBoundaryCheck == 1){
MyQue.push(WestNode);
}
}
//North Node
if (Set.insert(NorthNode).second) {
if (tmpSlice[NorthNode] == TargetColour && NorthNodeBoundaryCheck == 1){
MyQue.push(NorthNode);
}
}
}
// Insert the colored points as 0 and everything else as 1
for(i = 0; i < sizes[1]*sizes[2]; i++){
if(tmpSlice[i] == 0.0 || 1.0){
slab[first_voxel_at_slice + i] = 1.0;
}
if(tmpSlice[i] == 2.0){
slab[first_voxel_at_slice + i] = 0.0;
}
}
I found the answer myself when answering a comment :-)
I needed to check the NorthNode if it was bigger than 0 for the first row to avoid segmentation fault.
//North Node
if (Set.insert(NorthNode).second) {
if (NorthNode > 0){
if (tmpSlice[NorthNode] == TargetColour && NorthNodeBoundaryCheck == 1){
MyQue.push(NorthNode);
}
}
}
If I have the following graph:
Marisa Mariah
\ /
Mary---Maria---Marian---Maryanne
|
Marley--Marla
How should be Depth First Search function be implemented such that I get the output if "Mary" is my start point ?
Mary
Maria
Marisa
Mariah
Marian
Maryanne
Marla
Merley
I do realize that the number of spaces equal to depth of the vertex( name ) but I don't how to code that. Following is my function:
void DFS(Graph g, Vertex origin)
{
stack<Vertex> vertexStack;
vertexStack.push(origin);
Vertex currentVertex;
int currentDepth = 0;
while( ! vertexStack.empty() )
{
currentVertex = vertexStack.top();
vertexStack.pop();
if(currentVertex.visited == false)
{
cout << currentVertex.name << endl;
currentVertex.visited = true;
for(int i = 0; i < currentVertex.adjacencyList.size(); i++)
vertexStack.push(currentVertex.adjacencyList[i]);
}
}
}
Thanks for any help !
Just store the node and its depth your stack:
std::stack<std::pair<Vertex, int>> vertexStack;
vertexStack.push(std::make_pair(origin, 0));
// ...
std::pair<Vertex, int> current = vertexStack.top();
Vertex currentVertex = current.first;
int depth = current.second;
If you want to get fancy, you can extra the two values using std::tie():
Vertex currentVertex;
int depth;
std::tie(currentVertex, depth) = vertexStack.top();
With knowing the depth you'd just indent the output appropriately.
The current size of your stack is, BTW, unnecessarily deep! I think for a complete graph it may contain O(N * N) elements (more precisely, (N-1) * (N-2)). The problem is that you push many nodes which may get visited.
Assuming using an implicit stack (i.e., recursion) is out of question (it won't work for large graphs as you may get a stack overflow), the proper way to implement a depth first search would be:
push the current node and edge on the stack
mark the top node visited and print it, using the stack depth as indentation
if there is no node
if the top nodes contains an unvisited node (increment the edge iterator until such a node is found) go to 1.
otherwise (the edge iterator reached the end) remove the top node and go to 3.
In code this would look something like this:
std::stack<std::pair<Node, int> > stack;
stack.push(std::make_pair(origin, 0));
while (!stack.empty()) {
std::pair<Node, int>& top = stack.top();
for (; top.second < top.first.adjacencyList.size(); ++top.second) {
Node& adjacent = top.first.adjacencyList[top.second];
if (!adjacent.visited) {
adjacent.visted = true;
stack.push(std::make_pair(adjacent, 0));
print(adjacent, stack.size());
break;
}
}
if (stack.top().first.adjacencyList.size() == stack.top().second) {
stack.pop();
}
}
Let Rep(Tree) be the representation of the tree Tree. Then, Rep(Tree) looks like this:
Root
<Rep(Subtree rooted at node 1)>
<Rep(Subtree rooted at node 2)>
.
.
.
So, have your dfs function simply return the representation of the subtree rooted at that node and modify this value accordingly. Alternately, just tell every dfs call to print the representation of the tree rooted at that node but pass it the current depth. Here's an example implementation of the latter approach.
void PrintRep(const Graph& g, Vertex current, int depth)
{
cout << std::string(' ', 2*depth) << current.name << endl;
current.visited = true;
for(int i = 0; i < current.adjacencyList.size(); i++)
if(current.adjacencyList[i].visited == false)
PrintRep(g, current.adjacencyList[i], depth+1);
}
You would call this function with with your origin and depth 0 like this:
PrintRep(g, origin, 0);
I want to implement Prims algorithm to find the minimal spanning tree of a graph. I have written some code to start with what I think is the way to do it, but Im kind of stuck on how to complete this.
Right now, I have a matrix stored in matrix[i][j], which is stored as a vector>. I have also a list of IP address stored in the variable ip. (This becomes the labels of each column/row in the graph)
int n = 0;
for(int i = 0; i<ip.size();i++) // column
{
for(int j = ip.size()-1; j>n;j--)
{
if(matrix[i][j] > 0)
{
edgef test;
test.ip1 = ip[i];
test.ip2 = ip[j];
test.w = matrix[i][j];
add(test);
}
}
n++;
}
At the moment, this code will look into one column, and add all the weights associated with that column to a binary min heap. What I want to do is, dequeue an item from the heap and store it somewhere if it is the minimum edge weight.
void entry::add(edgef x)
{
int current, temp;
current = heap.size();
heap.push_back(x);
if(heap.size() > 1)
{
while(heap[current].w < heap[current/2].w) // if child is less than parent, min heap style
{
edgef temp = heap[current/2]; // swap
heap[current/2] = heap[current];
heap[current] = temp;
current = current/2;
}
}
}
I have the following implementation of a binary tree in an array;
32
/ \
2 -5
/ \
-331 399
The data is grouped 3 indexes at a time. index%3==0 is the value of the node, index%3==1 is the index of the value of the left node and index%3==2 is the index of the value of the right node. If the left or right index reference is 0, there is no node that direction.
I'm trying to find the depth (height) of this tree. I've written it recursively
height(node):
if node == null:
return 0
else:
return max(height(node.L), height(node.R)) + 1
I want to find a non-recursive solution, however.
Here is some pseudocode i have, assuming the tree is not empty
int i = 0; int left = 0; int right = 0;
while (i != n ){
if ( a[i+1] != 0 ){
left++;
}
else if ( a[i+2] != 0 ){
right++;
}
i = i + 3;
}
return max ( left, right ) + 1;
I don't think this is right and I'd like some help figuring out how to do this correctly.
You haven't said what your problem is with recursion for us to understand what behavior you want to improve.
There are many solutions to this, but almost all of them have the same or worse performance than your recursive solution. Really, the best solutions are going to be things you'd have to do when you're creating the tree. For example, you could store the height of each node in a fourth array index per node. Then it's a trivial scan of every fourth index to find the max height. It would also make it easier if nodes had parent references stored with them so that didn't have to be computed during the height check.
One solution is to simulate recursion with a stack, but that's really no different than recursion.
Another solution is to go through each node and determine its height based on it's parent, but not in a specific traversal's order. However, because of how you have this configured, without a secondary datastructure to store the hierarchy, it's going to be less efficient O(n^2). The problem is you can't get from the child to its parent without a full array scan. Then you can do it in linear time (but recursion is also linear time, so I'm not sure we're doing better. It's also not going to be much better from a memory perspective).
Can you define what type of efficiency you want to improve?
Here's the pseudocode for each, but I'm depending on a few datastructures that aren't easily present:
"recursion without recursion" solution:
int get_height(int * tree, int length) {
Stack stack;
int max_height = 0;
if (length == 0) {
return 0;
}
// push an "array" of the node index to process and the height of its parent.
// make this a struct and use that for real c code
stack.push(0,0);
while(!stack.empty()) {
int node_index, parent_height = stack.pop();
int height = parent_height + 1;
if (height > max_height) {
max_height=height;
}
if (tree[node_index+1] != 0 )
stack.push(tree[node_index+1], height);
if (tree[node_index+2] != 0 )
stack.push(tree[node_index+2], height);
}
return max_height;
}
Now working on really slow solution that uses no additional memory, but it's REALLY bad. It's like writing fibonacci recursively bad. The original algorithm went through each node and performed O(n) checks worst case for a runtime of O(n^2) (actually not quite as bad as I had originally thought)
edit: much later I'm adding an optimization that skips all nodes with children. This is REALLY important, as it cuts out a lot of calls. Best case is if the tree is actually a linked list, in which case it runs in O(n) time. Worst case is a fully balanced tree - with logn leaf nodes each doing logn checks back to the root for O((log(n)^2). Which isn't nearly so bad. Lines below to be marked as such
"really slow but no extra memory" solution (but now updated to not be nearly so slow):
int get_height(int * tree, int length) {
int max_height = 0;
for (int i = 0; i < length; i+=3) {
// Optimization I added later
// if the node has children, it can't be the tallest node, so don't
// bother checking from here, as the child will be checked
if (tree[i+1] != 0 || tree[i+2] != 0)
continue;
int height = 0;
int index_pointing_at_me;
// while we haven't gotten back to the head of the tree, keep working up
while (index_pointing_at_me != 0) {
height += 1;
for (int j = 0; j < length; j+=3) {
if (tree[j+1] == tree[i] ||
tree[j+2] == tree[i]) {
index_pointing_at_me = j;
break;
}
}
}
if (height > max_height) {
max_height = height;
}
}
return max_height;
}
Improved on previous solution, but uses O(n) memory - this assumes parents are always before children in array (which I suppose isn't technically required)
int get_height(int * tree, int length) {
if (length == 0)
return 0;
// two more nodes per node - one for which node is its parent, the other for its height
int * reverse_mapping = malloc((sizeof(int) * length / 3) * 2)
reverse_mapping[1] = 1; // set height to 1 for first node
// make a mapping from each node to the node that points TO it.
// for example, for the first node
// a[0] = 32
// a[1] = 3
// a[2] = 6
// store that the node at 3 and 6 are both pointed to by node 0 (divide by 3 just saves space since only one value is needed) and that each child node is one taller than its parent
int max_height = 0;
for (int i = 0; i < length; i+=3) {
int current_height = reverse_mapping[(i/3)*2+1];
if (current_height > max_height)
max_height = current_height;
reverse_mapping[(tree[i+1]/3)*2] = i;
reverse_mapping[(tree[i+1]/3)*2 + 1] = current_height + 1;
reverse_mapping[(tree[i+2]/3)*2] = i;
reverse_mapping[(tree[i+2]/3)*2 + 1] = current_height + 1;
}
return max_height
}
If we have a 3x3x3 array of objects, which contain two members: a boolean, and an integer; can anyone suggest an efficient way of marking this array in to contiguous chunks, based on the boolean value.
For example, if we picture it as a Rubix cube, and a middle slice was missing (everything on 1,x,x == false), could we mark the two outer slices as separate groups, by way of a unique group identifier on the int member.
The same needs to apply if the "slice" goes through 90 degrees, leaving an L shape and a strip.
Could it be done with very large 3D arrays using recursion? Could it be threaded.
I've hit the ground typing a few times so far but have ended up in a few dead ends and stack overflows.
Very grateful for any help, thanks.
It could be done that way:
struct A {int m_i; bool m_b;};
enum {ELimit = 3};
int neighbour_offsets_positive[3] = {1, ELimit, ELimit*ELimit};
A cube[ELimit][ELimit][ELimit];
A * first = &cube[0][0][0];
A * last = &cube[ELimit-1][ELimit-1][ELimit-1];
// Init 'cube'.
for(A * it = first; it <= last; ++it)
it->m_i = 0, it->m_b = true;
// Slice.
for(int i = 0; i != ELimit; ++i)
for(int j = 0; j != ELimit; ++j)
cube[1][i][j].m_b = false;
// Assign unique ids to coherent parts.
int id = 0;
for(A * it = first; it <= last; ++it)
{
if (it->m_b == false)
continue;
if (it->m_i == 0)
it->m_i = ++id;
for (int k = 0; k != 3; ++k)
{
A * neighbour = it + neighbour_offsets_positive[k];
if (neighbour <= last)
if (neighbour->m_b == true)
neighbour->m_i = it->m_i;
}
}
If I understand the term "contiguous chunk" correctly, i.e the maximal set of all those array elements for which there is a path from each vertex to all other vertices and they all share the same boolean value, then this is a problem of finding connected components in a graph which can be done with a simple DFS. Imagine that each array element is a vertex, and two vertices are connected if and only if 1) they share the same boolean value 2) they differ only by one coordinate and that difference is 1 by absolute value (i.e. they are adjacent)