How to change this code from recursion to iteration - c++

I've trying to make the following code implement by iteration instead of recursive(the "hit" function of the BVH_node class),but I've no idea how to do this.I did found some topic about this,but they are not very helpful.Could anybody help me?thanks so much.(by the way this is the third time I ask this question ,people says that I'm not making my question clear,please give me some advice on asking question)
class Ray {
public:
vec3 origin;
vec3 direction;
float t = 10000.0f;
};
class AABB{
public:
bool hit(Ray ray){
//test if ray hit itself
//but don't write the t into the ray
}
vec3 min;
vec3 max;
};
class Geometry {
public:
bool hit(Ray& ray) {
float t;
//test if the ray hit this geometry
//ray.origin + t * ray.direction = ......
//then solve the t
if (t < ray.t && t>0.0f) {
ray.t = t;
return true;
}
return false;
}
private:
//...some private data
};
class BVH_node {
public:
void construction(/*......some data for construction*/) {
//is_node_or_geo = ......
//if(is_node_or_geo == 0)
//L_node = ......; R_node = ......;
//if(is_node_or_geo == 1)
//L_geo = ......; R_geo = ......;
}
bool hit(Ray& ray) {
if(aabb.hit(ray)){
if (is_node_or_geo == 0) {
bool hit_left = L_node->hit(ray);
bool hit_right = R_node->hit(ray);
return hit_left || hit_right;
}
if (is_node_or_geo == 1) {
bool hit_left = L_geo->hit(ray);
bool hit_right = R_geo->hit(ray);
return hit_left || hit_right;
}
}
return false;
}
private:
int is_node_or_geo;//node = 0,geo = 1
AABB aabb;
BVH_node* L_node;
BVH_node* R_node;
Geometry* L_geo;
Geometry* R_geo;
};
int main(){
BVH_node* root = new BVH_node;
root->construction(/*.......*/);
Ray ray;//ray = .......;
bool hit = root->hit(ray);
delete root;
}
most tutorial I found on how to change recursion to iteration(like this http://blog.moertel.com/posts/2013-05-11-recursive-to-iterative.html) don't consider some situation where member variable is involved.

Follow up on the approach mentioned in a comment of Alan Birtles:
Let us focus on the hit function. In order to make our life easier, it's better to first rewrite it as follows:
bool hit(Ray& ray) {
if(!aabb.hit(ray)) return false;
if (is_node_or_geo == 0) {
if (L_node->hit(ray)) return true;
if (R_node->hit(ray)) return true;
return false;
} else if (is_node_or_geo == 1) {
if (L_geo->hit(ray)) return true;
if (R_geo->hit(ray)) return true;
return false;
}
}
Now we can add a loop and a stack (implemented with a std::vector, since I'm not familiar with std::stack). We also make the method static, as it does not relate to a single object:
static bool hit(Ray& ray, BVH_node * root) {
std::vector<BVH_node *> nodes {root};
while (!nodes.empty()){
BVH_node & top = *nodes.back();
nodes.pop_back();
if(!top.aabb.hit(ray)) continue;
if (top.is_node_or_geo == 0) {
nodes.push_back(top.L_node);
nodes.push_back(top.R_node);
continue;
} else if (top.is_node_or_geo == 1) {
if (top.L_geo->hit(ray)) return true;
if (top.R_geo->hit(ray)) return true;
continue;
}
}
return false;
}
This code wasn't tested so it might require minor tweacking.
Note that depending on your implementation, you might want to add a bunch of consts - after every mention of BVH_node

Related

When inheriting from a class, do the variables inherited get redefined by the inherited class through the parent class?

I have made two classes: stack1 and stack2 and defined my own stack operations of push(), pop(), isempty() and isfull(). I am trying to calculate a postfix expression from an input. I have made another class called operation that is a child of stack1 and stack2, so I can access the functions of push(),pop(), etc.. within operation. I have a function within operation called operate() that does the dirty work on the stacks. Within this function I have a while loop that depends on stack1 not being empty until the operation is complete; HOWEVER, when I step through this function top1, where stack1 is pointing to, has been reset to 0. Is there a way to overcome this/am I doing something wrong? This is the first time I am using classes and such, so I am not sure of the ins and outs.
Here are the definitions of my classes:
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
void push1(int data)
{
if (is_full1());
else
{
num1[top1] = data;
top1++;
}
}
int pop1(void)
{
if(is_empty1());
else
{
top1--;
return num1[top1];
}
}
int is_empty1(void)
{
if(top1 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full1(void)
{
if(top1 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
} };
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
void push2(int data)
{
if (is_full2());
else
{
num2[top2] = data;
top2++;
}
}
int pop2(void)
{
if(is_empty2());
else
{
top2--;
return num2[top2];
}
}
int is_empty2(void)
{
if(top2 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full2(void)
{
if(top2 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
} };
class operation: public stack2, public stack1 {
private:
int answer;
int a;
int b;
int num_cnt;
int ans;
int from_st1;
int from_st2;
public:
int c;
int oper(void)
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
c = 0;
stack1 st1;
stack2 st2;
while(!st1.is_empty1())
{
from_st1 = st1.pop1();
if(from_st1 == plus)
{
st2.push2(from_st1);
}else if(from_st1 == minus)
{
st2.push2(from_st1);
}else if(from_st1 == mult)
{
st2.push2(from_st1);
}else if (from_st1 == divide)
{
st2.push2(from_st1);
}else if(num_cnt == 1)
{
num_cnt = 0;
if(ans == 0)
{
answer = b;
ans++;
}
a = from_st1;
from_st2 = st2.pop2();
if(from_st2 == plus)
{
c = a+answer;
}else if(from_st2 == minus)
{
c = a-answer;
}else if(from_st2 == mult)
{
c = a*answer;
}else if(from_st2 == divide)
{
c = a/answer;
}
}else
{
b = from_st1;
}
num_cnt++;
}
return c;
}
operation()
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
from_st1 = 0;
from_st2 = 0;
} };
I think that the "problem" is with the line:
stack1 st1;
stack2 st2;
This will call the default constructor and set the value of the variables top1 and top2 as zero.
A workaround to this would be to initialise these variables with some positive non-zero value.
Hence the code would look something like(focusing only on the changed parts):
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
.....
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
}
stack1(int top1)
{this.top1 = top1;}
};
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
public:
.....
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
}
stack2(int top2)
{this.top2 = top2;}
};
class operation: public stack2, public stack1 {
.....
public:
int c;
int oper(void)
{
.....
//just an example, can be declared explicitly as well
stack1 st1(5);
stack2 st2(7);
.....
Also, I would advice you to make your code a bit more readable(for instance the presence of 3-liner {} in if cases spanning only a single line). It is just unnecessary consumption of space.
And finally, if the "redefinition" of parent class' variables means the variables re-asserting some value on being inherited, they don't, unless you specify explicitly(such as using a constructor in our case to assign different values to top1 and top2). The inherited class will get a copy of the state of the parent class*.
*meaning they cannot be changed directly by the inherited class. For example if you would've done: int top1=5; initially then top1 would've been 5 until it were to be redefined again somewhere(such as using a constructor)
I take from the problem statement you are trying to build a basic calculator with four operators and need basic expression evaluation done using stack.
Say you have an expression: a+b-cd/e
looks like this in stack: TOP e->/->d->->c->-->b->+->a EMPTY
And this track needs to be evaluated.
Based on these.. you may be looking for something like below:
class stack {
private:
int num[SIZE];
int top;
public:
void push(int data)
{
if (is_full1());
else
{
num[top] = data;
top++;
}
}
int pop(void)
{
if(is_empty());
else
{
top--;
return num[top];
}
}
int is_empty(void)
{
if(top == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full(void)
{
if(top == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack()
{
top = 0; num[SIZE] = {0};
}
};
class operation {
private:
int answer;
int op1;
int op;
boolean isOperator(int val) {
boolen retVal = false;;
if (val == plus ||
val == minus ||
val == divide ||
val == mult) {
retVal = true;
}
else {
retVal = false;
}
return retVal;
}
public:
int oper(stack st1)
{
int from_st1 = 0;
while(!st1.is_empty())
{
from_st1 = st1.pop();
if(isOperator(from_st1))
{
op = from_st1;
}
else if(answer != 0)
{
op1 = from_st1;
if(op == plus)
{
answer = op1 + answer;
}else if(op == minus)
{
answer = op1 - answer;
}else if(op == mult)
{
answer = op1 * answer;
}else if(op == divide)
{
answer = op1 / answer;
}
}
else
{
answer = from_st1;
}
}
return answer;
}
operation()
{
answer = 0;
op1 = 0;
op = 0;
}
};
Note: You can do all evaluation with one stack don't need two stacks. Your operands can not equal to integer values for +, -, * and / for this assignment. You have a valid expression input into stack in main() code.

Using the function "find", of a set of struct, by passing just one attribute of the struct?

Is it possible to use the function "find", of a set of struct, by passing just one attribute of the struct?
The structs and the operators < are defined below:
struct ARCO_TEMPO {
Arco a;
int slotTimeU; // momento que sai do vertice u do arco
int slotTimeV; // momento que chega no vertice v do arco
int order;
ARCO_TEMPO () {};
ARCO_TEMPO (const ARCO_TEMPO& obj): a(obj.a), slotTimeU(obj.slotTimeU), slotTimeV(obj.slotTimeV), order(obj.order) {};
ARCO_TEMPO (Arco _a, int _slotTimeU, int _slotTimeV, int _order) : a(_a), slotTimeU(_slotTimeU), slotTimeV(_slotTimeV), order(_order) {}
};
struct PATH {
set<ARCO_TEMPO> rota;
float COST;
};
bool operator<(const ARCO_TEMPO& obj1, const ARCO_TEMPO& obj2) {
if (obj1.slotTimeU < obj2.slotTimeU) {
return true;
}
else {
if (obj1.slotTimeU == obj2.slotTimeU && obj1.slotTimeV < obj2.slotTimeV) {
return true;
}
else {
if (obj1.slotTimeU == obj2.slotTimeU && obj1.slotTimeV == obj2.slotTimeV && obj1.a.i < obj2.a.i) {
return true;
}
else {
if (obj1.slotTimeU == obj2.slotTimeU && obj1.slotTimeV == obj2.slotTimeV &&obj1.a.i == obj2.a.i && obj1.a.j < obj2.a.j ) {
return true;
}
else{
return false;
}
}
}
bool operator<(const PATH& obj1, const PATH& obj2) {
if (obj1.COST < obj2.COST) {
return true;
}
else {
if (obj1.COST == obj2.COST && obj1.rota < obj2.rota) {
return true;
}
else{
return false;
}
}
}
I have a variable PATH, called as aux_p. Then I have the attribute rota of this PATH (aux_p.rota). I want to find the "position" in the set rota (aux_p.rota), in which the attribute order is equal a specific value.
I tried the lines below, but it doesn't work:
set<ARCO_TEMPO>::iterator it;
int orderAux = aux_p.rota.size();
it = aux_p.find(it->orderAux)
How can I use a second container unordered_map to this works?
Could anyone help me, please?
What you want is impossible. Either iterate through all set elements from begin() to end(), or use a second container unordered_map<int>.
BTW ARCO_TEMPO::orderAux and PATH::find are not declared.

C++: Value of pointer changes "randomly"

I'm creating a function that creates a map from an image with a maze in it.
It takes the image, goes to every pixel and decides if it has to create a node there. One rule is, that when it finds a white pixel at one of the borders it will either be the start or the end node. To tell my pathfinding function where to start, I push the node into a vector(like all other nodes, too) and save the address of that node in a (double)pointer. My problem is, at the end of the loop, the variables in this node change their values(a bool variable might get the value 133) I actually never modify most of the members in this loop. I really have no idea why this is the case...
For examle:
After assigning the node to the pointer:
Completed: false
DistanceTo: 4294967295
PreviousNode: 0x0
XPos: 3
YPos: 0
m_vConnections: <0 Elements>
After function finished:
Completed: 8
DistanceTo: 32674
PreviousNode: SomeAddress
XPos: 3
YPos: 0
m_vConnections: <0 Elements>
The node at SomeAddress actually has completely screwed values, too, but I suspect that the address just changed and it now interprets the data found there as a node.
Sometimes m_vConnections becomes "inaccesseble" which results in sigsegvs when I try to connect something to it.
My function:
bool CreateGraph(const sf::Image &mMaze, std::vector<dijkstra::CNode> *vGraph, dijkstra::CNode **mStart, dijkstra::CNode **mEnd, SMazeCol mColors)
{
*mStart = 0;
unsigned short nExits = 0;
//Get Maze Colours
sf::Color mWallColor = mColors.Wall;
sf::Color mPathColor = mColors.Path;
//Create nodes
for(unsigned int y = 0; y < mMaze.getSize().y; ++y)
{
for(unsigned int x = 0; x < mMaze.getSize().x; ++x)
{
if(mMaze.getPixel(x, y) == mPathColor) //Current pixel is a path
{
bool bTop = false;
bool bBottom = false;
unsigned short nNeighbours = 0;
//Check surroundings of pixel
if(y != 0 && mMaze.getPixel(x, y - 1) == mPathColor)
{
bTop = true;
++nNeighbours;
}
if(y != mMaze.getSize().y - 1 && mMaze.getPixel(x, y + 1) == mPathColor)
{
bBottom = true;
++nNeighbours;
}
if(x != 0 && mMaze.getPixel(x - 1, y) == mPathColor)
{
++nNeighbours;
}
if(x != mMaze.getSize().x - 1 && mMaze.getPixel(x + 1, y) == mPathColor)
{
++nNeighbours;
}
//Decide if a node has to be created at that pixel
if(x == 0 || y == 0 || x == mMaze.getSize().x - 1 || y == mMaze.getSize().y - 1)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
if(*mStart == 0)
{
*mStart = &vGraph->back();
++nExits;
}
else
{
*mEnd = &vGraph->back();
++nExits;
}
}
else if(nNeighbours == 2 && bTop != bBottom)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
}
else if(nNeighbours > 2)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
}
}
}
}
if(nExits != 2)
return false;
The CNode class:
struct SConnection
{
SConnection(CNode *To, unsigned int Distance);
CNode *To;
unsigned int Distance;
};
class CNode
{
public:
CNode();
std::vector<SConnection> Connections()const;
bool AddConnection(CNode *mTo, unsigned int nDistance);
bool AddConnection(const SConnection &mConnection);
bool RemoveConnection(CNode *mTo);
bool operator > (const CNode &rhs)const;
bool operator < (const CNode &rhs)const;
bool operator == (const CNode &rhs)const;
CNode* Addr();
bool Completed;
unsigned int DistanceTo;
CNode *PreviousNode;
unsigned int XPos, YPos;
private:
std::vector<SConnection> m_vConnections;
};
Implementation:
SConnection::SConnection(CNode *To, unsigned int Distance)
{
this->Distance = Distance;
this->To = To;
}
CNode::CNode()
:Completed(false), DistanceTo(std::numeric_limits<unsigned int>::max()), PreviousNode(0)
{
}
std::vector<SConnection> CNode::Connections() const
{
return m_vConnections;
}
bool CNode::AddConnection(CNode *mTo, unsigned int nDistance)
{
if(mTo == 0)
return false;
if(mTo == this)
return false;
for(auto &it : m_vConnections)
{
if(it.To == mTo)
return false;
}
m_vConnections.push_back({mTo, nDistance});
mTo->m_vConnections.push_back({this, nDistance});
return true;
}
bool CNode::AddConnection(const SConnection &mConnection)
{
return (AddConnection(mConnection.To, mConnection.Distance));
}
bool CNode::RemoveConnection(CNode *mTo)
{
for(auto it = m_vConnections.begin(); it != m_vConnections.end(); ++it)
{
if(it->To == mTo)
{
m_vConnections.erase(it);
for(auto it2 = mTo->m_vConnections.begin(); it2 != m_vConnections.end(); ++it2)
{
if(it2->To == this)
mTo->m_vConnections.erase(it2);
}
}
}
return false;
}
bool CNode::operator >(const CNode &rhs)const
{
return DistanceTo > rhs.DistanceTo;
}
bool CNode::operator <(const CNode &rhs) const
{
return DistanceTo < rhs.DistanceTo;
}
bool CNode::operator ==(const CNode &rhs)const
{
return DistanceTo == rhs.DistanceTo;
}
CNode *CNode::Addr()
{
return this;
}
Your main problem is here:
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
if(*mStart == 0)
{
*mStart = &vGraph->back();
++nExits;
}
else
{
*mEnd = &vGraph->back();
++nExits;
}
}
else if(nNeighbours == 2 && bTop != bBottom)
{
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
}
else if(nNeighbours > 2)
{
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
}
Local variables are not placed in global heap, and can be forgotten by programm soon after the code block where they were created is finished.
The better way to improve your code is to rewrite function declaration as
bool CreateGraph(const sf::Image &mMaze, std::vector<dijkstra::CNode*> *vGraph, dijkstra::CNode **mStart, dijkstra::CNode **mEnd, SMazeCol mColors)
And inside function change all:
dijkstra::CNode mNode
vGraph->push_back(mNode);
to
std::shared_ptr<dijkstra::CNode> mNode =
std::shared_ptr<dijkstra::CNode>(new dijkstra::CNode(X, Y));
vGraph->push_back(mNode.get());

C++ Rectangle to rectangle Collision

I'm having a really bad time here looking for the error in my code.
My collision detection won't work here even the algorithm I searched in Google.
void PollEvents()
{
for (int i = 0;i < NUMBER_OF_BLOCKS; ++i)
{
Rectangle& a = blocks[i];
if (mouse.state == GLFW_PRESS)
{
//look for any block to grab
if (mouse.leftClick && !blocks[selectedBlock].Grab() &&
a.Hover(mouse.pos.x, mouse.pos.y))
{
//prevent grabbing another block
if (i != selectedBlock) {
selectedBlock = i;
}
a.Grab() = true;
if (a.IsTypeHorizontal()) {
diff = mouse.pos.x - a.Left();
} else {
diff = mouse.pos.y - a.Top();
}
}
if (a.Grab())
{
for (int j = 0;j < NUMBER_OF_BLOCKS; ++j)
{
//skip for any self-checking
if (i == j) continue;
Rectangle& b = blocks[j];
//check for rectangle collision
if (!a.Collide(b) || b.Collide(a)) {
//j++;
//how does this block will move.
if (a.IsTypeVertical()) {
a.SetY(mouse.pos.y - diff);
} else {
a.SetX(mouse.pos.x - diff);
}
} else {
switch (a.sideHit)
{
case UP:
//a.SetY(b.Bottom());
printf("UP\n");
break;
case DOWN:
//a.SetY(b.Top() + a.GetHeight());
printf("DOWN\n");
break;
case LEFT:
//a.SetX(b.Right());
printf("LEFT\n");
break;
case RIGHT:
//a.SetX(b.Left() - a.GetWidth());
printf("RIGHT\n");
break;
}
}
//check for bound collision
a.BoundCheck(1.f);
}
}
} else {
a.Grab() = false;
}
}
}
Collision detection:
bool Rectangle::Collide(const Rectangle& r) {
if (IsTypeHorizontal()) {
if (r.Hover(Left(), Top()) && r.Hover(Right(), Top())) {
sideHit = UP;
return true;
} else if (r.Hover(Right(), Bottom()) && r.Hover(Left(), Bottom())) {
sideHit = DOWN;
return true;
}
// } else if (r.Hover(Left(), Top())) {
// sideHit = UP;
// return true;
// } else if (r.Hover(Right(), Top())) {
// sideHit = UP;
// return true;
// } else if (r.Hover(Right(), Bottom())) {
// sideHit = DOWN;
// return true;
// } else if (r.Hover(Left(), Bottom())) {
// sideHit = DOWN;
// return true;
// }
} else {
if (r.Hover(Left(), Top()) && r.Hover(Left(), Bottom())) {
sideHit = LEFT;
return true;
} else if (r.Hover(Right(), Top()) && r.Hover(Right(), Bottom())) {
sideHit = RIGHT;
return true;
}
// } else if (r.Hover(Left(), Top())) {
// sideHit = LEFT;
// return true;
// } else if (r.Hover(Left(), Bottom())) {
// sideHit = LEFT;
// return true;
// } else if (r.Hover(Right(), Top())) {
// sideHit = RIGHT;
// return true;
// } else if (r.Hover(Right(), Bottom())) {
// sideHit = RIGHT;
// return true;
// }
}
return false;
}
Code for Hover:
inline float Hover(float X, float Y) const {
return X >= Left() &&
X <= Right() &&
Y >= Bottom() &&
Y <= Top();
}
I'm trying to make my own unblockme.
Please help me on my collision-detection. It's been 3 days now since I got stuck in this problem.
UPDATE
I have found out the problem why all rect-rect collision detection won't work in my program.
Bug:
if (!a.Collide(b)) {
//Move()
} else {
//Resolve collision
}
This one should be
if (!Rectangle::Collide(a, b)) {
//Move()
} else {
//Resolve collision
}
Making the Collide() a static member of Rectangle because, as you can see in my implementation of Collide(), it bases its decision on its own member so a.Hover(b.x, b.y) doesn't make any sense.
Hope this helps a little bit to all newbies like me.
To do rect/rect collision detection, if any of one (edges parallel to x and y axis) rect's four points is inside the other rect, we have a collision.
An easier way than to check each of the four points is to check if one X edge is between both the other rect's X edges, and if one Y edge is between both the other rect's Y edges - if both are true, we have a collision (because the two edges must meet at a point inside of the other rect). So we just check this in both directions:
bool isclamped(float mid, float A, float B)
{
if (A > B)
{
return mid >= B && mid <= A;
}
return mid >= A && mid <= B;
}
bool checkcollisiononeway(rect rectA, rect rectB)
{
if (isclamped(rectA.left, rectB.left, rectB.right)
|| isclamped(rectA.right, rectB.left, rectB.right))
&& (isclamped(rectA.bottom, rectB.bottom, rectB.top)
|| isclamped(rectA.top, rectB.bottom, rectB.top))
{
return true;
}
return false;
}
bool checkcollisionbothways(rect rectA, rect rectB)
{
return checkcollisiononeway(rectA, rectB) || checkcollisiononeway(rectB, rectA);
}
To determine the angle of collision after detecting a collision, find the angle between their two centers using atan2(rectA.y - rectB.y, rectA.x - rectB.x) (the angle is returned in radians, not in degrees)

Dijkstra's Algorithm issue [repost]

I realized I can't post answers to my own questions because of my low rep or whatever so i deleted my old question and am reasking it. i changed some things and still can't get what i'm looking for.
Here is most of the code
I left out some of the simpler implementations such as parts of the pathFinder class because I know for sure they work, which is why you'll see playerVertex and time just randomly there.
In the example they used a decreaseKey function, I'm not sure if THAT'S what I'm missing? I'm a beginner here, so constructive criticism is welcome. (hopefully as polite as possible) lol. My problem is printing the path, I get a looop of the same two values over and over again.
class Heap
{
public: Heap();
~Heap();
void insert(double element);
double deletemin();
void print();
int size(){return heap.size();}
private:
int currentIndex;
int left(int parent);
int right(int parent);
int parent(int child);
void heapifyup(int index);
void heapifydown(int index);
private:
vector<double> heap;
};
Heap::Heap()
{
currentIndex = 0;
}
Heap::~Heap()
{}
void Heap::insert(double element)
{
heap.push_back(element);
currentIndex++;
heapifyup(heap.size() - 1);
}
double Heap::deletemin()
{
double min = heap.front();
heap[0] = heap.at(heap.size()-1);
heap.pop_back();
heapifydown(0);
currentIndex--;
return min;
}
void Heap::print()
{
vector<double>::iterator pos = heap.begin();
cout << "Heap = ";
while ( pos != heap.end() )
{
cout << *pos;
++pos;
cout << endl;
}
}
void Heap::heapifyup(int index)
{
while((index>0) && (parent(index) >=0) && (heap[parent(index)] > heap[index]))
{
double tmp = heap[parent(index)];
heap[parent(index)] = heap[index];
heap[index] = tmp;
index = parent(index);
}
}
void Heap::heapifydown(int index)
{
int child = left(index);
if((child > 0) && (right(index) > 0) && (heap[child]>heap[right(index)]))
{
child = right(index);
}
if(child > 0)
{
double tmp = heap[index];
heap[index] = heap[child];
heap[child] = tmp;
heapifydown(child);
}
}
int Heap::left(int parent)
{
int i = ( parent <<1) + 1;
return(i<heap.size()) ? i : - 1;
}
int Heap::right(int parent)
{
int i = ( parent <<1) + 2;
return(i<heap.size()) ? i : - 1;
}
int Heap::parent(int child)
{
if(child != 0)
{
int i = (child - 1) >>1;
return i;
}
return -1;
}
class pathFinder : public weightedGraph
{
private:
vertex* playerVertex;
double time;
public:
string source;
pathFinder()
{
playerVertex = NULL;
time = 0;
}
void Dijkstra(int s,int t)
{
vertex *verts = findVertex(grid[s][t]);
Heap H;
for each(vertex *v in vertexList)
{
if(v->data == verts->data)
{
verts->distance = 0;
verts->pred = NULL;
}
v->distance = INFINITY;
v->pred = NULL;
H.insert(v->data);
}
while(H.size() != 0)
{
vertex *x = findVertex(H.deletemin());
for each(edge *v in x->adjacencyList)
{
if(v->end->visited != true)
{
relax(x,v->end);
v->end->visited = true;
}
else
break;
}
}
}
void relax(vertex *a, vertex *b)
{
if(a->distance + weightFrom(a,b) > b->distance)
{
b->distance = a->distance + weightFrom(a,b);
b->pred = a;
}
}
void printPath(double dest,double dest1)
{
vertex *verta = findVertex(dest);
while(verta->pred->data != dest1)
{
cout<<verta->data<<endl;
verta = verta->pred;
}
}
and i'm not sure about the print path being that. i just used the print path from the BFS algorithm i've implemented before.
Where in your printPath function are you looking for the end of the list?
You keep going verta = verta->pred until the data is not equal to some value.
By the way, don't compare doubles for equality, as it ain't going to happen. See What Every Computer Scientist Should Know About Floating Point.
What happens when you single step with your debugger?
(Try drawing the links and how you traverse them.)