Prim's algorithm won't compute - graph

I made a prim's algorithm but whenever i try to use the code it give me the same matrix back. In general it isn't minimizing. Can anyone check the code and let me know why it isn't minimizing my matrix
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <list>
#include <cstdlib>
#include <iomanip>
#include <limits.h>
int minKey(int n,int key[], bool mst[])
{
// Initialize min value
int min = INT_MAX, min_index;
for (int i = 0; i < n; i++)
if (mst[i] == false && key[i] < min)
min = key[i], min_index = i;
return min_index;
}
void print(int n,int **matrix)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++) // print the matrix
{
cout << setw(2) << matrix[i][j] << " ";
}
cout << endl;
}
}
int **gen_random_graph(int n)
{
srand(time(0));
int **adj_matrix = new int*[n];
for(int i = 0; i < n; i++)
{
for (int j = i; j < n; j++) //generating a N x N matrix based on the # of vertex input
{
adj_matrix[i] = new int[n];
}
}
for(int u = 0; u < n; u++)
{
for (int v = u; v < n; v++) //decide whether it has an edge or not
{
bool edgeOrNot = rand() % 2;
adj_matrix[u][v] = adj_matrix[v][u] = edgeOrNot;
cout << u << " " << v << " " << adj_matrix[u][v] << endl;
if(adj_matrix[u][v] == true)
{
adj_matrix[v][u] = true;
if(u == v) //We can't have i = j in an undirected graph
{
adj_matrix[u][v] = -1;
}
cout << u << " " << v << " " << adj_matrix[u][v] << endl;
}
else
{
adj_matrix[v][u] = adj_matrix[u][v] = -1;
cout << u << " " << v << " " << adj_matrix[u][v] << "else" << endl;
}
}
}
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++) //create the N x N with edges and sets the weight between the edge randomly
{
if(adj_matrix[i][j] == true)
{
int weight = rand() % 10 + 1;
adj_matrix[i][j] = adj_matrix[j][i] = weight;
cout << " ( " << i << "," << j << " ) " << "weight: " << adj_matrix[i][j] << endl;
}
}
}
print(n,adj_matrix);
return (adj_matrix);
}
void solve_mst_prim_matrix(int n, int **matrix)
{
int parent[n]; // Array to store constructed MST
int key[n]; // Key values used to pick minimum weight edge in cut
bool mstSet[n]; // To represent set of vertices not yet included in MST
// Initialize all keys as INFINITE
for (int i = 0; i < n; i++)
{
key[i] = INT_MAX, mstSet[i] = false;
}
// Always include first 1st vertex in MST.
key[0] = 0; // Make key 0 so that this vertex is picked as first vertex
parent[0] = -1; // First node is always root of MST
// The MST will have n vertices
for (int count = 0; count < n-1; count++)
{
// Pick the minimum key vertex from the set of vertices
// not yet included in MST
int u = minKey(n,key, mstSet);
// Add the picked vertex to the MST Set
mstSet[u] = true;
// Update key value and parent index of the adjacent vertices of
// the picked vertex. Consider only those vertices which are not yet
// included in MST
for (int v = 0; v < n; v++)
// matrix[u][v] is non zero only for adjacent vertices of m
// mstSet[v] is false for vertices not yet included in MST
// Update the key only if matrix[u][v] is smaller than key[v]
if (matrix[u][v] && mstSet[v] == false && matrix[u][v] < key[v])
parent[v] = u, key[v] = matrix[u][v];
}
cout << endl;
print(n,matrix);
}
int main()
{
int N;
cout << "Enter number of vertices" << endl;
cin >> N;
int **matrix = gen_random_graph(N);
solve_mst_prim_matrix(N, matrix);
return 0;
}

Correct me if I'm wrong, but after reading your code, you did not even change any value of **matrix in your solve_mst_prim_matrix function. So it basically prints the same thing..

Related

Where to initialize array then to scatter it. MPI_Scatter

