Implementing Dijkstra's algorithm with vector of pointers - c++

I'm working on a program involving Dijkstra's algorithm.
After searching long and far, I have only found help pertaining to Dijkstra's algorithm using Queues or Heaps, however, I am not using these. I have been tasked to used a vector of pointers to Vertex objects (a custom class I have defined).
I have attempted to convert the Queue pseudo code (from my textbook) to the best of my ability below:
void Dijkstra(vector<Vertex*> & V, int startNum)
{
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0);
insertionSort(sortedVertices);
while(sortedVertices.size() != 0)
{
sortedVertices[sortedVertices.size() - 1]->setKnown(true);
sortedVertices.pop_back();
insertionSort(sortedVertices);
Vertex * v = V[1]; // Will always bring the first element off the list
v->setKnown(true);
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
{
int dist = getAdjacentVertices()[m].getWeight();
if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
{
//WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
cout << "It works so far" << endl;
// BOOK has this, somehow need to change it: w.path = v
}
}
}
}
However, when I attempt to compile, I keep receiving the following errors:
Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'
I am trying to reduce the amount of Code in this post, but if need to be, my entire code is below:
Main.cpp:
#include "Vertex.h"
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
void shortestPath(vector<Vertex> & v);
template <typename Comparable>
void insertionSort(vector<Comparable> & a);
template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right );
///overload the less than operator in order to use the stl sort for vector
///print out the path for each vertex
int main()
{
/////READ ALL THE STUFF INTO THE GRAPH////
ifstream file;
file.open("graph.txt");
cout << "Opening file..." << endl;
if(!file)
{
cout << "System failed to open file.";
}
else
{
cout << "File successfully opened" << endl;
}
int numVertices;
int numEdges;
int num;
int adjacentVertex;
int weight;
file >> numVertices;
cout << "The number of vertices that are being read into the graph from the file: " << numVertices;
cout << endl;
vector<Vertex*> vertices;
//vector<Vertex> vertices(numVertices + 1);
Vertex * newVertex;
vertices.push_back(NULL);
cout << "SIZE: " << vertices.size() << endl;
cout << "NUM VERTICES: " << numVertices << endl;
for(int i=1;i < numVertices + 1; i++)
{
file >> numEdges;
cout << "At vertex " << i << " the number of edges is " << numEdges << endl;
newVertex = new Vertex();
//Using the i counter variable in the outer for loop to identify
//the what vertex what are currently looking at in order to read in the correct adjacent vertex and weight
cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
newVertex->setVertexNum(i);
//newVertex.setVertexNum(i);
for(int j=1;j<=numEdges;j++)
{
file >> adjacentVertex;
cout << "The adjacent vertex is: " << adjacentVertex << endl;
file >> weight;
cout << "The weight is: " << weight << endl;
cout << endl;
newVertex->setAdjacentVertex(adjacentVertex, weight);
}
//cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
vertices.push_back(newVertex);
}
file.close();
vector<Vertex*> sortedVertices = vertices;
insertionSort(sortedVertices);
cout << "SIZE: " << vertices.size() << endl;
for(int i=0;i<vertices.size();i++)
{
cout << "V" << i << ": ";
cout << endl;
if(vertices[i] != NULL)
{
cout << "DV Value: " << vertices[i]->getDV();
cout << endl;
cout << "Known Value: " << vertices[i]->getKnown();
cout << endl;
}
}
cout << "Sorted: " << endl;
for(int i=0;i<sortedVertices.size();i++)
{
cout << "V" << i << ": ";
cout << endl;
if(vertices[i] != NULL)
{
cout << "DV Value: " << sortedVertices[i]->getDV();
cout << endl;
cout << "Known Value: " << sortedVertices[i]->getKnown();
cout << endl;
}
}
//CALL THE SHORTEST PATH FUNCTION ON THE GRAPH/////
}
/*
const bool myFunction(const Vertex & x, const Vertex & y)
{
return (x.getDV() >= y.getDV());
}
*/
bool operator < (const Vertex & v1, const Vertex & v2)
{
return v1.getDV() > v2.getDV();
}
void Dijkstra(vector<Vertex*> & V, int startNum)
{
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0);
insertionSort(sortedVertices);
while(sortedVertices.size() != 0)
{
sortedVertices[sortedVertices.size() - 1]->setKnown(true);
sortedVertices.pop_back();
insertionSort(sortedVertices);
Vertex * v = V[1]; // Will always bring the first element off the list
v->setKnown(true);
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
{
int dist = getAdjacentVertices()[m].getWeight();
if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
{
//WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
cout << "It works so far" << endl;
// BOOK has this, somehow need to change it: w.path = v
}
}
}
}
////////INSERTION SORT////////////
template <typename Comparable>
void insertionSort( vector<Comparable> & a )
{
for( int p = 1; p < a.size( ); ++p )
{
Comparable tmp = std::move( a[ p ] );
int j;
for( j = p; j > 0 && tmp < a[ j - 1 ]; --j )
a[ j ] = std::move( a[ j - 1 ] );
a[ j ] = std::move( tmp );
}
}
template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right )
{
for( int p = left + 1; p <= right; ++p )
{
Comparable tmp = std::move( a[ p ] );
int j;
for( j = p; j > left && tmp < a[ j - 1 ]; --j )
a[ j ] = std::move( a[ j - 1 ] );
a[ j ] = std::move( tmp );
}
}
Vertex.h:
#include "Edge.h"
#include <vector>
#include <climits>
#include <fstream>
using namespace std;
class Vertex
{
private:
int vertexNum; //number of the vertex for identification purposes
int degree;
bool known;
vector<Edge> adjacentVertices; //vector of vertices that are adjacent to the vertex we are currently looking at
int dv; //distance
int pv; //previous vertex
Vertex *vertex;
public:
Vertex()
{
dv = INT_MAX;
known = false;
}
void setKnown(bool Known)
{
known = Known;
}
bool getKnown()
{
return known;
}
void setVertexNum(int VertexNum)
{
vertexNum = VertexNum;
}
void setDegree(int Degree)
{
degree = Degree;
}
vector<Edge> & getAdjacentVertices()
{
return adjacentVertices;
}
int getVertexNum()
{
return vertexNum;
}
int getDegree()
{
return degree;
}
int getDV() const
{
return dv;
}
int setDV(int Dv)
{
dv = Dv;
}
void setAdjacentVertex(int AdjacentVertex, int Weight)
{
Edge newEdge;
newEdge.setWeight(Weight);
newEdge.setAdjVertex(AdjacentVertex);
adjacentVertices.push_back(newEdge);
}
friend ostream & operator <<(ostream & outstream, Vertex *vertex)
{
outstream << vertex->getVertexNum() << endl;
outstream << vertex->getDegree() << endl;
outstream << vertex->getKnown() << endl;
vector<Edge> E = vertex->getAdjacentVertices();
for(int x=0;x<E.size();x++)
{
outstream << E[x].getAdjVertex() << endl;
outstream << E[x].getWeight() << endl;
}
return outstream;
}
friend bool operator < (const Vertex & v1, const Vertex & v2);
};
Edge.h:
#include <cstdlib>
class Edge
{
private:
int adjVertex; //represents the vertex that the edge leads to
int weight;
public:
Edge()
{
adjVertex = 0;
weight = 0;
}
void setWeight(int Weight)
{
weight = Weight;
}
void setAdjVertex(int adjacent)
{
adjVertex = adjacent;
}
int getAdjVertex()
{
return adjVertex;
}
int getWeight()
{
return weight;
}
};

