cellular automaton in c++ with class and object - c++

I did my cellular automaton in c but now I want to convert it to c++ with using class and object. I am new in c++ that is why I need your help. My program crashes after typing decimal number. I think data is not transfered properly between the functions, but I send few hours on it and I cannot get it. I would be pleased if I could get any advice with finding when my error is. I've got 3 files. One is my main, one is file with functions, and the last one is a header.
Main:
#include <iostream>
#include "cellular.h"
using namespace std;
int main()
{
CA myCA;
myCA.run();
return 0;
}
File with functions:
#include "cellular.h"
#include <cstdio>
CA::CA()
{
int WIDTH = 59;
int numOfRules = 8;
currentState = new int [WIDTH];
nextState = new int[WIDTH];
storeTheRules = new int[numOfRules];
}
CA::~CA()
{
delete [] currentState;
delete [] nextState;
delete [] storeTheRules;
}
void CA::run()
{
int x;
int t;
//enter which cellular you want to print out
printf("Enter the number of cellular you want to print out 0-255 (-1 to end):\n");
scanf("%d", &number);
while(number != -1) {
if(number >= 0 && number <= 255) {
for(x = 0; x < WIDTH; x++) {
currentState[x] = 0;
}
for(x = 0; x < WIDTH; x++) {
t = (int)WIDTH/2;
currentState[t] = 1;
}
// convert decimal number to binary
decimalToBinary(number);
// print binary number
printf("In binary:");
for(x = 0; x < numOfRules; x++)
{
printf("%d", storeTheRules[x]);
}
printf("\n");
//print current state
printCellular();
printf("\n");
// calculate for next generation
calcNextGeneration();
// update array
updateArray();
}
else {
printf("\nWrong number entered! Try again\n");
}
//enter which cellular you want to print out
printf("\nEnter the number of cellular you want to print out 0-255 (-1 to end):\n");
scanf("%d", &number);
}
}
void CA::calcNextGeneration()
{
int i;
int j;
int LENGHT = 27;
for(j = 0; j < LENGHT; j++) {
for (i = 0; i < WIDTH; i++) {
left = currentState[i-1];
middle = currentState[i];
right = currentState[i+1];
nextState[i] = rules(left, middle, right);
}
updateArray();
printCellular();
printf("\n");
}
}
int CA::rules(int left,int middle, int right)
{
if(left == 1 && middle == 1 && right == 1)
return storeTheRules[0];
else if(left == 1 && middle == 1 && right == 0)
return storeTheRules[1];
else if(left == 1 && middle == 0 && right == 1)
return storeTheRules[2];
else if(left == 1 && middle == 0 && right == 0)
return storeTheRules[3];
else if(left == 0 && middle == 1 && right == 1)
return storeTheRules[4];
else if(left == 0 && middle == 1 && right == 0)
return storeTheRules[5];
else if(left == 0 && middle == 0 && right == 1)
return storeTheRules[6];
else if(left == 0 && middle == 0 && right == 0)
return storeTheRules[7];
return 0;
}
void CA::printCellular()
{
int i;
for(i = 0; i < WIDTH; i++) {
if(nextState[i] == 1 || currentState[i] == 1)
printf("#");
else
printf(" ");
}
}
void CA::updateArray()
{
int i;
for(i = 0; i < WIDTH; i++) {
currentState[i] = nextState[i];
}
}
// function to convert decimal number to binary
void CA::decimalToBinary(int n)
{
int k;
int i = 0;
for (numOfRules = 7; numOfRules >= 0; numOfRules--) {
k = n >> numOfRules;
if (k & 1)
storeTheRules[i] = 1;
else
storeTheRules[i] = 0;
i++;
}
printf("\n");
}
Header:
#ifndef CELLULAR_H_INCLUDED
#define CELLULAR_H_INCLUDED
// A cellular automaton class
class CA {
private:
int WIDTH;
int numOfRules;
int *currentState;
int *nextState;
int *storeTheRules;
int number;
int left, middle, right;
public:
// Constructor
CA();
// Destructor
~CA();
// Functions
void run();
int rules(int left, int middle, int right);
void calcNextGeneration();
void printCellular();
void updateArray();
void decimalToBinary(int n);
};
#endif // CELLULAR_H_INCLUDED
I am making my code in CodeBlocks. And.. include cstdio is because I didn't changed my printf's from C code yet.
Thank you for any help.
Regards,
Nel