I need to send array pieces to all processes using MPI_Scatter then to get sum of all elements. Where should I initialize array then to scatter it? In root rank?
If I initialize array on root rank then other ranks dont get their data. Otherway I can initialize array for everyone (out of if(rank == root)...else), but it means, that I create array several times.
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <iostream>
#include <time.h>
using namespace std;
int main(int argc, char* argv[])
{
int size;
int rank;
srand(time(NULL));
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int arr_size = size * 2;
int block = arr_size / (size);
int* B = new int[block];
if (rank == 0)
{
int* A = new int[arr_size];
cout << "generated array: " << endl;
for (int i = 0; i < arr_size; i++)
{
A[i] = rand() % 100;
cout << A[i] << " ";
}
cout << endl;
MPI_Scatter(A, block, MPI_INT, B, block, MPI_INT, 0, MPI_COMM_WORLD);
}
cout << "process " << rank << " received: " << endl;
for (int i = 0; i < block; i++)
{
cout << B[i] << " ";
}
cout << endl;
int local_sum = 0;
for (int i = 0; i < block; i++)
{
local_sum += B[i];
}
cout << "sum in process " << rank << " = " << local_sum << endl;
cout << endl;
int global_sum;
MPI_Reduce(&local_sum, &global_sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank == 0)
{
cout << "sum = " << global_sum << endl;
}
MPI_Finalize();
return 0;
}
I get something like this (only root rank got its data):
process 1 received:
process 3 received:
-842150451 -842150451
-842150451 -842150451
sum in process 1 = -1684300902
sum in process 3 = -1684300902
process 2 received:
-842150451 -842150451
sum in process 2 = -1684300902
process 0 received:
4 9
sum in process 0 = 13
sum = -757935397
MPI_Scatter() is a collective operation and must hence be invoked by all the ranks.
Declare int *A = NULL; on all ranks and only allocate and populate on rank zero.
int* A = NULL;
int* B = new int[block];
if (rank == 0)
{
A = new int[arr_size];
cout << "generated array: " << endl;
for (int i = 0; i < arr_size; i++)
{
A[i] = rand() % 100;
cout << A[i] << " ";
}
cout << endl;
}
MPI_Scatter(A, block, MPI_INT, B, block, MPI_INT, 0, MPI_COMM_WORLD);

dynamic arrays c++ Access violation writing location

What is wrong with my code ? I have the error like this.
Unhandled exception at 0x00d21673 in mnozenie_macierzy.exe : 0xC0000005: Access violation writing location 0xcdcdcdcd.
It create the first array and the half to the second. The program multiplies arrays.
Sorry for my English if It isn't correct. I hope you understand me.
#include <iostream>
#include <time.h>
using namespace std;
void losowa_tablica(int **tab1, int **tab2, int a, int b, int c, int d)
{
int i, j;
for(i=0; i<a; i++)
{
cout << endl;
for(j=0; j<b; j++)
{
tab1[i][j]=rand();
cout << "tab1[" << i << "][" << j << "] : \t" << tab1[i][j] << "\t";
}
}
cout << endl;
for(i=0; i<c; i++)
{
cout << endl;
for(j=0; j<d; j++)
{
tab2[i][j]=rand();
cout << "tab2[" << i << "][" << j << "] : \t" << tab2[i][j] << "\t";
}
}
cout << endl << endl;
}
int **mnozenie(int **tab1, int **tab2, int a, int b, int c, int d)
{
int g, suma, i, j;
int **mac=new int*[a];
for(int i=0; i<d; i++)
mac[i]=new int[d];
for(i=0; i<a; i++)
for(j=0; j<d; j++)
{
g=b-1, suma=0;
do
{
suma+=tab1[i][g]*tab2[g][j];
g--;
}while(g!=0);
mac[i][j]=suma;
}
return mac;
}
int main()
{
int a,b,c,d;
cout << "Podaj liczbe wierszy pierwszej macierzy: " << endl;
cin >> a;
cout << "Podaj liczbe kolumn pierwszej macierzy: " << endl;
cin >> b;
cout << "Podaj liczbe wierszy drugiej macierzy: " << endl;
cin >> c;
cout << "Podaj liczbe kolumn drugiej macierzy: " << endl;
cin >> d;
int **tab1=new int*[a];
for(int i=0; i<b; i++)
tab1[i]=new int[b];
int **tab2=new int*[c];
for(int i=0; i<d; i++)
tab2[i]=new int[d];
losowa_tablica(tab1, tab2, a, b, c, d);
if ( b==c )
{
cout << "Mnozenie wykonalne" << endl;
int **mno=mnozenie(tab1, tab2, a, b, c, d);
}
else cout << "Mnozenie niewykonalne" << endl;
system("pause");
}
Your code yields undefined behavior:
int **tab1=new int*[a]; // allocating an array of 'a' elements
for(int i=0; i<b; i++) // if b > a then the next line will eventually yield UB
tab1[i]=new int[b];
int **tab2=new int*[c]; // allocating an array of 'c' elements
for(int i=0; i<d; i++) // if d > c then the next line will eventually yield UB
tab2[i]=new int[d];
int **mac=new int*[a]; // allocating an array of 'a' elements
for(int i=0; i<d; i++) // if d > a then the next line will eventually yield UB
mac[i]=new int[d];
In practice, the above code will most likely perform a memory access violation at some point.