From g++ to English:
Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'
Explanation:
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++) <- this is 154. sortedVertices is not a pointer. It is a std::vector of some pointers.
int dist = getAdjacentVertices()[m].getWeight(); <- 156. What is getAdjacentVertices?
sortedVertices[1].getDV() <- 157 sortedVertices[1] is a pointer. Look at operator[]
sortedVertices[m+1]->getAdjacentVertices() is a vector of Edge. Edge does not have a getDV() method defined.
Is this really your code?
As an author you should not have trouble understanding the error messages. Those are simple mistakes, that took 5 minutes for a stranger to understand. You need to put more effort in understanding what you write, and what compiler tells you. Or get some sleep to get some focus.
I would also suggest to spend some time working out what std::vector really is and how to understand std::vector<Vertex*> vector_of_vertices; object.

vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0)
Here you create variable of type vector<Vertex*> on the stack. This is not a pointer. This is a container containing pointers of type Vertex* and that's completely different. You use -> operator which is only used on pointers.

Related

C++ programming problem, failed to assign pointers to correct objects

I've been working on a problem which involves an size-N square matrix maze with N^2 nodes and 2N(N-1) edges connecting vertical and horizontal neighbours. The codes are as follows:
//Node.h
#pragma once
#define NULL 0
using namespace std;
class Edge;
class Node {
public:
int id, row, col;
Edge* EL, * ER, * EU, * ED;
vector<int> connected;
Node(int id, int row, int col);
Node* get_L();
Node* get_R();
Node* get_U();
Node* get_D();
void print();
};
//Edge.h
#pragma once
#include "Node.h"
class Edge {
public:
int id, type;
bool state;
Node* N1, * N2;
Edge(int id, Node n1, Node n2, int type);
void setState(bool b);
void print();
};
//Maze.h
#pragma once
#include <vector>
#include "Node.h"
#include "Edge.h"
using namespace std;
class Maze {
public:
int size;
vector<Node> nodes;
vector<Edge> edges;
Maze(int N);
void print();
};
//main.cpp
#include <iostream>
#include <vector>
#include "Node.h"
#include "Edge.h"
#include "Maze.h"
Node::Node(int id, int row, int col) {
this->id = id;
this->row = row;
this->col = col;
this->EL = NULL;
this->ER = NULL;
this->EU = NULL;
this->ED = NULL;
}
Node* Node::get_L() {
if (EL) {
return EL->N1;
}
else {
cerr << "Node " << id << "does not have left neighbour.";
}
}
Node* Node::get_R() {
if (ER) {
return ER->N2;
}
else {
cerr << "Node " << id << "does not have right neighbour.";
}
}
Node* Node::get_U() {
if (EU) {
return EU->N1;
}
else {
cerr << "Node " << id << "does not have up neighbour.";
}
}
Node* Node::get_D() {
if (ED) {
return ED->N2;
}
else {
cerr << "Node " << id << "does not have down neighbour.";
}
}
void Node::print() {
int l, r, u, d;
l = EL ? EL->N1->id : -1;
r = ER ? ER->N2->id : -1;
u = EU ? EU->N1->id : -1;
d = ED ? ED->N2->id : -1;
cout << "Node " << id << " (Row " << row << " Col " << col << "), neighbours <L,R,U,D>: <" << l << "," << r << "," << u << "," << d << ">" << endl;
}
Edge::Edge(int id, Node n1, Node n2, int type) {
this->id = id;
this->N1 = &n1;
this->N2 = &n2;
this->state = false;
this->type = type;
}
void Edge::print() {
if (type == 0) {
cout << "Horizontal ";
}
else {
cout << "Vertical ";
}
cout << "edge " << id << " between <" << N1->id << ", " << N2->id << ">, " << state << endl;
}
void Edge::setState(bool b) {
this->state = b;
}
Maze::Maze(int N) {
size = N;
for (int i = 0; i < N * N; ++i) {
Node n = Node(i, i / N, i % N);
nodes.push_back(n);
}
int eid = 0;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N - 1; ++j) {
Node n1 = nodes[i * N + j];
Node n2 = nodes[i * N + j + 1];
Edge e = Edge(eid, n1, n2, 0);
/*
// &n1 and &n2 retain the same throughout the loop
cout << &n1 << endl;
cout << &n2 << endl;
cout << e.N1->id << "," << e.N2->id << endl; // This line gives correct result
e.print(); // Incorrect
*/
n1.ER = &e;
n2.EL = &e;
edges.push_back(e);
eid++;
}
}
cout << nodes[0].ER << endl;
for (int i = 0; i < N - 1; ++i) {
for (int j = 0; j < N; ++j) {
Node n1 = nodes[i * N + j];
Node n2 = nodes[i * N + j + 1];
Edge e = Edge(eid, n1, n2, 1);
n1.ED = &e;
n2.EU = &e;
edges.push_back(e);
eid++;
}
}
}
void Maze::print() {
cout << size << " x " << size << " Maze" << endl;
cout << nodes.size() << " nodes:" << endl;
for (auto& i : nodes) {
i.print();
}
cout << edges.size() << " edges:" << endl;
for (auto& i : edges) {
i.print();
}
}
int main()
{
Maze m = Maze(8);
m.print();
}
However after compiling and running I found out that the nodes and edges are NOT connected to each other as I expected. In the codes of creating edges I tried to figure out the reason (see the commented part), I found that in the entire loop, the addresses of n1 and n2 always retain the same. Still have no idea why this is happening. Please help.

