Unknown Error While Writing An Adjacent List Graph - c++

I was writing an adjacent list-based graph with weighted edges. My goal is to implement a graph to test the Djikstra's shortest path algorithm. I came to a bummer when I was implementing the removeEdge function. I looked at the build messages but I didn't have a clue as in what the errors below are about.
There are a few warnings before this one below but they are minor as it compiled and ran ok.
c:\program files (x86)\codeblocks\mingw\bin..\lib\gcc\mingw32\4.7.1\include\c++\bits\list.tcc||In instantiation of 'void std::list<_Tp, _Alloc>::remove(const value_type&) [with _Tp = Edge; _Alloc = std::allocator; std::list<_Tp, _Alloc>::value_type = Edge]':|
This is the error generated.
c:\program files (x86)\codeblocks\mingw\bin..\lib\gcc\mingw32\4.7.1\include\c++\bits\list.tcc|249|error: no match for 'operator==' in '__first.std::_List_iterator<_Tp>::operator*() == __value'|
Now, the code:
#ifndef WEIGHTED_ADJACENT_LIST_GRAPH_H
#define WEIGHTED_ADJACENT_LIST_GRAPH_H
#include <list>
#include <forward_list>
#include <stack>
#include <string>
using namespace std;
typedef int Weight;
class Edge;
class Vertex {
friend class Edge;
int num;
string name;
public:
Vertex();
Vertex(int n, string v_name){
num = n;
name = v_name;
}
int getNum() const{
return num;
}
string getName() const{
return name;
}
void setNum(int new_num){
num = new_num;
}
void setName(string new_name){
name = new_name;
}
};
class Edge {
Weight weight;
Vertex src;
Vertex dest;
public:
Edge();
Edge(Vertex s, Vertex d, Weight w):src(s), dest(d),weight(w){}
/*
Edge(Vertex s, Vertex d, Weight w){
src = s;
dest = d;
weight = w;
}
*/
Weight getWeight() const{
return weight;
}
int getSrcNum() const{
return src.num;
}
int getDestNum() const{
return dest.num;
}
};
class AdjacentList{
int num_Vertices;
list<Edge> *adj;
public:
AdjacentList();
AdjacentList(int n){
num_Vertices = n;
}
void addEdge(Vertex &i, Edge &j){
adj[i.getNum()].push_back(j);
}
void removeEdge(Vertex &i, Edge j){
if(!adj[i.getNum()].empty())
{
adj[i.getNum()].remove(j);
}
else{
cerr<<"Adjacent list underflow in removeEdge function"<<endl;
}
}
};
#endif
Please be noted that this graph is incomplete. A lot functions still need to be implemented there. Does anyone know what's wrong with this data structure code?

You haven't provided an operator== for Edge, I have no idea exactly how you want to specify which Edges are equal but you'll need something like the following defined before you use remove
bool operator==(Edge const& lhs, Edge const& rhs)
{
return
lhs.getWeight() == rhs.getWeight() &&
lhs.getSrcNum() == rhs.getSrcNum() &&
lhs.getDestNum() == rhs.getDestNum();
}

Related

Why am I getting a Link error when I try to overload an operator?