Pointer Arithmetic in Opencv Using CvMat?

So I'm trying to access matrix elements via a pointer. Here is my code:
CvMat *Q = cvCreateMat(3,3, CV_32F);
for(int i = 0; i < Q->rows ; i++){
float *ptr = (float *)(Q->data.ptr + i * Q->step );
for(int j = 0; j < Q->cols ; j++){
*ptr = 0.0;
if((i ==0)&&(j==0)) *ptr = 1;
if((i ==0)&&(j==1)) *ptr = 2;
if((i ==0)&&(j==2)) *ptr = 3;
if((i ==1)&&(j==0)) *ptr = 4;
if((i ==1)&&(j==1)) *ptr = 5;
if((i ==1)&&(j==2)) *ptr = 6;
if((i ==2)&&(j==0)) *ptr = 7;
if((i ==2)&&(j==1)) *ptr = 8;
if((i ==2)&&(j==2)) *ptr = 9;
//cout << *ptr << endl;
//system("pause");
}
}
cout << CV_MAT_ELEM(*Q,float,0,0) << endl;
cout << CV_MAT_ELEM(*Q,float,0,1) << endl;
cout << CV_MAT_ELEM(*Q,float,0,2) << endl;
cout << CV_MAT_ELEM(*Q,float,1,0) << endl;
cout << CV_MAT_ELEM(*Q,float,1,1) << endl;
cout << CV_MAT_ELEM(*Q,float,1,2) << endl;
cout << CV_MAT_ELEM(*Q,float,2,0) << endl;
cout << CV_MAT_ELEM(*Q,float,2,1) << endl;
cout << CV_MAT_ELEM(*Q,float,2,2) << endl;
system("pause");
I am trying to make the matrix in the for loop as:
[1 2 3
4 5 6
7 8 9],
but when cout'ing them, I get:
3
-4.31602e+008
-4.31602e+008
6
-4.31602e+008
-4.31602e+008
9
-4.31602e+008
-4.31602e+008
Where is the -4.31602e+008 coming from? What am I not understanding here? I'm a little new to pointers.
Check out the API for CvMat (also you might want to consider using Mat if you can use c++).
I'm not totally sure what you are trying to accomplish here, but if you want to access the data using the pointer you are doing it slightly wrong at this point.
float *ptr = (float *)(Q->data.ptr + i * Q->step );
The step here is the number of bytes in a row (so here it would be 12, 4 bytes per element * 3 elements) the pointer will automatically step the correct number of bytes based on the datatype of the pointer when you do arithmetic with it (Good tutorial here). In order to access it like an array you should do it like this:
CvMat *Q = cvCreateMat(3,3, CV_32F);
for(int i = 0; i < Q->rows ; i++){
for(int j = 0; j < Q->cols ; j++){
float *ptr = (float *)(Q->data.ptr) + i*Q->rows + j; //Index is row major
if((i ==0)&&(j==0)) *ptr = 1;
if((i ==0)&&(j==1)) *ptr = 2;
if((i ==0)&&(j==2)) *ptr = 3;
if((i ==1)&&(j==0)) *ptr = 4;
if((i ==1)&&(j==1)) *ptr = 5;
if((i ==1)&&(j==2)) *ptr = 6;
if((i ==2)&&(j==0)) *ptr = 7;
if((i ==2)&&(j==1)) *ptr = 8;
if((i ==2)&&(j==2)) *ptr = 9;
}
}
A much simpler solution would be to use the CV_MAT_ELEM macro that exists.
CvMat *Q = cvCreateMat(3,3, CV_32F);
for(int i = 0; i < Q->rows ; i++){
for(int j = 0; j < Q->cols ; j++){
CV_MAT_ELEM(*Q, float, i, j) = i*Q->rows + j + 1;
}
}
You should increment ptr inside your inner j loop.

Converting 1d vector into 2d vector

