global variable and class versus local - c++

I am writing a program, it is an optimization problem. As part of the problem I have defined a class in which I save the optimization parameters. It is composed of some vectors that I resize them and give initial values to them in a function. The class is as follows:
typedef class Chrom
{
public:
vector<vector <short int>> bit;
vector<vector <float>> WaitingTime;
vector <short int> WaitingJob;
vector<vector <float>> StartTime;
vector<vector <float>> finish;
//short int FinishTime;
float fit;
void variablesresize(){
WaitingTime.resize(Jobs);
WaitingJob.resize(Jobs);
StartTime.resize(Jobs);
finish.resize(Jobs);
bit.resize(Jobs);
//cout << "machine size is:" << Machines;
for (int i = 0; i < Machines - 1; ++i)
{
WaitingTime[i].resize(Jobs);
}
for (int i = 0; i < Machines; ++i)
{
StartTime[i].resize(Jobs);
finish[i].resize(Jobs);
bit[i].resize(Jobs);
}
}
} chrom;
Then I define two classes of this type (popcurrent and popnext) and also functions y and x before main function:
chrom popcurrent[populationsize];
chrom popnext[populationsize];
void *initialize(chrom popcurrent[populationsize]); //defining the
functions that we will use
chrom x(chrom popcurrent,int pindex);
float y(chrom chromp);
void *selection(chrom popcurrent[populationsize]);
void *crossover(chrom popnext[populationsize]);
void *mutation(chrom popnext[populationsize]);
Problem ProblemConstraint;
void SetProblemSize(short int &Machines, short int &Jobs);
void vectordimension(chrom ch[populationsize]);
void ytest(chrom popcurrent);
void main()
{
My Issue is that whenever I call x and y within other functions and I assign some values in other functions, it gives back only zero for the members of those classes. For example below is a part of assigning value in function x:
chrom x(chrom popnext,int pindex)
{
int z = 0, i, j, k, tempindex, previousjobindex, l;
float temp;
//sorting chromosoms based on the population
//if
cout << '\n';
cout << "popcurrent.bit[0][0] =" << popnext.bit[0][0] << '\n';
cout << "popcurrent.bit[0][1] =" << popnext.bit[0][1] << '\n';
//for the first machine
//for (int i = 0; i < populationsize;i++)
for (i = 0; i < Machines; i++)//**just for test
for (j = 0; j < Jobs; j++)//**just for test
{
cout << "popcurrent.bit[" << i << "][" << j << "] =" << popnext.bit[i]
[j] << '\n';
}
for (int j = 0; j < Machines; j++)//after first machine so j=1 and not 0
{
for (int k = 0; k < Jobs; k++)
{
for (l = 0; l < Jobs; l++)
if (popnext.bit[j][l] == 1)
{
cout << "j= " << j << "k = " << k;
popnext.WaitingTime[j][k] = ProblemConstraint.t1[j][k];
popnext.StartTime[j][k] = popnext.finish[j - 1][k] +
popnext.WaitingTime[j - 1][k];
popnext.finish[j][k] = popnext.WaitingTime[j][k] + ProblemConstraint.Processing[j][k] + popnext.StartTime[j][k];
cout << "
cout << "popcurrent.StartTime[" << j << "][" << k << "]= " << popnext.StartTime[j][k] << " popcurrent.finish[j - 1][k]" << popnext.finish[j - 1][k] << '\n';
cout << " popcurrent.WaitingTime[" << j - 1 << "][" << k << "]= " << popnext.WaitingTime[j - 1][k] << '\n';//start time of machine j is equal to finish time of machine j-1
}
}
for (k = 1; k < Jobs; k++)
{
if (popnext.bit[j][k] == k + 1)
{
for (int l = 0; l < Jobs; l++)
if (popnext.bit[j][l] == 1 + k)
{
temp = popnext.finish[j][l];//finish time of previous job
tempindex = l;
}
popnext.StartTime[j][k] = temp;
if (popnext.StartTime[j][k] < popnext.finish[j - 1][k] + popnext.WaitingTime[j - 1][k]);
popnext.StartTime[j][k] = popnext.finish[j - 1][k] + popnext.WaitingTime[j - 1][k];//we need to update the start time and also we need to update w as well.
else if (popnext.StartTime[j][k] > popnext.finish[j - 1][k] + popnext.WaitingTime[j - 1][k])
popnext.WaitingTime[j - 1][k] = popnext.StartTime[j][k] - popnext.finish[j - 1][k];//we need to update the waiting time which is greater than t1 here.
popnext.finish[j][k] = popnext.StartTime[j][k] + ProblemConstraint.Processing[j][k] + popnext.StartTime[j][k];
popnext.WaitingTime[j][k] = ProblemConstraint.t1[j][k];
cout << "popcurrent.finish[" << j << "][" << k << "]= " << popnext.finish[j][k] << '\n';//debugging code
}//start of '{' is: else if (popcurrent.bit[j][k] >0)
}
}
cout << "In x functionn, popcurrent.finish[Machines - 1][k]= " <<
popnext.finish[1][2] << '\n';//debugging cout
return(popnext);
}
The function returns popnext but I call it with x(popcurrent,pindex) and x(popnext,pindex). The problem is that after calling I expect that values of members such as finish change but they do not change and therefore when I have
x(popcurrent) ;
Because of last command in x function it prints out popcurrent.finish[Machines - 1][k]=32 but when I have a cout in another function such as main it gives me popcurrent.finish[Machines - 1][k]=0;
It only gives me zero for all values (I assigned zero to vector values in another function while defining them which is initial values of the vector). I wonder why this happens while I have defined popcurrent and popnext global classes?

Related

How can I merge three functions into one? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have written next code but 3 functions must be replaced by 1 and I don't know how to.
The program creates 3 arrays but only 1 function must calculate negative numbers of each column and find the max element in each column. Here's the code:
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
int n = 0;
const int m = 3, k = 3, b = 4, u = 5;
int i, j;
void calc(float** array, int i, int j );
void calc1(float** array, int i, int j);
void calc2(float** array, int i, int j);
int main()
{
float** array = new float* [m];
for (int l = 0; l < m; l++) {
array[l] = new float[k];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
array[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < k; j++) {
cout << setprecision(2) << setw(4) << array[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(array, i, j); // FUNCTION !!!
float** arr = new float* [b];
for (int l = 0; l < b; l++) {
arr[l] = new float[b];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < b; i++) {
for (int j = 0; j < b; j++) {
arr[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < b; i++)
{
for (int j = 0; j < b; j++) {
cout << setprecision(2) << setw(4) << arr[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(arr, i, j); // FUNCTION !!!
float** ar = new float* [u];
for (int l = 0; l < u; l++) {
ar[l] = new float[u];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < u; i++) {
for (int j = 0; j < u; j++) {
ar[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < u; i++)
{
for (int j = 0; j < u; j++) {
cout << setprecision(2) << setw(4) << ar[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc2(ar, i, j); // FUNCTION !!!
}
void calc(float** array, int i, int j) {
int max = array[0][0];
for (int j = 0; j < k; j++)
{
max = array[0][0];
for (int i = 0; i < k; i++) {
if (array[i][j] > max)
max = array[i][j];
if (array[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}
void calc1(float** arr, int i, int j) {
int max = arr[0][0];
for (int j = 0; j < b; j++)
{
max = arr[0][0];
for (int i = 0; i < b; i++) {
if (arr[i][j] > max)
max = arr[i][j];
if (arr[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}
void calc2(float** ar, int i, int j) {
int max = ar[0][0];
for (int j = 0; j < u; j++)
{
max = ar[0][0];
for (int i = 0; i < u; i++) {
if (ar[i][j] > max)
max = ar[i][j];
if (ar[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}
The parameters to calc() should be the number of rows and columns in the array. Then it should use these as the limits in the for loops.
Also, since you're calculating total negative and maximum for each column, you must reset these variables each time through the column loop.
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
const int m = 3, k = 3, b = 4, u = 5;
void calc(float** array, int rows, int cols);
int main()
{
float** array = new float* [m];
for (int l = 0; l < m; l++) {
array[l] = new float[k];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
array[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < k; j++) {
cout << setprecision(2) << setw(4) << array[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(array, m, k); // FUNCTION !!!
float *arr = new float* [b];
for (int l = 0; l < b; l++) {
arr[l] = new float[b];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < b; i++) {
for (int j = 0; j < b; j++) {
arr[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < b; i++)
{
for (int j = 0; j < b; j++) {
cout << setprecision(2) << setw(4) << arr[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(arr, b, b); // FUNCTION !!!
float** ar = new float* [u];
for (int l = 0; l < u; l++) {
ar[l] = new float[u];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < u; i++) {
for (int j = 0; j < u; j++) {
ar[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < u; i++)
{
for (int j = 0; j < u; j++) {
cout << setprecision(2) << setw(4) << ar[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(ar, u, u); // FUNCTION !!!
}
void calc(float** array, int rows, int cols) {
for (int j = 0; j < cols; j++)
{
int n = 0;
int max = array[0][j];
for (int i = 1; i < rows; i++) {
if (array[i][j] > max)
max = array[i][j];
if (array[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}

Last value of the array 'disapears'

So, i am currently doing a project. And while debuging i noticed that sometimes, a variable from the array changes value without me changing it.
The array is created to hold some values from tree structure.
int* tablica_synow1;
tablica_synow1 = (int*)malloc(sizeof(int) * number_of_sons(wskaznik_wierzcholki[zmienna1][i]));
//cout << "Initializing values to tablica_synow1" << endl;
for (int k = 0; k < ilu_synow(wskaznik_wierzcholki[zmienna2][j]); k++) {
if (k == 0)
tmp = wskaznik_wierzcholki[zmienna2][j]->son;
tablica_synow1[k] = tmp->key;
//cout << "tablica_synow1 [" << k << "]" << tablica_synow1[k] << endl;
tmp = tmp->brother;
}
//cout <<"end of initialization"<< endl;
after this I do some other things in my code that don't involde tablica_synow1
and then when i want to use it
for (int m = 0; m < ilu_synow(wskaznik_wierzcholki[zmienna2][j]); m++) {
int x = tablica_synow1[m];
cout << "tablica synow1 [" << m << "]" << tablica_synow1[m] << endl;
int y = i;
int a;
if (x > 0)
a = tablica2[y][zwroc_indeks(wartosci_tab[zmienna2], x)];
else
a = tablica4[y][x * (-1)];
if (a > najwieksza)
najwieksza = a;
}
the last element goes from 2 to -123781237 and it breaks my code
image

Expression must have a constant value, a variable can not be used as a constant for defining array size

I am trying to produce this code but have and error in the double functions starting at double b[n];. The error I am getting is saying that "the expression must have a constant value, the variable 'n' can not be used as a constant. Any help you can give would be much appreciated.
//Get inputs from user
double V = 0; // shear load applied
int n;
double H_total = 0;
double A_total = 0;
double a = 0;
double I = 0;
double t = 0;
double e = 0;
double y_bar = 0;
cout << "Input the shear load applied in [N]: " << endl;
cin >> V;
cout << "Input number of sections: " << endl;
cin >> n;
double b[n];
double h[n];
double A[n];
double y[n];
double Q[n];
double Tau[n];
for (int i = 1; i <= n; i++) { // Calculates variables to find shear stress
cout << "Width of section " << i << " in [mm]: " << endl;
cin >> b[i];
cout << "Height of section " << i << " in [mm]: " << endl;
cin >> h[i];
H_total += h[i];
A[i] = b[i] * h[i];
A_total += A[i];
y[i] = H_total - 0.5 * h[i];
a += A[i] * y[i];
y_bar = a / A_total;
}
cout << "Applied shear force, V = " << V / 1000 << " kN" << endl;
cout << "Y coordinate of the centroid for given cross section, Y_Bar = " << y_bar << " mm" << endl;
for (int i = 1; i <= n; i++) { // Finds moment of inertia
double d = (y[i] - y_bar);
I += (b[i] * pow(h[i], 3.0) / 12.0) + (A[i] * pow(d, 2.0));
}
cout << "Moment of Inertia, I = " << I << " mm^4" << endl;
for (int i = 1; i <= n; i++) { // Calculates first moment of inertia
Q[i] = A[i] * (y[i] - y_bar);
}
for (int i = 1; i <= n - 1; i++) {
if (b[i] <= b[i + 1]) {
t = b[i];
}
else {
t = b[i + 1];
}
Tau[i] = (abs(V * Q[i]) / (I * t));
}
for (int i = 1; i <= n - 1; i++) {
if (i <= 2) {
e += Tau[i];
}
else {
e -= Tau[i];
}
cout << "Shear stress between sections " << i << " and " << i + 1 << " = " << e << " MPa" <<
endl;
}
}
First of all double b[n]; is not a function, it is an array. This error is common with 2-D arrays. However, you aren't using any 2-D arrays here. Also, your code has no error unless you provide specific inputs which cause this error.
You can see the output for some random inputs:
Applied shear force, V = 0.004 kN
Y coordinate of the centroid for given cross section, Y_Bar = 3.29661 mm
Moment of Inertia, I = 322.476 mm^4
Shear stress between sections 1 and 2 = 0.147082 MPa
Shear stress between sections 2 and 3 = 0.231598 MPa

Comparisons in Multiple Sorting Algorithms

Currently this program will generate 10 random numbers and either sort (from least to greatest), reverse sort, or shuffle them. However, when trying to list the number of comparisons made, the number of comparisons printed out are completely incorrect. For example, it prints that there were 44 comparisons with bubble sort (this is the one that varies every time but is usually around 40), 45 with selection sort, and 9 with insertion sort. For now I'm only running the program with numbersSorted() just to make sure the comparisons work.
How can I print the correct number of comparisons made with each sorting method?
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int count1 = 0; //bubble
int count2 = 0; //selection
int count3 = 0; //insertion
vector<int> numbersSorted(int n);
vector<int> numbersReversed(int n);
vector<int> numbersShuffled(int n);
int main() {
srand(time(0));
numbersSorted(10);
//numbersReversed(10);
//numbersShuffled(10);
return 0;
}
vector<int> numbersSorted(int n)
{
vector <int> v(n);
for (auto &x : v)
x = rand() % 100;
cout << "Original list to be sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n\n";
// bubble sort
bool swapped = true;
for (int pass = 0; pass <= n - 2 && swapped; ++pass)
{
swapped = false;
for (int i = 0; i <= n - pass - 2; ++i)
{
++count1;
if (v.at(i) > v.at(i + 1))
{
swap(v[i], v[i + 1]);
swapped = true;
}
}
}
cout << "Bubble sort sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count1 << " comparisons with bubble sort.\n" <<
endl;
// selection sort
for (int pass = 0; pass <= n - 2; ++pass)
{
// Find least element remaining in the list starting at index pass
int minIndex = pass;
// i = minIndex + 1, minIndex + 1, ..., n - 1
for (int i = minIndex + 1; i < n; i++)
{
++count2;
if (v[i] < v[minIndex])
{
minIndex = i;
}
// The element at index i is smaller than what I thought was the
min
}
swap(v[pass], v[minIndex]);
}
cout << "Selection sort sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count2 << " comparisons with selection sort.\n" <<
endl;
//insertion sort
for (int pass = 0; pass <= n - 2; ++pass) {
// Take the element at pass+1 and move it to the left until it's in the
// right spot (i.e., as long as it's in the wrong spot).
// for i = pass, pass-1, ..., 0 while L[i] > L[i+1]
++count3;
for (int i = pass; i >= 0 && v[i] > v[i + 1]; --i) {
swap(v[i], v[i + 1]);
}
}
cout << "Insertion sort sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count3 << " comparisons with insertion sort.\n" <<
endl;
//return v;
}
vector<int> numbersReversed(int n)
{
vector <int> v(n);
for (auto &x : v)
x = rand() % 100;
cout << "Original list to be reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n\n";
// bubble sort
bool swapped = true;
for (int pass = 0; pass <= n - 2 && swapped; ++pass)
{
swapped = false;
for (int i = 0; i <= n - pass - 2; ++i)
{
++count1;
if (v.at(i) > v.at(i + 1))
{
swap(v[i], v[i + 1]);
swapped = true;
}
}
}
//reverse the content of the vector
reverse(v.begin(),v.end());
cout << "Bubble sort reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count1 << " comparisons with bubble sort.\n" <<
endl;
// selection sort
for (int pass = 0; pass <= n - 2; ++pass)
{
// Find least element remaining in the list starting at index pass
int minIndex = pass;
// i = minIndex + 1, minIndex + 1, ..., n - 1
for (int i = minIndex + 1; i < n; i++)
{
++count2;
if (v[i] < v[minIndex])
// The element at index i is smaller than what I thought was the
min
minIndex = i;
}
swap(v[pass], v[minIndex]);
}
reverse(v.begin(),v.end());
cout << "Selection sort reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count2 << " comparisons with selection sort.\n" <<
endl;
// insertion sort
for (int pass = 0; pass <= n - 2; ++pass) {
// Take the element at pass+1 and move it to the left until it's in the
// right spot (i.e., as long as it's in the wrong spot).
// for i = pass, pass-1, ..., 0 while L[i] > L[i+1]
++count3;
for (int i = pass; i >= 0 && v[i] > v[i + 1]; --i) {
swap(v[i], v[i + 1]);
}
}
reverse(v.begin(),v.end());
cout << "Insertion sort reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count3 << " comparisons with insertion sort.\n" <<
endl;
}
vector<int> numbersShuffled(int n)
{
vector<int> v(n);
for (auto &x : v)
{
x = rand() % 100;
++count1;
}
cout << "Numbers Shuffled: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count1 << " comparisons made. " << endl;
}

Error on the result vector

My problem is that when I make the multiplication it only multiplies the the first row of the matrix with the first element of the vector and the next elements makes them zero so the result vector gives a wrong result.
using namespace std;
#define N 100
#define F 3
#define X 7
__global__ void matvec(int *MAT, int *VEC, int *SOL) {
int bx = blockIdx.x;
int tx = threadIdx.x;
int i = 32*bx+tx;
for (int j = 0; j < X; j++) {
SOL[i] = ((MAT[i * X + j] * VEC[j]) +SOL[i]) % 2;
}
}
int main () {
int i, j;
int MAT[N][N], VEC[N], SOL[N];
int *MAT_dev, *VEC_dev, *SOL_dev;
size_t nBytes = X * X * sizeof(int);
cout << "\t- - - - - MATRIX - - - - -\n\n";
for (i = 0; i < X; i++) {
for (j = 0; j < X; j++) {
cout << "Element [" << i << "][" << j << "]: ";
cin >> MAT[i][j];
}
}
cout << endl << endl;
for (i = 0; i < X; i++) {
for (j = 0; j < X; j++) {
cout << MAT[i][j] << " ";
if (j == (X - 1))
cout << endl;
}
}
cout << endl << endl;
cout << "\t- - - - - VECTOR - - - - -\n\n";
for (i = 0; i < X; i++) {
cout << "Element [" << i << "]: ";
cin >> VEC[i];
}
cout << endl << endl;
for (i = 0; i < X; i++) {
cout << VEC[i] << " ";
}
cout << endl << endl;
cudaMalloc((void**)&MAT_dev, nBytes);
cudaMalloc((void**)&VEC_dev, nBytes);
cudaMalloc((void**)&SOL_dev, nBytes);
cudaMemcpy(MAT_dev, MAT, nBytes, cudaMemcpyHostToDevice);
cudaMemcpy(VEC_dev, VEC, nBytes, cudaMemcpyHostToDevice);
dim3 dimBlock(X,X);
dim3 dimGrid(1,1);
matvec<<<dimGrid,dimBlock>>>(MAT_dev, VEC_dev, SOL_dev);
cudaMemcpy(SOL, SOL_dev, nBytes, cudaMemcpyDeviceToHost);
cout << "\t- - - - - RESULT - - - - -\n\n";
for (i = 0; i < X; i++)
{
cout << SOL[i] << " ";
}
cout << endl << endl;
cudaFree(MAT_dev);
cudaFree(VEC_dev);
cudaFree(SOL_dev);
system("PAUSE");
return 0;
}
Thanks for the help
This is because the size of MAT is much larger than it should be. Basically you need N == X, which shouldn't be a problem because both are known at compile time. Memory for a 2D array is laid out in a single contiguous block, row major for C--so in your case the first row corresponds to the first 400 (sizeof(int)*N) bytes, the second row to the second 400, etc. The length of the row is called the 'stride' However, cudaMemcpy has no idea what the stride is or which elements of MAT have been filled in, it just copies the first nBytes bytes from MAT into MAT_DEV. Since nBytes is sizeof(int)*X*X and X == 7 << N the second and subsequent rows of your matrix never get copied. Only the first 196 bytes from the MAT get copied, explaining why your second row is all zeros.