I'm doing a project exercise, where I'm revising a previous project of a class I created called Polynomial to use a link list (the original used arrays). The link list uses a template so that any type can be passed into it.
One of the problems I ran into with this project exercise is that I am trying to pass an object of type PolyNumber (from a class I made), and the link list bag I made has a function that compares any item (using ==) that is passed to it.
It works fine with regular types, such as int and string, but runs into problems with custom made object types. So I figured out how to overload the == operator in the PolyNumber class. By itself, it works when I test this class, but when I use this type with the Polynomial class with the Link List implementation, I get errors such as the following for each method in the Polynomial class:
Error LNK2005 "public: __thiscall PolyNumber::PolyNumber(int,int)" (??0PolyNumber##QAE#HH#Z) already defined in Polynomial.obj Project11
Here's my code for those files, but as you can see in the code, there are other files that go with this code, such as the LinkedBag for the link list object, but for space I just include these:
PolyNumber.h
#pragma once
class PolyNumber
{
public:
PolyNumber();
PolyNumber(int set_coefficent, int set_degree);
void setDegree(int set);
void setCoefficient(int set);
int getDegree();
int getCoefficient();
friend bool operator== (const PolyNumber& p1, const PolyNumber& p2);
friend bool operator!= (const PolyNumber& p1, const PolyNumber& p2);
private:
int degree;
int coefficient;
};
PolyNumber.cpp
#include "PolyNumber.h"
PolyNumber::PolyNumber()
{
coefficient = 0;
degree = 0;
}
PolyNumber::PolyNumber(int set_coefficent, int set_degree)
{
coefficient = set_coefficent;
degree = set_degree;
}
void PolyNumber::setDegree(int set)
{
degree = set;
}
void PolyNumber::setCoefficient(int set)
{
coefficient = set;
}
inline int PolyNumber::getDegree()
{
return degree;
}
inline int PolyNumber::getCoefficient()
{
return coefficient;
}
bool operator== (const PolyNumber& p1, const PolyNumber& p2)
{
return (p1.coefficient == p2.coefficient && p1.degree == p2.degree);
}
bool operator!= (const PolyNumber& p1, const PolyNumber& p2)
{
return !(p1 == p2);
}
Polynomial.h
#pragma once
#include "PolynomialInterface.h"
#include "LinkedBag.cpp"
#include "PolyNumber.cpp"
static const int POLYNOMIAL_SIZE = 10;
class Polynomial : public Polynomoal_Interface
{
public:
//Cunstructs am empty Polynomial
Polynomial();
//Copy constructor
Polynomial(Polynomial& copy);
/** Cunstructs a Polynomial with a client defined Polynomial
#param an array of non-negative integer coeffient that does not exceed POLYNOMIAL_SIZE, each coeffient in the array has a power that correspounds
to the respective value of the location of the ceffient in that array. */
Polynomial(int coeffient[POLYNOMIAL_SIZE], int size);
int degree();
int coefficient(int power);
bool changeCoefficient(int newCoefficient, int power);
private:
//static const int POLYNOMIAL_SIZE = 10;
//int polynomial[POLYNOMIAL_SIZE];
LinkedBag<PolyNumber> bag;
};
Polynomial.cpp
#include "Polynomial.h"
Polynomial::Polynomial()
{
}
Polynomial::Polynomial(Polynomial& copy)
{
std::vector<PolyNumber> copyFrom = copy.bag.toVector();
for (int i = 0; i < copyFrom.size(); i++)
{
bag.add(copyFrom[i]);
}
}
Polynomial::Polynomial(int coeffient[POLYNOMIAL_SIZE], int size)
{
for (int i = 0; i <= size; i++)
{
PolyNumber number = { coeffient[i], i + 1 };
bag.add(number);
}
}
int Polynomial::degree()
{
int max = 0;
std::vector<PolyNumber> result = bag.toVector();
for (int i = 0; i < result.size(); i++)
{
if (result[i].getDegree() > max)
{
max = result[i].getDegree();
}
}
return max;
}
int Polynomial::coefficient(int power)
{
int result = 0;
std::vector<PolyNumber> powerOf = bag.toVector();
for (int i = 0; i < powerOf.size(); i++)
{
if (powerOf[i].getDegree() == power)
{
result = powerOf[i].getCoefficient();
}
}
return result;
}
bool Polynomial::changeCoefficient(int newCoefficient, int power)
{
PolyNumber number = { newCoefficient, power };
int result = coefficient(power) + newCoefficient;
bag.remove(number);
number.setCoefficient(result);
bag.add(number);
return true;
}
You have #include "PolyNumber.cpp" instead of #include "PolyNumber.h".
That makes all the methods defined in PolyNumber.cpp to be included (and re-defined) in Polynomial.cpp.
The same will happen with LinkedBag.
Why are you including cpps?

Breadth First Search implementing to vector of Linked List

Can anybody explain me, how to do Breadth first search in the graph that uses vector of linked lists ?
My Graph header file:
#include <string>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct vertex {
string code;
vertex* next;
};
struct AdjList {
vertex *head;
AdjList(vertex* Given) {
head = Given;
}
};
class Graph {
map<string, string> associations;
int nodeNum; //amount of nodes or size of the graph;
vector<AdjList> adjList;
public:
Graph(int NodeNum);
~Graph();
int singleSize(string codeName);
int getSize();// must destroy every prerequisite list connected to the node
vertex* generateVertex(string codeName);
int getIndexOfVertex(vertex* givenVertex); // will find the location of the vertex in the array
void addVertex(vertex* newVertex);
void addEdge(string codeName, string linkCodeName);
void printPrerequisites(vertex* ptr, int i);
bool deleteVertex(string codeName);
bool deleteEdge(string codeName, string linkCodeName);
bool elemExistsInGraph(string codeName);
void printPrereq(string codeName);
void printCourseTitle(string codeName);
void printGraph();
};
I am trying to print all connected nodes within the graph using the breadth first search. Here is my code for the breadth first search algorithm that does not work.
void Graph::printPrereq(string codeName) {
int adjListSize = this->adjList.size();
int index = getIndexOfVertex(generateVertex(codeName));
bool visited[this->adjList.size()];
for(int i = 0; i < adjListSize; i++) {
visited[i] = false;
}
list<int> queue;
visited[index] = true;
queue.push_back(index);
while(!queue.empty()) {
index = queue.front();
vertex* pointer = this->adjList[index].head;
cout << pointer->code;
queue.pop_front();
while(pointer != nullptr){
if(!visited[getIndexOfVertex(pointer)]) {
queue.push_back(getIndexOfVertex(pointer));
visited[getIndexOfVertex(pointer)] = true;
}
cout << pointer->code <<"->";
pointer = pointer->next;
}
cout << "Null" << endl;
}
}
This algorithm outputs nodes that are only within the linked list, but not the ones that are connected through the graph.
Can anybody help and solve this problem?