C++ Hamming Function

This program is supposed to create three arrays of class object My_array. The first array is filled with random numbers. The second array is an exact copy of the first. The third array is entered by the user. The program checks to make sure that the first two arrays indeed equal each other and then it check to the hamming distance of the first and third array. The professor defines the hamming distance as each part off the array that is different.
My problem has been getting hamming to work. I actually have a hard time with operating overloading so I am surprised that works (well I have no errors showing in VS Studio) but not the hamming part. Any help would be appreciated. There are three files in order: main.cpp, my_array.cpp, and my_array.h. Function definitions and declarations were provided by professor. I am required to insert how each function operates.
#include "my_array.h"
#include <iostream>
using namespace std;
int main()
{
int size;
cout << "How big of an array shall we work with? ";
cin >> size;
My_array a(size);
My_array b(size);
My_array c(size);
a.randomize(100);
b = a;
c.input();
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << "a != b: " << (a != b) << endl;
cout << "a == b: " << (a == b) << endl;
cout << "The hamming distance is: " << a.hamming(c);
return 0;
}
#include "my_array.h"
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <time.h>
// Constructor
My_array::My_array(int the_size)
{
array = NULL;
size = 0;
resize(the_size);
}
// Destructor.
My_array::~My_array()
{
empty();
}
// Copy constructor
My_array::My_array(My_array &data)
: size(data.size)
{
array = new int[size];
for (int i = 0; i<size; i++)
array[i] = data.array[i];
}
// Overloaded assignment operator.
My_array &My_array::operator=(My_array &data)
{
if (this != &data) {
resize(data.size);
for (int i = 0; i<size; i++)
array[i] = data.array[i];
}
else
cout << "Attempt to copy an object on itself. "
<< "Operation ignored." << endl;
return *this;
}
void My_array::input()
{
int j;
cout << "Please enter " << size << " numbers.\n";
for (int i = 0; i < size; i++)
{
cout << "Number " << i + 1 << ": ";
cin >> j;
array[i] = j;
}
}
void My_array::randomize(int limit)
{
srand(time(NULL));
for (int i = 0; i < size; i++)
array[i] = rand() % limit + 1;
}
bool My_array::operator ==(My_array &data)
{
if(this->size != data.size)
return false;
for (int i = 0; i <size; i++)
{
if (*this[i].array != data.array[i])
return false;
}
return true;
}
bool My_array::operator !=(My_array &data)
{
if (*this == data)
return false;
return true;
}
int My_array::hamming(My_array &data)
{
int ham = 0;
for (int i = 0; i < size; i++)
if (*this[i].array != data[i].array)
ham++;
return ham;
}
// This function will empty the target object
void My_array::empty()
{
if (size != 0 && array != NULL) {
size = 0;
delete[] array;
}
}
// Resize the array.
void My_array::resize(int the_size)
{
if (size >= 0) {
empty();
if (the_size != 0) {
size = the_size;
array = new int[size];
}
}
else
cout << "Resize attepmted with a negative size. "
<< "Operation ignored." << endl;
}
// Access an element of the array.
int &My_array::operator[](int index)
{
if (index < size)
return array[index];
else {
cerr << "Illegal access to an element of the array." << endl
<< "The size of the array was " << size
<< " and the index was " << index << endl;
exit(1);
}
}
// Accessor
int My_array::get_size()
{
return size;
}
void My_array::output()
{
cout << "The array of size " << size
<< " contains the elements:" << endl;
for (int i = 0; i<size; i++)
cout << array[i] << ' ';
cout << endl;
}
//overloading the << operator.
ostream &operator<<(ostream &out, My_array &data)
{
out << "The array of size " << data.size
<< " contains the elements:" << endl;
for (int i = 0; i<data.size; i++)
out << data.array[i] << ' ';
out << endl;
return out;
}
#ifndef MY_ARRAY_H
#define MY_ARRAY_H
#include <iostream>
using namespace std;
class My_array {
protected:
int size;
int *array;
public:
// Constructor
My_array(int the_size = 0);
// Destructor
~My_array();
// Copy constructor
My_array(My_array &data);
// Assignment operator
My_array &operator=(My_array &data);
void input();
void randomize(int limit);
bool operator ==(My_array &data);
bool operator !=(My_array &data);
int hamming(My_array &data);
// Deletes the array
void empty();
// Resize the array.
void resize(int the_size = 0);
// Access an element of the array.
int &operator[](int index);
// Returns the size of the array.
int get_size();
// Output the elements of the array.
void output();
friend ostream &operator<<(ostream &out, My_array &data);
};
#endif
This:
*this[i].array != data[i].array
should be this:
array[i] != data.array[i]
or this:
array[i] != data[i]
The *this is unnecessary, and data[i] is a reference to an int (the same one you get by calling data.array[i], thanks to your operator[]), and an int has no member called "array".

