Related
Basically I wrote code to simulate one encoded data vector over a AWGN channel. The simulation but only works once. So I would like to create multiple objects or find a way to run the code multiple times depending on int N (for example int N = 1000000; in my case), so that I can calculate the BER (bit error rate).
I haven't found an elegant way to do that yet though...
I hope you understand my question.
Do you need more information?
Thank you!!
#include <iostream>
#include "encode.h"
#include "awgn.h"
#include "decode.h"
using namespace Eigen;
int main()
{
std::string code = "Hamming";
int dim_u, dim_mat_col, dim_mat_row, dim_mat_col_H, dim_mat_row_H;
MatrixXi P;
if (code == "Hamming")
{
dim_u = 4; // can also call it "k"
dim_mat_col = 7; // also serves as dim of x and y, or simply n
dim_mat_row = 4;
dim_mat_col_H = dim_mat_col;
dim_mat_row_H = dim_mat_col - dim_mat_row;
P = MatrixXi::Zero(dim_u, dim_mat_col - dim_u);
P << 1, 1, 0,
0, 1, 1,
1, 1, 1,
1, 0, 1;
}
if (code == "BCH")
{
dim_u = 7;
dim_mat_col = 15; // also serves as dim of x and y, or simply n
dim_mat_row = 7;
dim_mat_col_H = dim_mat_col;
dim_mat_row_H = dim_mat_col - dim_mat_row;
P = MatrixXi::Zero(dim_u, dim_mat_col - dim_u);
P << 1, 1, 1, 0, 1, 0, 0, 0,
0, 1, 1, 1, 0, 1, 0, 0,
0, 0, 1, 1, 1, 0, 1, 0,
0, 0, 0, 1, 1, 1, 0, 1,
1, 1, 1, 0, 0, 1, 1, 0,
0, 1, 1, 1, 0, 0, 1, 1,
1, 1, 0, 1, 0, 0, 0, 1;
}
if (code == "Golay")
{
dim_u = 12;
dim_mat_col = 24; // also serves as dim of x and y, or simply n
dim_mat_row = 12;
dim_mat_col_H = dim_mat_col;
dim_mat_row_H = dim_mat_col - dim_mat_row;
P = MatrixXi::Zero(dim_u, dim_mat_col - dim_u);
P << 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1,
0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0,
0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1,
1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0,
1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1,
1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0,
1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0,
0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1,
0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1;
}
int N = 1000000; // number of simulations
bool c_hat_minus_c = 0;
int val = 0;
Encode vec(dim_u, dim_mat_row, dim_mat_col);
awgn channel(dim_mat_col);
Decode dec(dim_mat_col, dim_mat_row_H, dim_mat_col_H, P);
vec.encodeDataVector(dim_u, dim_mat_col, P);
// std::cout << "modulated x: " << vec.x << std::endl;
channel.addGausian(vec.x);
// std::cout << channel.y << std::endl;
c_hat_minus_c = dec.decodingalg(6000, channel.y, P, vec.x); // check if codeword is received correctly
// std::cout << channel.y << std::endl;
// std::cout << "val: " << val << std::endl;
}
If I wrap the stack allocated objects in a for loop like this:
for (int i = 0; i < N; i++)
{
Encode vec(dim_u, dim_mat_row, dim_mat_col);
awgn channel(dim_mat_col);
Decode dec(dim_mat_col, dim_mat_row_H, dim_mat_col_H, P);
vec.encodeDataVector(dim_u, dim_mat_col, P);
// std::cout << "modulated x: " << vec.x << std::endl;
channel.addGausian(vec.x);
// std::cout << channel.y << std::endl;
c_hat_minus_c = dec.decodingalg(6000, channel.y, P, vec.x); // check if codeword is received correctly
// std::cout << channel.y << std::endl;
// std::cout << "val: " << val << std::endl;
}
The program breaks and says:
/usr/include/eigen3/Eigen/src/Core/CommaInitializer.h:97: Eigen::CommaInitializer& Eigen::CommaInitializer::operator,(const Eigen::DenseBase&) [with OtherDerived = Eigen::Matrix<int, -1, -1>; XprType = Eigen::Matrix<int, -1, -1>]: Assertion `(m_col + other.cols() <= m_xpr.cols()) && "Too many coefficients passed to comma initializer (operator<<)"' failed.
Edit:
so I basically found out that it braks in encode.cpp
the second time it tries to initialize the Matrix G_
#include <iostream>
#include "encode.h"
#include "awgn.h"
#include <cstdlib> // rand and srand
#include <ctime> // For the time function
using namespace std;
using namespace Eigen;
Encode::Encode(int dim_u, int dim_mat_row, int dim_mat_col) //(7,4) Hamming code only up to now
{
// if (code == "Hamming")
// dim_u = 4;
// dim_mat_col = 7;
// dim_mat_row = 4;
u_ = RowVectorXi::Zero(dim_u);
G_ = MatrixXi::Zero(dim_mat_row, dim_mat_col);
}
void Encode::encodeDataVector(int dim_u, int dim_mat_col, MatrixXi &P)
{
// Get the system time.
unsigned seed = time(0);
// Seed the random number generator.
srand(seed);
for (int i = 0; i < dim_u; i++)
{
u_(i) = rand() % 2; // only zeros and ones
}
// cout << u_ << endl << endl;
MatrixXi I;
// I = MatrixXi::Zero(7, 7);
I = MatrixXi::Identity(dim_u, dim_u);
G_ << I, P; **<----- here**
// cout << G_ << endl << endl;
x = u_ * G_;
for (int i = 0; i < dim_mat_col; i++)
{
x(i) = x(i) % 2;
}
// std::cout << "correct codeword: " << x << std::endl;
// mapping for BPSK
for (int i = 0; i < dim_mat_col; i++)
{
if (x(i) == 0)
x(i) = 1;
else
x(i) = -1;
}
// awgn::awgn channel(dim_mat_col);
// channel.addGausian(this->x);
}
P is being passed by non-const reference, which means it may be modified by the functions you call. Passing a copy of P in each iteration makes sure that the modifications to P stay local to that iteration:
for (int i = 0; i < N; i++) {
MatrixXi P_copy = P;
...
}
If I have an array that looks like
int digits[size] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4}
I want to remove the leading zeros and to do so I'm attempting to convert the array of integers into a string (which is an array of chars).
My attempt looks like
string toString(int digits[], int size){
string number = " ";
for(int i = 0; i < size - 1; i++){
number[i] = digits[i];
}
return number;
}
which came out horribly broken.
I also can't simply remove all zeros, just the leading ones.
Also if I may dogpile another question here:
how can I identify if a string is numeric?
e.g
string number = "12a4"
cout << "not a number"
you can use C++11 function std::to_string() here is an example
#include <string>
#include <iostream>
int main()
{
int size = 15;
int digits[size] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
std::string result = "";
for (int i = 0; i < size; i++)
{
if (!(digits[i] == 0 && result.size() == 0))
result += std::to_string(digits[i]);
}
std::cout << result << std::endl;
}
you can check if a string is numeric using this function
bool isNb(std::string str)
{
if (str.size() == 0)
return false;
for (int i = 0; i < str.size(); i++)
{
if (std::isdigit(str.at(i)) == false)
return false;
}
return true;
}
Instead of changing digits with your for loop, add them with
number += to_string(digits[i]);
Also, you can remove the toString line you have, and just use it as I put here.
As to your other question, just use a for loop to check each digit in the string and its ASCII value, if there is any whose ASCII value is less than 48 or greater than 57 then it's not a number.
Try the following way:
int i = 0;
while(digits[i] == 0) i++;
for (; i < size; i++)
result += to_string(digits[i]);
To answer your actual question (How to remove the leading zeros?) here a solution without strings:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
std::vector<int> x = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
// ...or if you insist on the array...
// int x[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
// std::vector<int> x = {x,x+15};
auto it = std::find_if_not(x.begin(),x.end(),[](int i){return i==0;});
std::vector<int> y{it,x.end()};
for (auto i : y) std::cout << i << " ";
}
prints:
1 2 3 0 4
You can use a string stream to convert from any type to string:
#include <sstream> //<-- ALLOWS USE OF std::stringstream
const int size = 15;
int digits[size] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
std::stringstream ss; //<-- DECLARE STREAM
int k;
for (k = 0; k < size; ++k)
if (digits[k] != 0)
break; //FIND FIRST NON-0 INDEX
for (int i = k; i < size; ++i)
ss << digits[i]; //ADD TO THE STREAM s
std::cout<< ss.str() << std::endl; //PRINT STREAM
12304
Hello after connected component labeling for a single label why am I getting more than a one pixel value ?
this is my image
#include <iostream>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
void FindBlobs(const cv::Mat &binary, std::vector < std::vector<cv::Point2i> > &blobs);
int main(int argc, char **argv)
{
cv::Mat img = cv::imread("/Users/Rodrane/Documents/XCODE/test/makalesvm/persembe.png", 0); if(!img.data) {
std::cout << "File not found" << std::endl;
return -1;
}
cv::namedWindow("binary");
cv::namedWindow("labelled");
cv::Mat output = cv::Mat::zeros(img.size(), CV_8UC3);
cv::Mat binary;
std::vector < std::vector<cv::Point2i > > blobs;
equalizeHist( img , img );
cv::threshold(img, binary, 0, 1, cv::THRESH_BINARY_INV);
FindBlobs(binary, blobs);
// Randomy color the blobs
for(size_t i=0; i < blobs.size(); i++) {
unsigned char r = 255 * (rand()/(1.0 + RAND_MAX));
unsigned char g = 255 * (rand()/(1.0 + RAND_MAX));
unsigned char b = 255 * (rand()/(1.0 + RAND_MAX));
for(size_t j=0; j < blobs[i].size(); j++) {
int x = blobs[i][j].x;
int y = blobs[i][j].y;
output.at<cv::Vec3b>(y,x)[0] = b;
output.at<cv::Vec3b>(y,x)[1] = g;
output.at<cv::Vec3b>(y,x)[2] = r;
}
}
cout << "H = "<< endl << " " << output << endl << endl;
cv::imshow("binary", img);
cv::imshow("labelled", output);
cv::waitKey(0);
return 0;
}
void FindBlobs(const cv::Mat &binary, std::vector < std::vector<cv::Point2i> > &blobs)
{
blobs.clear();
// Fill the label_image with the blobs
// 0 - background
// 1 - unlabelled foreground
// 2+ - labelled foreground
cv::Mat label_image;
binary.convertTo(label_image, CV_32SC1);
int label_count = 2; // starts at 2 because 0,1 are used already
for(int y=0; y < label_image.rows; y++) {
int *row = (int*)label_image.ptr(y);
for(int x=0; x < label_image.cols; x++) {
if(row[x] != 1) {
continue;
}
cv::Rect rect;
cv::floodFill(label_image, cv::Point(x,y), label_count, &rect, 0, 0, 4);
std::vector <cv::Point2i> blob;
for(int i=rect.y; i < (rect.y+rect.height); i++) {
int *row2 = (int*)label_image.ptr(i);
for(int j=rect.x; j < (rect.x+rect.width); j++) {
if(row2[j] != label_count) {
continue;
}
blob.push_back(cv::Point2i(j,i));
}
}
blobs.push_back(blob);
label_count++;
}
}
}
actually this is a single label when I print the image
however when I check pixel values. I see there is actually 2 different values (I just write down part of the matrix not all)
H = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 33, 0, 192, 33, 0, 192, 33, 0, 0, 0, 0, ]
also by adding this line of code to the last line of FindBlobs function I recieve 3 since the label_count variable starts from 2 this also proves that H is a single label.
cout << "number of labels = "<< endl << " " << label_count << endl << endl;
I have a matrix called "temp_matrix" that looks kind of like this:
0.0,100.0,100.0,100.0,
0.0,45.1,60.6,66.2,0,
0.0,45.1,60.6,66.2,0,
0.0,100.0,100.0,100.0,0,
...except mine is a 20x20 matrix.
I've tried:
ofstream excel_plate("plate.csv");
excel_plate.write(temp_matrix[0],20);
excel_plate.close();
cout << endl;
but can't compile.
I've tried:
ofstream excel_plate("plate.csv");
excel_plate << temp_matrix[0], 20, 20;
excel_plate.close();
...but just get a csv file with a string of characters in the very first cell that looks like this: 0052EE98.
Here is my code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <math.h>
#include <Windows.h>
#include <algorithm>
#include <string>
#include <array>
#undef max
using namespace std;
const double neighbors = 4;
// START FUNCTION: Update Elements
void average(double *temp_matrix, int ROWS, int COLUMNS)
{
int i = 0;
int j = 0;
double row_left = 0;
double row_right = 0;
double column_up = 100;
double column_down = 0;
double sum = 0;
double av = 0;
for (int i = 1; i < ROWS - 1; i++)
{
for (int j = 1; j < COLUMNS - 1; j++)
{
/*
cout << "row_left:" << *(temp_matrix + i*ROWS + (j - 1)) << " ";
cout << "row_right:" << *(temp_matrix + i*ROWS + (j + 1)) << " ";
cout << "column_up:" << *(temp_matrix + (i - 1)*ROWS + j) << " ";
cout << "column_down:" << *(temp_matrix + (i + 1)*ROWS + j) << " ";
*/
row_left = *(temp_matrix + i*ROWS + (j-1));
row_right = *(temp_matrix + i*ROWS + (j + 1));
column_up = *(temp_matrix + (i-1)*ROWS + j);
column_down = *(temp_matrix + (i+1)*ROWS + j);
sum = row_left + row_right + column_up + column_down;
av = sum / neighbors;
*(temp_matrix + i*ROWS + j) = av;
}
}
}
// END FUNCTION: Update Elements
// START FUNCTION: Updtate Until Stable
void update(double *temp_matrix, int ROWS, int COLUMNS)
{
int i = 0;
int j = 0;
double row_left = 0;
double row_right = 0;
double column_up = 100;
double column_down = 0;
double sum = 0;
double old_num = 0;
double new_num = 0;
double difference = 0;
double max_change = .11;
while (max_change > .1)
{
max_change = -1;
for (int i = 1; i < ROWS - 1; i++)
{
for (int j = 1; j < COLUMNS - 1; j++)
{
old_num = *(temp_matrix + i*ROWS + j);
/*
cout << "row_left:" << *(temp_matrix + i*ROWS + (j - 1)) << " ";
cout << "row_right:" << *(temp_matrix + i*ROWS + (j + 1)) << " ";
cout << "column_up:" << *(temp_matrix + (i - 1)*ROWS + j) << " ";
cout << "column_down:" << *(temp_matrix + (i + 1)*ROWS + j) << " ";
*/
row_left = *(temp_matrix + i*ROWS + (j - 1));
row_right = *(temp_matrix + i*ROWS + (j + 1));
column_up = *(temp_matrix + (i - 1)*ROWS + j);
column_down = *(temp_matrix + (i + 1)*ROWS + j);
sum = row_left + row_right + column_up + column_down;
new_num = sum / neighbors;
difference = new_num - old_num;
if (difference > max_change)
{
max_change = difference;
}
*(temp_matrix + i*ROWS + j) = new_num;
}
}
}
}
// END FUNCTION: Update Until Stable
// START FUNCTION: Print Array
void print_array(double *temp_matrix, int ROWS, int COLUMNS)
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
if (j > 0)
{
cout << ",";
}
cout << fixed << setw(5) << setprecision(1) << *(temp_matrix + i*ROWS + j);
}
cout << endl;
}
}
// END FUNCTION: Print Array
// START FUNCTION: Print 4 Excel
void print_excel(double *temp_matrix, int ROWS, int COLUMNS)
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
cout << fixed << setprecision(1) << *(temp_matrix + i*ROWS + j) << ",";
}
cout << endl;
}
}
// END FUNCTION: Print 4 Excel
int main()
{
const int ROWS = 20;
const int COLUMNS = 20;
double temp_matrix[ROWS][COLUMNS] =
{
{ 0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 0 }
};
print_array(temp_matrix[0], 20, 20);
system("pause");
cout << endl << endl;
average(temp_matrix[0], 20, 20);
print_array(temp_matrix[0], 20, 20);
system("pause");
cout << endl << endl;
update(temp_matrix[0], 20, 20);
print_array(temp_matrix[0], 20, 20);
system("pause");
cout << endl << endl;
print_excel(temp_matrix[0], 20, 20);
ofstream excel_plate("plate.csv");
if (excel_plate.is_open())
{
excel_plate << temp_matrix[0], 20, 20;
excel_plate.close();
}
else
{
cout << "Unable to open file.";
}
/*
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
if (j > 0)
{
cout << ",";
}
cout << temp_matrix[i][j];
}
cout << endl;
}
*/
system("pause");
return 0;
}
This should be very, very simple. Please kindly help a noob out. :)
P.S. Because this is an assignment, you'll notice that I print out several matrices. The last one I print out is the format in which the matrix needs to be transferred to a .csv file.
The simplest way would be something like the following (assuming you can use c++11)
std::ofstream out("test.csv");
for (auto& row : temp_matrix) {
for (auto col : row)
out << col <<',';
out << '\n';
}
So, this code conatains a functions that should be able to transfer any 2d string array into a csv file
#include <iostream>
#include <fstream>
#include<string>
/* This is for a string array, but if you want to use any other type, just replace
'std::string' with int,double....*/
template <size_t row, size_t col>
void twodarray2csv(std::string(&array)[row][col], std::string filename)
{
std::ofstream myfile;
myfile.open(filename);
for (size_t i = 0; i < row; ++i)
{
for (size_t j = 0; j < col; ++j)
if (j < (col - 1)) {
myfile << array[i][j] << ",";
}
else if (j == (col - 1)) {
myfile << array[i][j] << "\n";
}
}
}
Th template gets the row size and column size and also opens ofstream which is basically for just opening the csv file that will be the output file
int main() {
//example
std::string ArrayName[9][3];
/* this for loop is just there to populate the array, if you have an array
already skip this step */
#include <iostream>
#include <fstream>
#include<string>
/* This is for a string array, but if you want to use any other type, just replace
'std::string' with int,double....*/
template <size_t row, size_t col>
void twodarray2csv(std::string(&array)[row][col], std::string filename)
{
std::ofstream myfile;
myfile.open(filename);
for (size_t i = 0; i < row; ++i)
{
for (size_t j = 0; j < col; ++j)
if (j < (col - 1)) {
myfile << array[i][j] << ",";
}
else if (j == (col - 1)) {
myfile << array[i][j] << "\n";
}
}
}
So the function above uses a template to get the row size and column size of the array, after which it iterates through the array so that when it passes by elements of the same row it adds a comma to the file and at the end of each row it adds a new line (\n) which is a row separator
The part below is an example of how to use it and how it works
First i just created a an Array called ArrayName, and populated it with just some numbers (int number)
int number = 0;
for (int i = 0; i < 9; i++) {
for (int x = 0; x < 3; x++) {
ArrayName[i][x] = number;
number++;
}
}
//this part converts the array to a csv file of desried name
twodarray2csv(ArrayName, "outputfile.csv");
return 0;
}
The output will be a csv file with the name "outputfile.csv" stored in the same folder with the cpp file you have
So I'm trying to code Dijkstra's shortest path algorithm in C++. For some reason, it's not adding up the distances correctly...
Here is what I have so far for code. You can ignore the section where I am copying the path to the stack because I know it's not complete yet. Any ideas where I'm going wrong?
#include <fstream>
#include "matrix.h"
#include <list> // STL container
using namespace std;
//---------------------------------------------------------------------------
const int INFIN = 100000;
const int size = 8;
double a[] = {
0, 0, 5, 0, 0, 2, 3, 0, //length matrix ( #9, page 276)
4, 0, 6, 0, 7, 0, 5, 0,
0, 3, 0, 9, 2, 6, 0, 7,
3, 0, 2, 0, 1, 0, 7, 6,
0, 5, 0, 1, 0, 0, 4, 0,
0, 0, 2, 0, 8, 0, 9, 0,
1, 2, 3, 0, 0, 6, 0, 0,
5, 0, 8, 0, 2, 0, 9, 0
};
// Global declarations for L Matrix and begin and end node
Matrix L(size,size,a); //length matrix
int begin, end;
void path(long* D, int* P); //function prototype for shortest path algorithm
Matrix Warshall(Matrix M);
void main()
{
int i, u;
long D [size+1]; //distance functions
int P [size+1]; //prior vertices in path
cout << "\nLength Matrix: " << L;
cout << "\nPaths that exist:" << Warshall(L);
for (i=1; i <= size; i++) {
D[i] = INFIN; //initialize distance functions
P[i] = 0;
}
cout << "\nFind distance from vertex #";
cin >> begin;
cout << " to vertex #";
cin >> end;
if (begin == end) exit(1);
if (begin < 0 || end < 0) exit(1);
if (begin > size || end > size) exit(1);
path(D,P);
cout << "\nShortest distance from \nvertex #"
<< begin << " to vertex #"
<< end << " is " << D[end];
// u = end;
list<int> stack; // work path backwards
while (1) {
stack.push_front(end);
stack.push_front(begin);
break;
}
cout << "\nusing path:\n";
cout << "\t" << stack.front();
stack.pop_front();
while (stack.size()) {
cout << " -> " << stack.front();
stack.pop_front();
}
getch();
}
void path(long* D, int* P) {
int i, u, dist;
int U[size+1];
for (i=1; i <= size; i++)
U[i] = 0;
U[begin] = 1; // add first vertex;
D[begin] = 0;
u = begin;
do { // until find end vertex
for (i = 1; i <= size; i++) {
dist = L.element(u,i); // distance from u to i
if( D[u] + dist < D[i]) {
D[i] = D[u] + dist;
P[i] = u;
}
}
dist = 38000; // reset distance value to large value
int min;
for(i = 1; i <= size; i++) {
if(L.element(u,i) != 0) {
if(L.element(u,i) < dist && U[i] != 1) {
dist = L.element(u,i);
min = i;
}
}
}
u = min;
U[u] = 1;
cout << "Min is " << min << endl;
} while (u != end);
}
if( D[u] + dist < D[i]) {
D[i] = D[u] + dist;
P[i] = u;
}
should be
if( D[u] + dist < D[i] && dist != 0) {
D[i] = D[u] + dist;
P[i] = u;
}