How does the code for comparison object actually work?

I was learning the dijkstra's algorithm and then in that there was the concept of priority queue with min_heap implementation where my priority_queue <Node,vector<Node>,comp> min_heap and the comp is a comparison struct;
struct Edge{
int src;
int dest;
int weight;
};
struct Node{
int vertex;
int weight;
};
class Graph{
public:
vector<vector<Edge>> adjList;
Graph(vector<Edge> &edges,int N){
adjList.resize(N);
for(auto &edge:edges){
adjList[edge.src].push_back(edge);
}
}
};
struct comp{
bool operator()(const Node &lhs,const Node &rhs) const{
return lhs.weight>rhs.weight;
}
};
void dij(Graph g,int source,int N){
priority_queue<Node,vector<Node>,comp> min_heap;
min_heap.push({source,0});
vector<int> dist(N,INT_MAX);
dist[source] = 0;
vector<bool> done(N,false);
done[0] = true;
while(!min_heap.empty()){
Node node = min_heap.top();
min_heap.pop();
int u = node.vertex;
for(auto i:g.adjList[u]){
int v = i.dest;
int weight = i.weight;
if(!done[u] && dist[u]+weight<dist[v]){
dist[v] = dist[u] + weight;
min_heap.push({v,dist[v]});
}
}
done[u] = true;
}
cout<<"The path from vertex "<<source<<" to "<<N<<" is "<<dist[N];
}
The code works fine and prints the minimum cost but I am not understanding the struct comp(); and how this works.