Output of neural network holds same values everytime

I am working on a very simple feed forward neural network to practice my programming skills. There are 3 classes :
Neural::Net ; builds the network, feeds forward input values (no backpropagation for the moment)
Neural::Neuron ; has characteristics of the neuron (index, output, weight etc)
Neural::Connection ; a structure-like class that randomizes the weights and hold the output, delta weight etc..
The program is very basic: I build the network with 2 hidden layers and randomized weights, then ask it to feed forward the same input values.
My problem is: It is expected that the program ends up with different output values after every run, yet the output are always the same. I tried placing markers everywhere to understand why it is calculating the same thing over and over again but I can't put my finger on the error.
Here is the code:
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <vector>
#include "ConsoleColor.hpp"
using namespace std;
namespace Neural {
class Neuron;
typedef vector<Neuron> Layer;
// ******************** Class: Connection ******************** //
class Connection {
public:
Connection();
void setOutput(const double& outputVal) { myOutputVal = outputVal; }
void setWeight(const double& weight) { myDeltaWeight = myWeight - weight; myWeight = weight; }
double getOutput(void) const { return myOutputVal; }
double getWeight(void) const { return myWeight; }
private:
static double randomizeWeight(void) { return rand() / double(RAND_MAX); }
double myOutputVal;
double myWeight;
double myDeltaWeight;
};
Connection::Connection() {
myOutputVal = 0;
myWeight = Connection::randomizeWeight();
myDeltaWeight = myWeight;
cout << "Weight: " << myWeight << endl;
}
// ******************** Class: Neuron ************************ //
class Neuron {
public:
Neuron();
void setIndex(const unsigned int& index) { myIndex = index; }
void setOutput(const double& output) { myConnection.setOutput(output); }
unsigned int getIndex(void) const { return myIndex; }
double getOutput(void) const { return myConnection.getOutput(); }
void feedForward(const Layer& prevLayer);
void printOutput(void) const;
private:
inline static double transfer(const double& weightedSum);
Connection myConnection;
unsigned int myIndex;
};
Neuron::Neuron() : myIndex(0), myConnection() { }
double Neuron::transfer(const double& weightedSum) { return 1 / double((1 + exp(-weightedSum))); }
void Neuron::printOutput(void) const { cout << "Neuron " << myIndex << ':' << myConnection.getOutput() << endl; }
void Neuron::feedForward(const Layer& prevLayer) {
// Weight sum of the previous layer's output values
double weightedSum = 0;
for (unsigned int i = 0; i < prevLayer.size(); ++i) {
weightedSum += prevLayer[i].getOutput()*myConnection.getWeight();
cout << "Neuron " << i << " from prevLayer has output: " << prevLayer[i].getOutput() << endl;
cout << "Weighted sum: " << weightedSum << endl;
}
// Transfer function
myConnection.setOutput(Neuron::transfer(weightedSum));
cout << "Transfer: " << myConnection.getOutput() << endl;
}
// ******************** Class: Net *************************** //
class Net {
public:
Net(const vector<unsigned int>& topology);
void setTarget(const vector<double>& targetVals);
void feedForward(const vector<double>& inputVals);
void backPropagate(void);
void printOutput(void) const;
private:
vector<Layer> myLayers;
vector<double> myTargetVals;
};
Net::Net(const vector<unsigned int>& topology) : myTargetVals() {
assert(topology.size() > 0);
for (unsigned int i = 0; i < topology.size(); ++i) { // Creating the layers
myLayers.push_back(Layer(((i + 1) == topology.size()) ? topology[i] : topology[i] + 1)); // +1 is for bias neuron
// Setting each neurons index inside layer
for (unsigned int j = 0; j < myLayers[i].size(); ++j) {
myLayers[i][j].setIndex(j);
}
// Console log
cout << red;
if (i == 0) {
cout << "Input layer (" << myLayers[i].size() << " neurons including bias neuron) created." << endl;
myLayers[i].back().setOutput(1);
}
else if (i < topology.size() - 1) {
cout << "Hidden layer " << i << " (" << myLayers[i].size() << " neurons including bias neuron) created." << endl;
myLayers[i].back().setOutput(1);
}
else { cout << "Output layer (" << myLayers[i].size() << " neurons) created." << endl; }
cout << white;
}
}
void Net::setTarget(const vector<double>& targetVals) { assert(targetVals.size() == myLayers.back().size()); myTargetVals = targetVals; }
void Net::feedForward(const vector<double>& inputVals) {
assert(myLayers[0].size() - 1 == inputVals.size());
for (unsigned int i = 0; i < inputVals.size(); ++i) { // Setting input vals to input layer
cout << yellow << "Setting input vals...";
myLayers[0][i].setOutput(inputVals[i]); // myLayers[0] is the input layer
cout << "myLayer[0][" << i << "].getOutput()==" << myLayers[0][i].getOutput() << white << endl;
}
for (unsigned int i = 1; i < myLayers.size() - 1; ++i) { // Updating hidden layers
for (unsigned int j = 0; j < myLayers[i].size() - 1; ++j) { // - 1 because bias neurons do not have input
cout << "myLayers[" << i << "].size()==" << myLayers[i].size() << endl;
cout << green << "Updating neuron " << j << " inside layer " << i << white << endl;
myLayers[i][j].feedForward(myLayers[i - 1]); // Updating the neurons output based on the neurons of the previous layer
}
}
for (unsigned int i = 0; i < myLayers.back().size(); ++i) { // Updating output layer
cout << green << "Updating output neuron " << i << ": " << white << endl;
const Layer& prevLayer = myLayers[myLayers.size() - 2];
myLayers.back()[i].feedForward(prevLayer); // Updating the neurons output based on the neurons of the previous layer
}
}
void Net::printOutput(void) const {
for (unsigned int i = 0; i < myLayers.back().size(); ++i) {
cout << blue; myLayers.back()[i].printOutput(); cout << white;
}
}
void Net::backPropagate(void) {
}
}
int main(int argc, char* argv[]) {
vector<unsigned int> myTopology;
myTopology.push_back(3);
myTopology.push_back(4);
myTopology.push_back(2);
myTopology.push_back(2);
cout << myTopology.size() << endl << endl; // myTopology == {3, 4, 2 ,1}
vector<double> myTargetVals= {0.5,1};
vector<double> myInputVals= {1, 0.5, 1};
Neural::Net myNet(myTopology);
myNet.feedForward(myInputVals);
myNet.printOutput();
return 0;
}
Edit: I figured that the bias neuron in the input layer was correctly set to output 1 while the ones in the hidden layers are set to 0 and I fixed that. But the outputs are still the same every run. I did the math on a sheet of paper and it works out. Here is the output (Color coded for clarity) :
I have expected the values to be random just like the weights. Shouldn't that be the case ? I am confused.
I found my mistake. I thought that rand() initialized its seed automatically. I knew it was a dumb thing. I added srand(time(NULL)); at the beginning of the program and now it works as it should.