I didn't read through everything, but a few issues upon first glance:
In your constructor you are creating local variables instead of accessing the class variables you intend to modify.
int WIDTH = 59;
int numOfRules = 8;
Also, just as a personal preference, I wouldn't organize this in such a way that a data entry loop getting input from the user is a part of a class. That could just be personal preference though.

Related

Bool function as class member conditions don't return a value

#include <iostream>
#include <vector>
using namespace std;
enum type{
noboard,
peg,
empty
};
class board{
public:
//create getter
vector<vector<int>>getVector() const;
//create setter
bool control_vect();
board(vector<vector<int>> pvect);
//display() function that prints elements of the vect data member
void display()
{
for(const vector<int> &elem: vect)
{
for(int intElem: elem)
{
if(intElem==1){
cout<<'P';
}
else if(intElem==0){
cout<<' ';
}
else if(intElem==2){
cout<<'.';
}
}
cout<<endl;
}
}
private:
vector<vector<int>> vect;
};
vector<vector<int>> board :: getVector() const
{
return vect;
}
board :: board(vector<vector<int>> pvect)
{
vect = pvect;
}
bool board :: control_vect(){
long unsigned int i,j;
bool controller=false;
cout<<vect[0][0];
for (i = 0; i < vect.size(); i++){
for ( j = 0; j < vect[i].size()-2; j++){
if(vect[i][j]==1 && vect[i][j+1]==1 && vect[i][j+2]==0){
controller=true;
break;
}
}
}
return controller;
}
int main()
{
//create a board instance
// board myBoard;
vector<vector<int>> pvect{
{peg,peg,peg,peg,peg},
{noboard,peg,peg,empty,peg},
{peg,peg,peg,peg,peg},
};
//cout<<pvect[0][5];
//use the setter to set the vect data member
board a(pvect);
a.display();
if(a.control_vect()==true){
cout<<"a";
}
else{
cout<<"b";
}
//lets print out the elements of the data member vect for the object myBoard using the display() member function
// myBoard.display();
return 0;
}
I write upside code and it run.Then I trying more complex conditions in control_vect function,The function does not give a return value.But upside least complex control_funcion return a bool value and it print vect[0][0] element.But downside do not print bool or vect[0][0].Why underside function do not return a bool value?Although similar.Also I am trying for loop and print all vector two's run.Example output:İf conditions supply print a,do not supply print b by program.
bool board :: control_vect(){
long unsigned int i,j;
for (i = 0; i < vect.size(); i++){
for ( j = 0; j < vect[i].size(); j++){ //Look for legal moves on the board.If there are legal moves program will continue.
if(vect[i][j]==1 && vect[i][j+1]==1 && vect[i][j+2]==2){
controller=true;
break;
}
else if(vect[i][j]==2 && vect[i][j+1]==1 && vect[i][j+2]==1){
controller=true;
break;
}
else if(vect[i][j] == 1 && vect[i+1][j] == 1 && vect[i+2][j] == 2){
controller=true;
break;
}
else if (vect[i][j] == 2 && vect[i+1][j] == 1 && vect[i+2][j] == 1){
controller=true;
break;
}
}
}
return controller;
}
There are some mistakes that i have spotted in your given code snippet.
Mistake 1
You are using using namespace std so this will result in an error saying
error: reference to 'empty' is ambiguous
86 | {noboard,peg,peg,empty,peg}
as can be seen here.
Solution to Mistake 1
You can solve this by replacing {noboard,peg,peg,empty,peg} with:
{noboard,peg,peg,type::empty,peg} //note the type:: i have added
Now your program works as can be seen here.
Mistake 2
The 2nd code snippet that you have given does not define a controller variable inside the bool board :: control_vect() and it also does not have a cout<<vect[0][0];
Solution to Mistake 2
You can solve these by just adding the following statements inside control_vect()'s body:
bool controller = false;
cout << vect[0][0];
So the correct modified code would look like:
bool board :: control_vect(){
long unsigned int i,j;
bool controller = false; //note I HAVE ADDED THIS
cout << vect[0][0]; //note I HAVE ADDED THIS
for (i = 0; i < vect.size(); i++){
for ( j = 0; j < vect[i].size(); j++){ //Look for legal moves on the board.If there are legal moves program will continue.
if(vect[i][j]==1 && vect[i][j+1]==1 && vect[i][j+2]==2){
controller=true;
break;
}
else if(vect[i][j]==2 && vect[i][j+1]==1 && vect[i][j+2]==1){
controller=true;
break;
}
else if(vect[i][j] == 1 && vect[i+1][j] == 1 && vect[i+2][j] == 2){
controller=true;
break;
}
else if (vect[i][j] == 2 && vect[i+1][j] == 1 && vect[i+2][j] == 1){
controller=true;
break;
}
}
}
return controller;
}
Mistake 3
You were trying to access vect[i][j+2] and vect[i+2][j] but you forgot to subtract 2 from loop variable values which resulted in Segmentation fault as can be seen here.
for (i = 0; i < vect.size(); i++){//you forgot to subtract 2
for ( j = 0; j < vect[i].size(); j++){//you forgot to subtract 2
Solution to Mistake 3 You can solve this by subtracting 2 from the loop variables i and j as follows:
for (i = 0; i < vect.size() -2; i++){ //note i have subtracted 2
for ( j = 0; j < vect[i].size()-2; j++){//note i have subtracted 2
So the final correct modified code would look like:
bool board :: control_vect(){
long unsigned int i,j;
bool controller = false;
cout << vect[0][0];
for (i = 0; i < vect.size() -2; i++){// note I HAVE SUBTRACTED 2
for ( j = 0; j < vect[i].size()-2; j++){ //note I HAVE SUBTRACTED 2 //Look for legal moves on the board.If there are legal moves program will continue.
if(vect[i][j]==1 && vect[i][j+1]==1 && vect[i][j+2]==2){
controller=true;
break;
}
else if(vect[i][j]==2 && vect[i][j+1]==1 && vect[i][j+2]==1){
controller=true;
break;
}
else if(vect[i][j] == 1 && vect[i+1][j] == 1 && vect[i+2][j] == 2){
controller=true;
break;
}
else if (vect[i][j] == 2 && vect[i+1][j] == 1 && vect[i+2][j] == 1){
controller=true;
break;
}
}
}
return controller;
}
Now your 2nd code snippet for control_vect() works and prints bool and vect[0][0] as you want and can be seen here. The complete working program can also be seen here.

Backtracking function - Show only the words that starts and ends with the letter a

I am currently a high school student and a beginner at programming on C++ and LUA.
I am trying to make a program using CodeBlocks, and I just made this code on C++:
#include <cstring>
using namespace std;
int st[20],n,ok,x,p;
char v[8] = "abcdefg",voc[] = "aeiouAEIOU",lit[] = "a";
// (n - 1)! n=9
void afisare(int k){
int i;
for (i=1;i<=k;i++)
cout<<v[st[i]]<<" ";
cout<<endl;
}
void valid(int k,int&ok){
int i;
ok = 0;
//cout<<v[st[k]];
if (strchr(lit,v[st[1]]) != NULL && strchr(lit,v[st[k]]) != NULL)
ok = 1;
for (i = 1; i <= k-1; i++)
if (st[k] == st[i])
ok = 0;
}
void back(){
int k;
k = 1;
x = 0;
st[k] = -1;
while(k > 0){
ok = 0;
while (ok==0 && st[k]<n - 1){
st[k] = st[k] + 1;
valid(k,ok);
}
if (ok == 1)
if (k == n){ //
afisare(k);
x++;
}
else {
k++;
st[k] = -1;}
else
k--;
}
}
int main()
{
//cin>>p;
n = strlen(v);
//while (p > n)
//cin>>p;
back();
cout<<endl<<"x! = "<<x;
return 0;
}
However it only shows:
x! = 0
Does anyone know the solution for this program? I am currently beginner at backtracking by the way.

Cellular automaton in C++

I'm trying to write a code of the famous game of life in C++. Here is what I've got so far. when I run it, it gives an initial random population of cells, but the next generations don't seem to work. What is wrong with my code?
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int main(){
//Number of rows and columns
const char live = '*';
const char dead = ' ';
const int rows = 10;
const int cols = 10;
char life[rows][cols];
char life1[rows][cols];
int ans=0;
//create initial generation randomly
srand (time(NULL));
int cell;
for(int r=0; r<rows; r++){
for(int c=0; c<cols; c++){
cell= rand()%10;
if(cell >= 5){
life[r][c] = live;
}
else {
life[r][c] = dead;
}
}
}
for(int r=0; r < rows; r++){
for(int c = 0; c<cols;c++){
cout << life[r][c] << " ";
}
cout << endl;
}
for(int k=0; k <10;k++){
for(int r=0; r < rows; r++){
for(int c=0;c<cols;c++){
if(life[r][c] == live){
if((c-1) >=1 && (life[r][c-1] == live))
ans++;
if(c<cols && (life[r][c+1] == live))
ans++;
if(c<cols && r<rows && (life[r+1][c+1] == live))
ans++;
if(r<rows && (life[r+1][c] == live))
ans++;
if(c<cols && c >=0 && (life[r+1][c-1] == live))
ans++;
if(r>=0 && c >=0 && (life[r-1][c-1] == live))
ans++;
if(r>=0 && (life[r-1][c]==live))
ans++;
if(r>=0 && c<cols && (life[r-1][c+1] == live))
ans++;
if(ans==2 || ans==3)
life[r][c]= live;
if(ans>3)
life[r][c]= dead;
if(ans<2)
life[r][c]=live;
}
else {
if( life[r][c]==dead){
if(c>=0 && (life[r][c-1]==dead))
ans++;
if(c<cols && (life[r][c+1]==dead))
ans++;
if(r<rows && c<cols && (life[r+1][c+1]==dead))
ans++;
if(r<rows && (life[r][c]==life[r+1][c]))
ans++;
if(r<rows && c>0 && (life[r][c]==life[r+1][c-1]))
ans++;
if(r>=0 && c>=0 && (life[r][c]==life[r-1][c-1]))
ans++;
if(r>=0 &&(life[r][c]==life[r-1][c]))
ans++;
if(r>=0 && c<cols && (life[r][c] == life[r-1][c+1]))
ans++;
if(ans==3)
life[r][c]=live;
}
}
}
}
for(int r=0; r<rows; r++){
for(int c=0; c< cols; c++){
life[r][c]=life1[r][c];
}
}
for(int r=0; r<rows;r++){
for(int c =0; c<cols;c++){
cout << life[r][c] << " ";
}
cout<<endl;
}
}
return 0;
}
Lets start with the minimal changes that are required to make your code work.
Reset ans every iteration: At the beginning of the inner loop (over cols), set ans = 0; otherwise you count above 3, never return and everything stays dead
Keep your generation: The next generation is computed from the life array, so don't change this array while computing a generation. Instead write the results to life1. At the end of each outer (k) iteration, the results will be copied back to life.
Apply the rules correctly: at the end of if (life[r][c] == live) case, with fewer than 2 neighbors, the cell should die according to the rules. So assign if (ans < 2) life1[r][c] = dead; instead of live.
With usage of life1, complete the assignment: For the other case (if (life[r][c] == dead)) add an else to make sure complete initialization: if(ans==3) life1[r][c] = live; else life1[r][c] = dead.
Use whole array size (starting at index 0): if ((c - 1) >= 1 && (life[r][c - 1] == live)) ommits the first index. Replace with if (c >= 1 && (life[r][c - 1] == live))
Stay within array bounds (ending at size-1). if(c < cols && (life[r][c + 1] == live)) is going out of bounds, replace with if((c + 1) < cols && (life[r][c + 1] == live)) to stay within bounds.
Be careful with the array bounds on all other if statements in the same way as described for the two examples.
Now moving on to the code design: I'd suggest you create a function int count_living_neighbors(char life[10][10], int rowPos, int colPos) where you place all the logic to count living neighbor cells. Then replace the huge if cascades in your main:
for(int k = 0; k < 10; k++)
{
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
int count = count_living_neighbors(life, r, c);
if(life[r][c] == live)
{
if(count == 2 || count == 3)
life1[r][c] = live;
else
life1[r][c] = dead;
}
else
{
if(count == 3)
life1[r][c]=live;
else
life1[r][c]= dead;
}
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
life[r][c] = life1[r][c];
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
cout << life[r][c] << " ";
}
cout << endl;
}
}
A note regarding count_living_neighbors: Actually it would be better to take a char* life and additionally the row and column size as parameters. But it makes array arithmetic a bit less obvious.
Edit:
Moving the constant values into global scope, the count_living_neighbors function could look like this:
const char live = '*';
const char dead = ' ';
const int rows = 10;
const int cols = 10;
int count_living_neighbors(char life[rows][cols], int r, int c)
{
int count = 0;
bool top = r <= 0;
bool bottom = r >= (rows - 1);
bool left = c <= 0;
bool right = c >= (cols - 1);
if (!left && life[r][c - 1] == live)
++count;
if (!right && life[r][c + 1] == live)
++count;
if (!top)
{
if (life[r - 1][c] == live)
++count;
if (!left && life[r - 1][c - 1] == live)
++count;
if (!right && life[r - 1][c + 1] == live)
++count;
}
if (!bottom)
{
if (life[r + 1][c] == live)
++count;
if (!left && life[r + 1][c - 1] == live)
++count;
if (!right && life[r + 1][c + 1] == live)
++count;
}
return count;
}
The actual answer is already given by grek40, but I figured that it might not hurt to give you some advice on coding style. This answer is based on the code of grek40.
First of all, if you work over some structure of data, this is a clear sign that you want a class. I will also get rid of the arrays (you want to avoid those in C++) and make the state of a cell more readable by using enum.
Let's begin with an interface, situated in a header file.
#include <vector>
using std::vector;
enum CellState{ //replacing your char* with CellState
dead, alive
};
class GameOfLife{
public:
GameOfLife(const unsigned int rows, const unsigned int cols);
virtual ~GameOfLife(){}; //can omit the virtual if no subclasses are guaranteed
void iterate(const unsigned int iterations = 1); //can do several steps at once, one step at a time is the assumed default
void print() const;
private:
vector<vector<CellState> > state;
void initialize(const unsigned int rows, const unsigned int cols); //does the randomization
unsigned int neighbors(const unsigned int row, const unsigned int col) const;
}
This class makes your main function look very easy to read:
#include "GameOfLife.h"
int main(){
GameOfLife game(10,10);
game.print(); //print initial configuration
game.iterate(); //or iterate(10) or how many steps you want
game.print(); //print configuration at the end
return 0;
}
Let's continue with the implementations of the class, situated in GameOfLife.cpp. I will omit the necessary includes like iostream for now.
Let's begin with the easy one, print:
inline char state_to_char(const CellState state){
if(state == dead){
return ' ';
}
return '*';
}
void GameOfLife::print() const{
for(unsigned int r = 0; r < state.size(); r++){
for(unsigned int c = 0; c < state[r].size(); c++){
cout << state_to_char(state[r][c]) << " ";
}
cout << endl;
}
}
Now for initialize:
void GameOfLife::initialize(const unsigned int rows, const unsigned int cols){
state.resize(rows);
for(unsigned int r = 0, r < rows, r++){
state[r].resize(cols);
}
insert your code of randomly assigning dead or alive with changed names
}
The constructor simply becomes
GameOfLife::GameOfLife(const unsigned int rows, const unsigned int cols){
initialize(rows, cols);
}
(initialize was created to make it easier to introduce new constructors later on if required)
unsigned int neighbors is to be like grek40 designed count_living_neighbors.
For the core part, iterate:
//function to resize any vector^2
template<class T>
void resize(vector<vector<T> >& target, const unsigned int dx, const unsigned int dy){
target.resize(dx);
for(unsigned int i=0; i<dx; i++){
target[i].resize(dy);
}
}
GameOfLife::iterate(const unsigned int iterations){
unsigned int rows = state.size();
unsigned int cells = 0;
if(rows != 0){
cells = state[0].size();
}
vector<vector<CellState> > new_state;
resize(new_state, rows, cells);
for(unsigned int iteration = 0; iteration < iterations; iteration++){
for(unsigned int r = 0; r < rows; r++){
for(unsigned int c = 0; c < cells; c++){
unsigned int count = neighbors(r, c);
if(state[r][c] == alive){
if(count == 2 || count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}else{
if(count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}
}
}//end for c
}//end for r
state = new_state;
}//end for iteration
}
Now, all in all, this is more code than before, but for any part of it, we know exactly what it does, can easily read it, and if there is a bug, we can easily locate the bug using a debugger.

Returning a value from a function to another function

I'm making a program where a user can move their character (the number 1) throughout an array that is printed to the screen. I ran into trouble when i tried checking to see if the next position was open in my moveRight function.
I want to return the value of the part of the array which is one space to the right of the 1. The reason I am trying to return the value of the next spot of the array is because I want to return that value to my drawBoard function so I can use that value to reprint the board making the one in that position. How would i return mB[i+1] -(the next value to the right of the 1) to my drawBoard function?
#include "stdafx.h"
#include <iostream>
#include "PlayerM.h"
using namespace std;
class Player {
public:
Player::Player(int b[]) //create a constructer to copy the values of b into mB
{
// copy b into the member array
for (int i = 0; i < 16; i++) {
mB[i] = b[i];
}
}
int moveUp();
void moveDown();
int moveRight();
void moveLeft();
private:
int mB[16];
};
int Player::moveUp() {
return 0;
}
void Player::moveDown() {
}
int Player::moveRight() {
for (int i = 0; i < 16; i++) //find the players pos on aray
{
if (mB[i] == 1 && i < 3) //if the player is eligible to move
{
mB[i] = 0;
mB[i + 1] = 1;
return mB[i + 1];
}
}
}
void Player::moveLeft() {
}
int drawBoard(int boardArray[16]) //draw the game board
{
for (int i = 0; i < 16; i++) //use a for loop to simply draw the game board (4x4)
{
cout << boardArray[i]; //ouput the storage id of the array
if (i == 3 || i == 7 || i == 11 || i == 15) //every 4 lines begin new line
{
cout << "\n";
}
}
return 0;
}
int main() {
int bArray[16] = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //create an array [16]
drawBoard(bArray); //send the aray to drawBoard ()
Player p(bArray); //send bArray to the p constructer
char m;
cin >> m;
if (m == 'W') {
p.moveRight();
}
char f;
cin >> f;
}
int Player::moveRight() {
for (int i = 0; i < 16; i++) //find the players pos on aray
{
if (mB[i] == 1 && i < 3) //if the player is eligible to move
{
mB[i] = 0;
mB[i + 1] = 1;
return mB[i + 1];
}
}
}
I think you want the following (given that the board is 4x4):
int Player::moveRight() {
for (int i = 0; i < 16; i++) //find the players pos on aray
{
if (mB[i] == 1 && (i%4) < 3) //if the player is eligible to move
{
mB[i] = 0;
mB[i + 1] = 1;
return mB[i + 1];
}
}
}
What changed: i < 3 to (i%4) < 3

Dijksta's Algorithm not finding path in Adjacency Matrix

For some reason when I run dijkstra's algorithm on my randomly generated matrix it does not find paths between all the nodes even though it's clear that it's a connected graph. I've printed out the graphs and they always follow this form
0--2--3
| | |
4--5--6
| | |
7--8--9
Right now I'm only working with a 3*3 matrix and am trying to get that to work properly. The below code makes a adjacency matrix with 9 nodes and randomly generates a number between 1 and 3 to represent the weights of edges. I use 4 for infinity.
source is hard coded to 0 and numOfVertices 9
#include<iostream>
#include <time.h>
#include <math.h>
#define INFINITY 4
#define V 9
using namespace std;
class Dijkstra{
private:
int predecessor[20],distance[20];
bool mark[20];
int source;
int destination;
int numOfVertices;
char gameMode;
public:
int adjMatrix[9][9];
void read();
void initialize();
void setSource(int k);
int getClosestUnmarkedNode();
void calculateDistance();
void output();
int randomEdge();
int randomNode();
void printPath(int);
};
void Dijkstra::read(){
numOfVertices = 4;
for(int i = 0; i < numOfVertices;i++){
for(int j = 0; j < numOfVertices;j++){
if(i == j)
adjMatrix[i][j] = 0;
else if(j >= i){
if(j == i + 1 || j == i - 1 || j == i + sqrt((double)numOfVertices)|| j == i - sqrt((double)numOfVertices))
adjMatrix[i][j] = randomEdge();
else
adjMatrix[i][j] = 4;
if((i % ((int)sqrt((double)numOfVertices)) == ((int)sqrt((double)numOfVertices)) - 1) && j == i + 1)
adjMatrix[i][j] = 4;
}
else
adjMatrix[i][j] = adjMatrix[j][i];
cout<<adjMatrix[i][j]<< " ";
}
cout<< "\n";
}
source = 0;
}
void Dijkstra::initialize(){
for(int i=0;i<numOfVertices;i++) {
mark[i] = false;
predecessor[i] = -1;
distance[i] = INFINITY;
}
distance[source]= 0;
}
int Dijkstra::getClosestUnmarkedNode(){
int minDistance = INFINITY;
int closestUnmarkedNode = 0;
for(int i=0;i<numOfVertices;i++) {
if((!mark[i]) && ( minDistance >= distance[i])) {
minDistance = distance[i];
closestUnmarkedNode = i;
}
}
return closestUnmarkedNode;
}
void Dijkstra::calculateDistance(){
initialize();
int minDistance = INFINITY;
int closestUnmarkedNode;
int count = 0;
while(count < numOfVertices) {
closestUnmarkedNode = getClosestUnmarkedNode();
mark[closestUnmarkedNode] = true;
for(int i=0;i<numOfVertices;i++) {
if((!mark[i]) && (adjMatrix[closestUnmarkedNode][i]>0) ) {
if(distance[i] > distance[closestUnmarkedNode]+adjMatrix[closestUnmarkedNode][i]) {
distance[i] = distance[closestUnmarkedNode]+adjMatrix[closestUnmarkedNode][i];
predecessor[i] = closestUnmarkedNode;
}
}
}
count++;
}
}
void Dijkstra::printPath(int node){
if(node == source)
cout<<node<<"..";
else if(predecessor[node] == -1)
cout<<"No path from "<<source<<"to "<<node<<endl;
else {
printPath(predecessor[node]);
cout<<node<<"..";
}
}
void Dijkstra::output(){
for(int i=0;i<numOfVertices;i++) {
if(i == source)
cout<<source<<".."<<source;
else
printPath(i);
cout<<"->"<<distance[i]<<endl;
}
}
int Dijkstra::randomEdge(){
return rand() % 3 + 1;
}
void Dijkstra::setSource(int k){
source = k;
}
int main(int argc, char** argv){
Dijkstra G;
G.read();
G.calculateDistance();
G.output();
int k;
cin>> k;
exit(0);
}
You are using 4 to represent infinite distance... but 4 is a distance that is easy to reach along a valid path. This code rejects any path with a total distance >=4, because every node starts out with a distance at most 4 (i.e. unreachable) from the source.