Graph traversal with A* algorithm - c++

Hey, I'm AI Student and gonna try my homework that is implementation of A* algorithm in order to traversal a graph. i use c++ codes and what i made for now is below code which is only a Graph class + insertedge and vertices functions.
but now i'm confused of how to define cost function (f= h(n) + g(n)) ...
also any code refrence or explain of how A* works for graphs would help me . what i found in google was about pathfinding via a* and it has nothing with traversal graph.
#include <iostream>
using namespace std;
class Graph;
class node {
friend class Graph;
private:
char data;
int cost;
node *next;
node *vlist;
bool goal;
bool visited;
public:
node(char d,int c, bool g){
cost = c;
goal = g;
next = NULL;
data = d;
vlist = NULL;
visited = false;
}
};
class Graph {
private:
node *Headnodes;
char n;
public:
Graph ()
{
Headnodes = NULL;
}
void InsertVertex(char n, int c, bool g);
void InsertEdge(char n, char m, int c);
void PrintVertices();
void Expand(char n);
};
/////////////////
// INSERTION //
/////////////////
void Graph::InsertVertex(char n, int c, bool g){
node *temp = new node(n,c,g);
if(Headnodes==NULL)
{
Headnodes=temp;
return;
}
node *t=Headnodes;
while(t->vlist!=NULL)
t=t->vlist;
t->vlist=temp;
}
void Graph::InsertEdge(char n, char m, int c){
int temp_cost = 0;
if(Headnodes==NULL)
return;
node *x=Headnodes;
while(x!=NULL){
if(x->data==m)
temp_cost = (x->cost+c);
x = x->vlist;
}
node *t=Headnodes;
node *temp=new node(m,temp_cost,false);
while(t!=NULL){
if(t->data==n){
node *s=t;
while(s->next!=NULL)
s=s->next;
s->next=temp;
}
t=t->vlist;
}
}
int min_cost = 1000;
bool enough = false;
void Graph::PrintVertices(){
node *t=Headnodes;
while(t!=NULL){
cout<<t->data<<"\t";
t=t->vlist;
}
}
void Graph::Expand(char n){
cout << n << "\t";
char temp_min;
node *t=Headnodes;
while(t!=NULL){
if(t->data==n && t->visited == false){
t->visited = true;
if (t->goal)
return;
while(t->next!=NULL){
if (t->next->cost <= min_cost){
min_cost=t->next->cost;
temp_min = t->next->data;
}
t = t->next;
}
}
t=t->vlist;
}
Expand(temp_min);
}
int main(){
Graph g;
g.InsertVertex('A',5,false);
g.InsertVertex('B',1,false);
g.InsertVertex('C',9,false);
g.InsertVertex('D',5,false);
g.InsertVertex('E',1,false);
g.InsertVertex('F',3,false);
g.InsertVertex('G',2,false);
g.InsertVertex('J',1,false);
g.InsertVertex('K',0,true);
g.InsertEdge('A','B',2);
g.InsertEdge('A','C',1);
g.InsertEdge('B','A',2);
g.InsertEdge('B','D',1);
g.InsertEdge('B','E',1);
g.InsertEdge('C','A',1);
g.InsertEdge('C','F',1);
g.InsertEdge('C','G',1);
g.InsertEdge('E','J',3);
g.InsertEdge('E','K',3);
g.PrintVertices();
cout<<"\n\n";
g.Expand('A');
return 0;
}

What you have is only a graph search algorithm.
You forgot the essence of the A* algorithm, that is the h(n) cost, that comes from an heuristic calculation.
You have to implement a method, the h(n) that will calculate, based on yours heuritics, the possible cost from actual path to the final path, and this value will be used to calculate the walking cost:
f'(n) = g(n) + h'(n), being the g(n) the already know cost, at your case, the x->cost.
g(n) is the total distance cost it has
taken to get from the starting
position to the current location.
h'(n) is the estimated distance cost from
the current position to the goal
destination/state. A heuristic
function is used to create this
estimate on how far away it will take
to reach the goal state.
f'(n) is the sum of g(n) and h'(n).
This is the current estimated shortest
path. f(n) is the true shortest path
which is not discovered until the A*
algorithm is finished.
So, what you have to do:
Implement a method heuristic_cost(actual_node, final_node);
Use this value together with the actual cost, like the equation before, by example: min_cost=t->next->cost + heuristic_cost(t->next, final_node) ;
I really like the explanation here: Link , cleaner than wikipedia's explanation.