Can't resolve Segmentation Fault core dump error

I am writing a program that implements Dijkstra algorithm for graphs and I ran into this:
Segmentation fault (core dump). I have narrowed down the line (I have marked the line where the error is occurring) that is causing me the error, and then I used both GDB and Valgrind on my program, but all those told me was what line the error was occurring on, something I already new. Any help that y'all can give would me awesome! Thanks in advance!
////HERE'S MY MAIN/////
#include "Vertex.h"
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
void Dijkstra(vector<Vertex> & V);
///overload the less than operator in order to use the stl sort for vector
///print out the path for each vertex
int main()
{
/////READ ALL THE STUFF INTO THE GRAPH////
ifstream file;
file.open("graph.txt");
cout << "Opening file..." << endl;
if(!file)
{
cout << "System failed to open file.";
}
else
{
cout << "File successfully opened" << endl;
}
int numVertices;
int numEdges;
int adjacentVertex;
int weight;
file >> numVertices;
cout << "The number of vertices that are being read into the graph from the file: " << numVertices;
cout << endl;
vector<Vertex*> vertices;
//vector<Vertex> vertices(numVertices + 1);
for(int i=1;i<=numVertices;i++)
{
file >> numEdges;
cout << "At vertex " << i << " the number of edges is " << numEdges << endl;
cout << "Hello" << endl;
vertices[i] = new Vertex(); ////THIS IS WHERE THE ERROR IS
cout << "World" << endl;
//Vertex newVertex;
//Using the i counter variable in the outer for loop to identify
//the what vertex what are currently looking at in order to read in the correct adjacent vertex and weight
vertices[i] -> setVertexNum(i);
//newVertex.setVertexNum(i);
for(int j=1;j<=numEdges;j++)
{
file >> adjacentVertex;
cout << "The adjacent vertex is: " << adjacentVertex << endl;
file >> weight;
cout << "The weight is: " << weight << endl;
cout << endl;
vertices[i]->setAdjacentVertex(adjacentVertex, weight);
}
vertices.push_back(vertices[i]);
}
file.close();
/*
for(int i=0;i<vertices.size();i++)
{
cout << "V" << i <<": ";
cout << endl;
for(int j=0;j<vertices[i].getAdjacentVertices().size();j++)
{
cout << "V" << vertices[i].getAdjacentVertices()[j].getAdjVertex() << " " << vertices[i].getAdjacentVertices()[j].getWeight() << endl;
}
}
*/
//CALL THE SHORTEST PATH FUNCTION ON THE GRAPH/////
}
////HERE'S MY VERTEX CLASS/////
#include "Edge.h"
#include <vector>
#include <climits>
#include <fstream>
using namespace std;
class Vertex
{
private:
int vertexNum; //number of the vertex for identification purposes
int degree;
bool known;
vector<Edge> adjacentVertices; //vector of vertices that are adjacent to the vertex we are currently looking at
int dv; //distance
int pv; //previous vertex
Vertex *vertex;
public:
Vertex()
{
dv = INT_MAX;
known = false;
}
void setKnown(bool Known)
{
known = Known;
}
bool getKnown()
{
return known;
}
void setVertexNum(int VertexNum)
{
vertexNum = VertexNum;
}
void setDegree(int Degree)
{
degree = Degree;
}
vector<Edge> & getAdjacentVertices()
{
return adjacentVertices;
}
int getVertexNum()
{
return vertexNum;
}
int getDegree()
{
return degree;
}
int getDV() const
{
return dv;
}
void setAdjacentVertex(int AdjacentVertex, int Weight)
{
Edge newEdge;
newEdge.setWeight(Weight);
newEdge.setAdjVertex(AdjacentVertex);
adjacentVertices.push_back(newEdge);
}
friend ostream & operator <<(ostream & outstream, Vertex & vertex)
{
outstream << vertex.vertexNum << endl;
outstream << vertex.degree << endl;
outstream << vertex.known << endl;
vector<Edge> E = vertex.getAdjacentVertices();
for(int x=0;x<E.size();x++)
{
outstream << E[x].getAdjVertex() << endl;
outstream << E[x].getWeight() << endl;
}
return outstream;
}
friend bool operator < (const Vertex & v1, const Vertex & v2);
void printVertex()
{
}
};
When initializing elements of a vector, you should use the push_back method.
So change:
vertices[i] = new Vertex();
to:
vertices.push_back( new Vertex() );
Of course, there are still other problems in your code. One hint I can give you is to iterate your for loops starting with 0 and using < instead of <= in the predicate.
So you must replace the line
vector <Vertex*> vertices;
By
vector<Vertex*> vertices(numVertices);