#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<double> > DV; //2d vector
std::vector<double>temp(8,0.0); //1d vector
temp[0] = 1;
temp[1] = 2;
temp[2] = 3;
temp[3] = 4;
temp[4] = 5;
temp[5] = 6;
temp[6] = 7;
temp[7] = 8;
DV.resize(3, temp);
for (int i = 0; i < DV.size(); i++)
{
for (int j = 0; j < DV.size(); j++)
{
std::cout << DV[i][j];
}
}
std::cin.get();
}
The convertion actually works but it does not give the expected the result. The output should be:
1 2 3
4 5 6
7 8
and it outputs:
123123123
Thanks in advance
I'm not aware of a method to automagically turn a 1D vector into a 2D one. It's not too hard to do manually, though...
typedef std::vector<std::vector<double>> DoubleVector2D;
DoubleVector2D boxed(size_t cols, std::vector<double> values) {
DoubleVector2D result;
for (std::size_t i = 0; i < values.size(); ++i) {
if (i % cols == 0) result.resize(result.size() + 1);
result[i / cols].push_back(values[i]);
}
return result;
}
With that done, you can call boxed(3, temp) to get back a vector of vectors of doubles. At that point, you just have to loop over them.
for (auto row : DV) {
for (auto value : row) {
std::cout << value << ' ';
}
std::cout << "\n";
}
If you're stuck without decent C++11 support, you may need to use counters or iterators.
for (int row = 0; row < DV.size(); ++row) {
for (int col = 0; col < DV[i].size(); ++col) {
std::cout << DV[row][col] << ' ';
}
std::cout << '\n';
}
Change this lines
for (int i = 0; i < DV.size(); i++){
for (int j = 0; j < DV.size(); j++){
std::cout << DV[i][j] << ", ";
}
std::cout << std::endl;
}
Your issue is how you are printing your values to the standard output.

OpenCV populating CvMat with data and verifying it

I have a vector of TrainingSets(struct below) called data
class TrainingSet
{
public:
int time;
float input[2];
float output[3*NUM_TRACKING_POINTS];
TrainingSet(int t, float in[2], float out[3*NUM_TRACKING_POINTS])
{
time = t;
for (int i = 0; i < 2; i++)
input[i] = in[i];
for (int i = 0; i < 3*NUM_TRACKING_POINTS; i++)
output[i] = out[i];
}
TrainingSet()
{
}
};
And then I try to take the contents of this Vector, and put them into CvMats for the purpose of training a Neural Network.
int datasize = data.size();
float** in = new float*[datasize];
float** out = new float*[datasize];
for (int i = 0; i < datasize; i++) {
in[i] = new float[2*TIME_STEPS];
out[i] = new float[3*NUM_TRACKING_POINTS];
}
for ( int i = 0 ; i < datasize; i ++)
{
// get the first set in the sequence.
TrainingSet tset = data.front();
data.pop();
// get the inputs
in[i] = new float[2*TIME_STEPS];
in[i][0] = tset.input[0];
in[i][1] = tset.input[1];
// get the outputs
out[i] = new float[3*NUM_TRACKING_POINTS];
for (int j = 0; j < 3*NUM_TRACKING_POINTS; j++)
out[i][j] = tset.output[j];
for (int j = 2; j < 2*TIME_STEPS; j++)
{
if (i == 0)
in[i][j] = 0.0f;
else
in[i][j] = in[i - 1][j - 2];
}
}
// make matrices from data.
CvMat *trainInput = cvCreateMat(datasize, 2*TIME_STEPS, CV_32FC1);
cvInitMatHeader(trainInput, datasize, 2*TIME_STEPS, CV_32FC1, in);
CvMat *trainOutput = cvCreateMat(datasize, 3*NUM_TRACKING_POINTS, CV_32FC1);
cvInitMatHeader(trainOutput, datasize, 3*NUM_TRACKING_POINTS, CV_32FC1, out);
for (int x = 0; x < datasize; x++)
{
cout << "IN: ";
for (int y = 0; y < 2*TIME_STEPS; y++)
cout << cvmGet(trainInput, x, y) << " ";
cout << endl << "IN: ";
for (int y = 0; y < 2*TIME_STEPS; y++)
cout << in[x][y] << " ";
cout << endl << "OUT: ";
for (int y = 0; y < 3 * NUM_TRACKING_POINTS; y++)
cout << cvmGet(trainOutput, x, y) << " ";
cout << endl << "OUT: ";
for (int y = 0; y < 3 * NUM_TRACKING_POINTS; y++)
cout << out[x][y] << " ";
cout << endl << endl;
}
That last forloop is to check to see if the matrices contents are the data I just fed it, but they don't match. The Matrices seem to have completely different data.
Any thoughts on what is going wrong?
Seems to me that in and out are not a contiguous array, but an array of pointers.
I think the cvMat needs a contiguous memory array to be able to operate on it.
Also once you create the array, you don't need to create a CvMat from it, just
use the
CvSetData( header, data ).

Resources