Performance collapse C++ (std vector bad_allocation)

Following code is about searching for neighbours in realtime. As soon as a new node is added to my graph, the function updateSeqNeighbours for this node is called. What I know is, that the new node is definitely neighbour to the last one added. In the next step I use this fact to look in the neighbourhood of the previously added node, find the one closest to the new and then search this neighbourhood for the closest neighbour.
I repeat this only for example 3 times, to limit the number of neighbours for one node to 4 to keep a constant time frame for calculation. It works wonderful, except for after ~30 nodes the calculation time increases very fast with every additional node resulting in a bad_alloc exception.
#ifndef GRAPH_NODE_H_
#define GRAPH_NODE_H_
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
class Node {
public:
double x;
double y;
Node* nodePrev;
vector<Node> seqNeighbours;
//Constructor
Node();
Node(double x, double y);
virtual ~Node();
//Operator functions
Node& operator=(const Node& n);
//Get&Set
int getID();
//Public member functions
void addNeighbour(Node& n);
bool isSeqNeighbour(int ID);
int updateSeqNeighbours();
double distanceTo(Node& n);
private:
static int count;
int ID;
void _setDefaults();
};
int Node::count = 0;
Node::Node() {
_setDefaults();
}
Node::Node(double x, double y) {
_setDefaults();
this->x = x;
this->y = y;
}
Node::~Node() {
// TODO Auto-generated destructor stub
}
//Operator functions
Node& Node::operator=(const Node& n) {
if (this != &n) {
ID = n.ID;
x = n.x;
y = n.y;
seqNeighbours.clear();
seqNeighbours = n.seqNeighbours;
nodePrev = n.nodePrev;
}
return *this;
}
//Get&Set
int Node::getID() {
return this->ID;
}
//Public member functions
void Node::addNeighbour(Node& n) {
seqNeighbours.push_back(n);
}
double Node::distanceTo(Node& n) {
return sqrt((n.x-x)*(n.x-x) + (n.y-y)*(n.y-y));
}
bool Node::isSeqNeighbour(int ID) {
for (int i = 0; i < seqNeighbours.size(); i++) {
if (seqNeighbours[i].getID() == ID) {
return true;
}
}
return false;
}
int Node::updateSeqNeighbours() {
if (nodePrev == NULL) {
return 1;
} else {
Node seed = *nodePrev; //previous node as seed
seqNeighbours.push_back(seed);
for (int i = 0; i < 3; i++) {
if (seed.nodePrev == NULL) break;
double minDist = 15353453;
Node closest;
for (int j = 0; j < seed.seqNeighbours.size(); j++) {
double dist = distanceTo(seed.seqNeighbours[j]);
if (dist < minDist) {
minDist = dist;
closest = seed.seqNeighbours[j];
}
}
if (minDist < 150) {
seqNeighbours.push_back(closest);
}
seed = closest;
}
cout << "neighbours = " << seqNeighbours.size() << endl;
}
return 0;
}
void Node::_setDefaults() {
x = 0;
y = 0;
ID = count;
nodePrev = NULL;
seqNeighbours.clear();
count++;
}
#endif /* GRAPH_NODE_H_ */
Graph:
#ifndef GRAPH_GRAPH_H_
#define GRAPH_GRAPH_H_
#include <vector>
#include <iostream>
#include "Node.h"
using namespace std;
class Graph {
public:
Graph();
virtual ~Graph();
vector<Node> list;
void addNode(Node& n);
void addSeqNode(Node& n);
private:
void _setDefaults();
};
Graph::Graph() {
// TODO Auto-generated constructor stub
}
Graph::~Graph() {
// TODO Auto-generated destructor stub
}
void Graph::addNode(Node& n) {
list.push_back(n);
}
void Graph::addSeqNode(Node& n) {
if (!list.empty()) {
n.nodePrev = &list.back();
}
n.updateSeqNeighbours();
list.push_back(n);
}
void Graph::_setDefaults() {
list.clear();
}
#endif /* GRAPH_GRAPH_H_ */
I suspect running out of memory causes this. However 40 nodes with each 4 neighbours doesn't sound much of a problem to me. Anyone any idea what goes wrong?
Edit:
Error in german, so I need to guess:
An exception accured in project prSimulation1.exe of class std::bad_alloc. Adress of Exception: '0x5476016'. Process was stopped.
Your seqNeighbours is vector<Node>. That means it stores the neighbours themselves, not pointers to them or their indices. The copy constructor, therefore, copies all the neighbours. Copying each neighbour, in turn, requires to copy its neighbours, which requires to copy their neighbours, and so on. Your assignment also copies all the neighbours, which requires to copy their neighbours, and so on. This means that each copy exponentially increases memory load, until the system is unable to store all the neighbours, neighbours of neigbours etc.
PS: on a side note, a vector called "list" is a bad idea. It is like a list called "vector", a set called "map", or a cat called Dog.