C++: transfer a vector into a subprogram

In my example there are three similar vectors which I would like to print.
Could you help me understand how to transfer a vector into a subprogram so that not to
repeat myself?
#include "stdafx.h";
#include <vector>;
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
struct SPoint
{
int X;
int Y;
};
vector<SPoint> points;
vector<SPoint> selected;
vector<SPoint> cleared;
void print_points()
{
cout << "Points: "<< endl;
for (int i = 0; i < points.size(); i++)
{
cout << '('<<points[i].X <<',' <<points[i].Y <<')'<< endl;
}
cout << endl;
}
void print_selected()
{
cout << "Selected: "<< endl;
for (int i = 0; i < selected.size(); i++)
{
cout << '('<<selected[i].X <<',' <<selected[i].Y <<')'<< endl;
}
cout << endl;
}
void print_cleared()
{
cout << "Cleared: "<< endl;
for (int i = 0; i < cleared.size(); i++)
{
cout << '('<<cleared[i].X <<',' <<cleared[i].Y <<')'<< endl;
}
cout << endl;
}
int main ()
{
SPoint temp = {0, 0};
for (int i = 0; i < 11;i++)
{
temp.X = i;
temp.Y = i;
points.push_back(temp);
}
for (int i = 5; i< 11;i++)
{
temp.X = i;
temp.Y = i;
points.push_back(temp);
}
print_points();
print_selected();
print_cleared();
system ("pause");
return 0;
}
You could do something like this:
void
print(const std::vector<SPoint>& vect, const std::string& message)
{
std::cout << message << ":" << std::endl;
for (int i = 0, size = vect.size(); i < size; ++i)
std::cout << vect[i].X << ":" << vector[i].Y << " ";
std::endl;
}
print(points, "Points");
print(points, "Selected");
print(points, "Cleared");
Good luck
To pass a vector as an argument to a function you do something like this:
void func(const vector<SPoint>& points) {
... do stuff
}
Then you call the function in you code like this:
...some stuff
vector<SPoint> a;
func(a);
Just use a const reference to a vector and pass it to the function:
void print(const vector<SPoint> &data) const {
}
...
print(points);
Here is a full C++ style approach:
struct SPoint
{
int X;
int Y;
};
std::ostream& operator <<( std::ostream& stream, SPoint const& point )
{
stream << '(' << point.X << ',' <<point.Y << ')';
return stream;
}
void print_vector( std::ostream& stream, std::vector< SPoint > const& vector )
{
std::copy(
points.begin(), points.end()
, std::ostream_iterator< SPoint >( std::cout, '\n' )
);
}
and then:
print_vector( std::cout, points );
print_vector( std::cout, selected );
print_vector( std::cout, cleared );