Related

Recursive function to get a decimal number out of a list of binaries

If I have a list with N elements that represent a binary number, and each node (I named it info) is a boolean (true = 1, false = 0) what would the best way to get the decimal value using a recursive function be?
I tried using google but I only came with the formula for decimal;
1 * 2N + 0 * 2N-1 + 0 * 2N-2 + ... + 1 * 21 + 1 * 20
Right now I have a header and some basic structure for the method, according to what I understand of the problem. Also the problem says the first digit is the most significative but I don´t quite get if that is relevant.
int Lista:: ConvierteBinarioDecimal ( void ) const;
static int suma= 0;
ConvierteBinarioDecimal();
}
return suma;
}
And the Nodo (node) class.
class Nodo{
public:
bool Nodo::getInfo(void); //Retorns the content of info
Nodo* Nodo::getNext(void); //Retorns the cotent of next
private:
bool info;
Nodo *next;
};
class Lista{
Nodo *primero;
int longitud;
};
I started learning C++ last week and so far it has been way more tough than Java >_< so any help would be a godsend.
This is a recursive example:
I have to do some little changes, adding const to getInfo (there is no problem here) and adding const to getNext (you could need also and non-const version), the problem was that function ConvierteBinarioDecimal is declared as const which is good (don't have to change anything for calculating decimal representation, but this force, that the two method need to be const) you could add non-const version if needed.
The static int ConvierteBinarioDecimal(Nodo const* node) { is the recursive implementation of the conversion to decimal from binary. If it need to be recursive this is your sample code, if you could use an iterative version would be better for performance.
#include <algorithm>
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Nodo {
public:
bool getInfo(void) const { return info; } // Retorns the content of info
Nodo* getNext(void) const { return next; } // Retorns the cotent of next
Nodo(bool i, Nodo* n) : info(i), next(n) {}
private:
bool info;
Nodo* next;
};
class Lista {
Nodo* primero;
int longitud;
public:
int ConvierteBinarioDecimal(void) const;
Lista(Nodo* p, int l) : primero(p), longitud(l) {}
};
static int ConvierteBinarioDecimal(Nodo const* node, int decimal = 0) {
if (node == NULL) // prefer C++11 nullptr
return decimal;
decimal *= 2;
if (node->getInfo())
decimal++;
return ConvierteBinarioDecimal(node->getNext(), decimal);
}
int Lista::ConvierteBinarioDecimal(void) const {
return ::ConvierteBinarioDecimal(primero);
}
int main(int argc, char* argv[]) {
Lista list(new Nodo(true, new Nodo(false, new Nodo(true, new Nodo(true, NULL)))), 4);
std::cout << list.ConvierteBinarioDecimal() << std::endl;
return 0;
}
ConvierteBinarioDecimal()
{
int indice = longitud;
Nodo *corriente = primero; // current, begin at first node
while (corriente != null)
{
if (corriente->getInfo())
suma += 1 << --indice; // use bitshifting to add this binary digit
// alternatively, this could be "suma |= 1 << --indice;"
corriente = corriente->getNext(); // go to next node
}
}
I hope the Spanish helps as well! :)
One of the fastest ways to do this is to use bit shift operations. So, for example:
long decimal = 0;
Nodo * current = primero;
unsigned int bitcounter = 0;
while(current)
{
if(current->getInfo)
{
long temp = 1;
temp << bit counter;
decimal |= temp;
}
bitcounter++;
current = current->next;
}
Basically, what I've done here is to look at each bit in a while look. Note how I traverse the linked list. I stop when current->next is null by checking current in the following iteration. I also keep track of which bit I'm processing. For each bit, if the bit is 1, I place that into a temporary variable and shift it over to the right position using the << operator. Then I OR this temporary variable with the running total using the |= operator (OR and assignment).
Now, to do this recursively:
long ConvertBinaryToDecimal()
{
static long decimal = 0;
static Nodo * current = primero;
// Base case
if(!current)
{
current = primero;
long result = decimal;
decimal = 0;
return result;
}
else {
decimal = decimal<<1;
if(primero->getInfo())
decimal |= 1;
current = current->next;
ConvertBinaryToDecimal();
}

Hash table implementation in C++

I am trying the following code for Hash table implementation in C++. The program compiles and accepts input and then a popup appears saying " the project has stopped working and windows is checking for a solution to the problem. I feel the program is going in the infinite loop somewhere. Can anyone spot the mistake?? Please help!
#include <iostream>
#include <stdlib.h>
#include <string>
#include <sstream>
using namespace std;
/* Definitions as shown */
typedef struct CellType* Position;
typedef int ElementType;
struct CellType{
ElementType value;
Position next;
};
/* *** Implements a List ADT with necessary functions.
You may make use of these functions (need not use all) to implement your HashTable ADT */
class List{
private:
Position listHead;
int count;
public:
//Initializes the number of nodes in the list
void setCount(int num){
count = num;
}
//Creates an empty list
void makeEmptyList(){
listHead = new CellType;
listHead->next = NULL;
}
//Inserts an element after Position p
int insertList(ElementType data, Position p){
Position temp;
temp = p->next;
p->next = new CellType;
p->next->next = temp;
p->next->value = data;
return ++count;
}
//Returns pointer to the last node
Position end(){
Position p;
p = listHead;
while (p->next != NULL){
p = p->next;
}
return p;
}
//Returns number of elements in the list
int getCount(){
return count;
}
};
class HashTable{
private:
List bucket[10];
int bucketIndex;
int numElemBucket;
Position posInsert;
string collision;
bool reportCol; //Helps to print a NO for no collisions
public:
HashTable(){ //constructor
int i;
for (i=0;i<10;i++){
bucket[i].setCount(0);
}
collision = "";
reportCol = false;
}
int insert(int data){
bucketIndex=data%10;
int col;
if(posInsert->next==NULL)
bucket[bucketIndex].insertList(data,posInsert);
else { while(posInsert->next != NULL){
posInsert=posInsert->next;
}
bucket[bucketIndex].insertList(data,posInsert);
reportCol=true;}
if (reportCol==true) col=1;
else col=0;
numElemBucket++;
return col ;
/*code to insert data into
hash table and report collision*/
}
void listCollision(int pos){
cout<< "("<< pos<< "," << bucketIndex << "," << numElemBucket << ")"; /*codeto generate a properly formatted
string to report multiple collisions*/
}
void printCollision();
};
int main(){
HashTable ht;
int i, data;
for (i=0;i<10;i++){
cin>>data;
int abc= ht.insert(data);
if(abc==1){
ht.listCollision(i);/* code to call insert function of HashTable ADT and if there is a collision, use listCollision to generate the list of collisions*/
}
//Prints the concatenated collision list
ht.printCollision();
}}
void HashTable::printCollision(){
if (reportCol == false)
cout <<"NO";
else
cout<<collision;
}
The output of the program is the point where there is a collision in the hash table, thecorresponding bucket number and the number of elements in that bucket.
After trying dubbuging, I come to know that, while calling a constructor you are not emptying the bucket[bucketIndex].
So your Hash Table constructor should be as follow:
HashTable(){ //constructor
int i;
for (i=0;i<10;i++){
bucket[i].setCount(0);
bucket[i].makeEmptyList(); //here we clear for first use
}
collision = "";
reportCol = false;
}
//Creates an empty list
void makeEmptyList(){
listHead = new CellType;
listHead->next = NULL;
}
what you can do is you can get posInsert using
bucket[bucketIndex].end()
so that posInsert-> is defined
and there is no need to
while(posInsert->next != NULL){
posInsert=posInsert->next;
because end() function is doing just that so use end() function

A Problem with Vectors (std::out_of_range)

Here is the description of my problem:
The Program's Description:
I am implementing a program in C++ that tests Prim's algorithm for finding minimum spanning trees. The objective of the program is calculating the number of seconds it takes to find the minimum spanning tree for a selected number of random graphs.
What i have done up to now?
I finished the implementation of the functions and the header files for the whole program. Since the source code is small, i decided for clarity reasons to paste it with this mail in order to provide a better visualization of the problem.
The Problem:
For some reason, i am facing some sort of "out of range" vector problem during the run time of the application.
The problem is marked in the ("Prim_and_Kruskal_Algorithms.cpp") file.
Requesting help:
I would be really grateful if anyone can help me spotting the problem. I have inlined the source code with this question.
The Source Code:
The (Undirected_Graph.h) file:
#ifndef UNDIRECTED_GRAPH_H
#define UNDIRECTED_GRAPH_H
#include <vector>
using std::vector;
#include <climits>
class Edge;
class Node
{
public:
Node(int); //The constructor.
int id; //For the id of the node.
bool visited; //For checking visited nodes.
int distance;
vector <Edge*> adj; //The adjacent nodes.
};
class Edge
{
public:
Edge(Node*, Node*, int); //The constructor.
Node* start_Node; //The start_Node start of the edge.
Node* end_Node; //The end of the edge.
int w; //The weight of the edge.
bool isConnected(Node* node1, Node* node2) //Checks if the nodes are connected.
{
return((node1 == this->start_Node && node2 == this->end_Node) ||
(node1 == this->end_Node && node2 == this->start_Node));
}
};
class Graph
{
public:
Graph(int); //The Constructor.
int max_Nodes; //Maximum Number of allowed Nodes.
vector <Edge*> edges_List; //For storing the edges of the graph.
vector <Node*> nodes_List; //For storing the nodes of the graph.
void insertEdge(int, int, int);
int getNumNodes();
int getNumEdges();
};
#endif
The (Undirected_Graph.cpp) file:
#include "Undirected_Graph.h"
Node::Node(int id_Num)
{
id = id_Num;
visited = 0;
distance = INT_MAX;
}
Edge::Edge(Node* a, Node* b, int weight)
{
start_Node = a;
end_Node = b;
w = weight;
}
Graph::Graph(int size)
{
max_Nodes = size;
for (int i = 1; i <= max_Nodes; ++i)
{
Node* temp = new Node(i);
nodes_List.push_back(temp);
}
}
void Graph::insertEdge(int x, int y, int w)
{
Node* a = nodes_List[x-1];
Node* b = nodes_List[y-1];
Edge* edge1 = new Edge(a, b, w);
Edge* edge2 = new Edge(b, a, w);
edges_List.push_back(edge1);
a->adj.push_back(edge1);
b->adj.push_back(edge2);
}
int Graph::getNumNodes()
{
return max_Nodes;
}
int Graph::getNumEdges()
{
return edges_List.size();
}
The (Prim_and_Kruskal_Algorithms.h) File:
#ifndef PRIM_AND_KRUSKAL_ALGORITHMS_H
#define PRIM_AND_KRUSKAL_ALGORITHMS_H
class PKA
{
private:
//inline void generateRandomGraph();
protected:
//-No Protected Data Members in this Class.
public:
void runAlgorithms();
void prim();
};
#endif
The (Prim_and_Kruskal_Algorithms.cpp) file
*(The problem is in this file and is marked below):*
#include "Prim_and_Kruskal_Algorithms.h"
#include "Undirected_Graph.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <cstdlib>
using std::rand;
using std::srand;
#include <ctime>
using std::time;
//=============================================================================
//============Global Variables and Settings for the program====================
//=============================================================================
const int numIterations = 1; //How many times the Prim function will run.
const int numNodes = 10; //The number of nodes in each graph.
const int numEdges = 9; //The number of edges for each graph.
const int sRandWeight = 1; //The "start" range of the weight of each edge in the graph.
const int eRandWeight = 100; //The "end" range of the weight of each edge in the graph.
//=============================================================================
//=============================================================================
//=============================================================================
void PKA::runAlgorithms() //Runs the Algorithms
{
srand( time(0) );
cout << "------------------------------" << endl;
//Calling the Functions:
cout << "\nRunning the Prim's Algorithms:\nPlease wait till the completion of the execution time" << endl;
//===============================================
//Start the clock for Prim's Algorithm:
clock_t start, finish;
start = clock();
for(int iter1 = 1; iter1 <= numIterations; ++iter1)
{
prim();
}
//Stop the clock for Prim and print the results:
finish = clock();
cout << "\n\tThe execution time of Prim's Algorithm:\t" << ((double)(finish - start) / CLOCKS_PER_SEC) << " s";
return;
}
void PKA::prim()
{
//=============================================================================
//=============================Generating A Random Graph=======================
//=============================================================================
//Randomizing Values:
//===============================================
int randStartNode = rand() % numNodes; //Generation a random start node.
int randEndNode = rand() % numNodes; //Generating a random end node.
int randWeight; //Random weight for the edge.
while(randEndNode == randStartNode) //Checking if both randomized nodes are equal.
{
randEndNode = (rand() % numNodes);
}
//===============================================
Graph myGraph(numNodes);
for(int i = 0; i < numEdges; ++i)
{
//Generating a random weight:
randWeight = sRandWeight + rand() % eRandWeight;
//Inserting a new Edge:
myGraph.insertEdge(randStartNode, randEndNode, randWeight);
}
//=============================================================================
//=============================================================================
//=============================================================================
int currentNode = 0; //The current Node being under investigation.
int adjCounter = NULL; //How many adjacent nodes do we have for the current node.
int minDistance = NULL;
int minIndex = 0;
myGraph.nodes_List[0]->distance = 0; //Indicate the start node.
myGraph.nodes_List[0]->visited = 1; //The starting node is already considered as a visited node.
for(int i = 0; i < numNodes - 1; i++)
{
//Determine how many adjacent nodes there are for the current node:
adjCounter = myGraph.nodes_List[currentNode]->adj.size();
if(adjCounter == 0) //If there are no adjacent nodes to the current node:
{
myGraph.nodes_List[currentNode]->adj.at(minIndex)->end_Node->visited = 1;
cout << "\n*******Not all nodes are connected!*******" << endl;
continue;
}
minDistance = myGraph.nodes_List[currentNode]->adj.at(0)->w;
minIndex = 0;
for(int counter = 0; adjCounter > 0; adjCounter--, counter++)
{
if(myGraph.nodes_List[currentNode]->adj[counter]->end_Node->visited == false)
{
if(myGraph.nodes_List[currentNode]->distance > myGraph.nodes_List[currentNode]->adj[counter]->w)
{
myGraph.nodes_List[currentNode]->distance = myGraph.nodes_List[currentNode]->adj[counter]->w;
}
if(minDistance > myGraph.nodes_List[currentNode]->adj[counter]->w)
{
minDistance = myGraph.nodes_List[currentNode]->adj[counter]->w;
minIndex = counter;
}
}
}
//======================================================================================
//=========================The Problem is in the following two lines====================
//======================================================================================
//Mark the current node as visited:
myGraph.nodes_List[currentNode]->adj.at(minIndex)->end_Node->visited = 1;
//Switching to the next node that we have just visited:
currentNode = myGraph.nodes_List[currentNode]->adj.at(minIndex)->start_Node->id;
//======================================================================================
//======================================================================================
//======================================================================================
}
}
The (Client_Code.cpp) file: For testing the program.
#include "Prim_and_Kruskal_Algorithms.h"
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "\nWelcome to the Prim and Kruskal Algorithms Comparison!" << endl;
cout << "\nPlease wait until the completion of the algorithms." << endl;
PKA myPKA; //Creating an object of the class.
myPKA.runAlgorithms(); //Running the Algorithm.
cout << "\n\nThe program terminated successfully!" << endl;
return 0;
}
Look at this line:
myGraph.nodes_List[currentNode]->adj.at(minIndex)->end_Node->visited = 1;
As an experienced C++ programmer, I find that line terrifying.
The immediate cause of trouble is that adj doesn't have as many members as you think it does; you're asking for (in my test run) the 5th element of a list of size zero. That sends you off the map, where you then start manipulating memory.
More generally, you are not checking bounds.
More generally still, you should allow these classes to manage their own members. Use accessors and mutators (getX() and setX(...)) so that member access happens all in one place and you can put the bounds checking there. Reaching down myGraph's throat like that is very unsafe.
You'll notice that I haven't said where/when/how the program diverges from intention so that the list doesn't have as many elements as it should. That's because it's too much trouble for me to track it down. If you organize the classes as I suggest, the code will be a lot cleaner, you can check your assumptions in various places, and the bug should become obvious.
EDIT:
To create a random connected graph, try this:
Graph myGraph(numNodes); //Create a new Graph.
// This ensures that the kth node is connected to the [1...(k-1)] subgraph.
for(int k=2 ; k<=numNodes ; ++k)
{
randWeight = rand() % eRandWeight;
myGraph.insertEdge(k, rand()%(k-1)+1, randWeight);
}
// This adds as many extra links as you want.
for(int i = 0; i < numExtraEdges; ++i)
{
randWeight = rand() % eRandWeight;
randStartNode = rand()%(numNodes-1)+1;
randEndNode = rand()%(numNodes-1)+1;
myGraph.insertEdge(randStartNode, randEndNode, randWeight);
}
You have too much code for a casual examination to be sure of anything. But the .at() method will throw the out-of-range exception that you mentioned and that crashing line occurs right after you've updated minIndex so I would suggest reviewing the code that determines that value. Are you using a debugger? What is the value of minIndex at the point of the exception and what is the allowable range?
Also, when you have a monster line of compounded statements like that, it can help in debugging problems like this and give you clearer, simpler looking code if you break it up. Rather than repeating big chunks of code over and over, you can have something like this:
Node * node = myGraph.nodes_List[currentNode];
assert(node);
Edge * minAdjEdge = node->adj.at(minIndex);
assert(minAdjEdge);
Then use minAdjEdge to refer to that edge instead of that repeated compound statement.
It also seems odd to me that your first use of minIndex in the big loop is still using the value determined from the node in the previous iteration, but it's applying it to the new current node. Then you reset it to zero after possibly using the stale value. But that isn't near the line that you say is causing the crash, so that may not be your problem. Like I said, you have a lot of code pasted here so it's hard to follow the entire thing.
It is too much code, but what I can observe at the first glance is that for some reason you are mixing 0-based and 1-based iteration.
Is this intentional? Couldn't that be the cause of your problem?

How to sort a Vector of type <class*>? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ how to sort vector<class *> with operator <
Hello everyone!
Please i am trying to sort a vector of type "class" based on one of its data members. As follows:
The Header File: (Undirected_Graph.h)
#ifndef UNDIRECTED_GRAPH_H
#define UNDIRECTED_GRAPH_H
#include <vector>
using std::vector;
#include <climits>
class Edge;
class Node
{
public:
Node(int); //The constructor.
int id; //For the id of the node.
bool visited; //For checking visited nodes.
int distance;
vector <Edge*> adj; //The adjacent nodes.
};
class Edge
{
public:
Edge(Node*, Node*, int); //The constructor.
Node* start_Node; //The start_Node start of the edge.
Node* end_Node; //The end of the edge.
int w; //The weight of the edge.
bool isConnected(Node* node1, Node* node2) //Checks if the nodes are connected.
{
return((node1 == this->start_Node && node2 == this->end_Node) ||
(node1 == this->end_Node && node2 == this->start_Node));
}
};
class Graph
{
public:
Graph(int); //The Constructor.
int max_Nodes; //Maximum Number of allowed Nodes.
vector <Edge*> edges_List; //For storing the edges of the graph.
vector <Node*> nodes_List; //For storing the nodes of the graph.
void insertEdge(int, int, int);
int getNumNodes();
int getNumEdges();
};
#endif
The Implementation File: (Undirected_Graph.cpp)
#include "Undirected_Graph.h"
Node::Node(int id_Num)
{
id = id_Num;
visited = 0;
distance = INT_MAX;
}
Edge::Edge(Node* a, Node* b, int weight)
{
start_Node = a;
end_Node = b;
w = weight;
}
Graph::Graph(int size)
{
max_Nodes = size;
for (int i = 1; i <= max_Nodes; ++i)
{
Node* temp = new Node(i);
nodes_List.push_back(temp);
}
}
void Graph::insertEdge(int x, int y, int w)
{
Node* a = nodes_List[x-1];
Node* b = nodes_List[y-1];
Edge* edge1 = new Edge(a, b, w);
Edge* edge2 = new Edge(b, a, w);
edges_List.push_back(edge1);
a->adj.push_back(edge1);
b->adj.push_back(edge2);
}
int Graph::getNumNodes()
{
return max_Nodes;
}
int Graph::getNumEdges()
{
return edges_List.size();
}
Now in the above code, after creating several nodes and edges, i need to sort the edges of this graph based on their weight. I am studying a way to implement Kruskal algorithm so i though of sorting the edges first based on their weight.
sort (myGraph.edges_List[index].begin(), myGraph.edges_List[index].end());
obviously does not work! since the vector edges_List is of type "Edge".
Assuming that (myGraph is an object of the class).
I was wondering if there is any good technique to do that?
Thanks in advance for your help! Any suggestions or ideas are greatly appreciated!
By default, std::sort uses using operator<, but you can also supply a comparison function object.
So:
bool your_comparer(const Edge * left, const Edge * right)
{
// return true if left should come before right, false otherwise
}
// ...
sort (myGraph.edges_List.begin(), myGraph.edges_List.end(), your_comparer);
Another way is usage std::set container for storing your objects. And you always will have sorted container. All you need is define operator < for stored classes.
Usage vector with push_back is not effective way in terms of time. It cause unnecessary memory rellocations.

Digraph arc list implementation

I'm trying to implement graph as the Arc List, and while this implementation works efficiency is horrible, anything i missed that's making it so slow? Time was measured as the average of looking for arcs from/to each node.
struct Arc
{
int start;
int end;
Arc(int start,int end)
: start(start),
end(end)
{ }
};
typedef vector<Arc> ArcList;
class AListGraph
{
public:
AListGraph(IMatrix* in); //Fills the data from Incidence Matrix
bool IsE(int va,int vb); //checks if arc exists a->b
int CountEdges(); //counts all the arcs
int CountNext(int v); //counts all outgoing arcs from v
int CountPrev(int v); //counts all arcs incoming to v
private:
ArcList L;
int VCount;
};
//Cut out constructor for clarity
int AListGraph::CountEdges()
{
return L.size();
}
int AListGraph::CountNext(int v)
{
int result=0;
for(ArcList::iterator it =L.begin();it!=L.end();it++)
{
if(it->end==v)result++;
}
return result;
}
int AListGraph::CountPrev(int v)
{
int result=0;
for(ArcList::iterator it =L.begin();it!=L.end();it++)
{
if(it->start==v)result++;
}
return result;
}
Well, your implemention is worst possible : in order to find the in/out edges you have go across the whole graph.
Do you really need an arc list? Usually an adjacency list is much more efficient.
A naïve implementation of an adjacency list would be to keep an vector > arcs where the size of the arc is the number of nodes.
Given an node u, arcs[u] gives you all the out edges. You can figure out how to optimize it for in edges also.