How to get the min value of an object in a list (C++)

I've a question to ask.
So, I have a structure call Node as shown below:
struct Node
{
int xKoor, yKoor;
Node *parent;
char nodeId;
float G;
float H;
float F;
Node(int x, int y, int id, Node * par)
{
xKoor = x;
yKoor = y;
nodeId = id;
parent = 0;
}
Node(int x, int y, char id)
{
xKoor = x;
yKoor = y;
nodeId = id;
}
};
And I have list that contains elements of this structure:
list<Node*> OPEN;
This list's size varies in time.
What I need to do is to find the Node object which has the minimum F value, then pop out that object from the list.
So, I tried to write a function as shown below:
void enKucukFliNodeBul(list<Node*> OPEN)
{
list<Node*>::iterator it = OPEN.begin();
for(it = OPEN.begin(); it != OPEN.end(); it++)
{
if(it._Ptr->_Myval->F < it._Ptr->_Next->_Myval->F)
{
}
}
}
But I'm stuck. I'm new to STL. How can I solve this?
My best regards...
You can use std::min_element with a suitable comparison function for this.
bool nodeComp(const Node* lhs, const Node* rhs) {
return lhs->F < rhs->F;
}
#include <algorithm> // for std::min_element
list<Node*>::iterator it = std::min_element(OPEN.begin(), OPEN.end(), nodeComp);
This assumes that list<Node*> is std::list<Node*>, in which case you should be aware that std::list itself is a linked list.
Other useful operations, based on your comments:
Remove a minimum value node from the list and delete it:
OPEN.erase(it);
delete *it; //
You may need to perform other operations, if your nodes depend on each other.
Sort the list:
OPEN.sort(nodeComp);
use std::min_element algirithm and overload Compare function
bool compareF(Node *lhs, Node *rhs)
{
return lhs->F < rhs->F;
}
if you are using C++03:
std::<Node*>::itertor ter = std::min_element(OPEN.begin(),OPEN.end(), compareF);
if you are using C++11:
auto iter = std::min_element(OPEN.begin(),OPEN.end(), compareF);
To sort the list, you can call OPEN.sort(compareF); to sort your list with compareF function
Try adding this:
bool compare_node_F(Node* n1, Node* n2)
{
return n1-> F< n2-> F;
}
#include <list>
#include <algorithm>
#include <cstdlib>
#include <iostream>
int main()
{
std::list<Node*> nodes;
for(int i= 100; i--;)
{
Node* n= new Node(42, 42, 42);
n-> F= i;
nodes.push_back(n);
}
std::list<Node*>::iterator min_element_iter= std::min_element(nodes.begin(), nodes.end(), compare_node_F);
std::cout<< "Min F: "<< (*min_element_iter)-> F<< '\n';
for(std::list<Node*>::iterator d= nodes.begin(); d!= nodes.end(); ++ d)
delete *d;
}