What's wrong in my small code ?

In the following code, I am trying to assign the sum to the cost_temp[i][k]. When I comment the line :
cost_temp[i][k] = h_sum + P_sum + f[Period[k]]
the code works well. When I assign the values, and tried to print them , even the line
cout << "cost="<< Opt_cost[k] + h_sum + P_sum + f[Period[k]]<< endl;
does not print anything while it was printing when the previous line is commented. What's wrong here ? Thank you so much for your ideas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include<fstream>
#include <vector>

using namespace std;

int main()
{
    vector<vector<double>>cost_temp;
    vector<int> Period;
    vector<int> First;
	
    	
	vector<double> D= { 20, 30, 40, 50, 60 };
	vector<double>f = { 20, 30, 40, 10, 40 };
	vector<double>h = { 2, 4 ,2 ,4, 2 };
	vector<double>c = { 5, 10, 15, 6 ,10 };


	Period = { 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4 };
	First = { 0, 1, 3, 11, 13 };
	vector<int>Opt_cost(14);
	

	Opt_cost[0] = 0;
	
	for (int i = 1; i < 14; i++)
	{
		
		for (int k = 0; k < First[Period[i]]; k++)
		{
			
			double sum = 0;
			double P_sum = 0;
			for (int kk = Period[k]; kk < Period[i]; kk++)
				sum += D[kk];
			
			double h_sum = 0;
			P_sum = c[Period[k]] * sum;
			
		
			for (int kk = Period[k]; kk < Period[i]; kk++)
			{
				h_sum = h_sum + h[kk] * (sum - D[kk]); 
				sum = sum - D[kk];
			}
			
		 //   cost_temp[i][k] = h_sum + P_sum + f[Period[k]];
			cout << "cost="<< Opt_cost[k] + h_sum + P_sum + f[Period[k]]<< endl;
						
		}
	} 

	

    return 0;
}
cost_temp has no memory. uncommenting the line gives undefined behavior, you need a reserve or initial size or push_back or the like.
Thank you so much @jonnin. I thought that might cause a problem. However, the the size of cost_temp can change whenever I call this function . So, it is not possible to define a initial size. That's why I have defined it as vector<vector<double>>cost_temp. How can I fix it in this case ? Thank you so much
push_back seems likely here.
vectors are dynamic. Its best if you can get their size right or close to it up front, but if you can't do that, they will grow to fit using push_back or similar tools. Take a look at vector's docs for all the methods for yourself, as its good to be familiar with what it has.

remember to handle BOTH dimensions! eg 2 for loops, inner and outer, push back a row every outer loop and push back columns every inner loop is a simple way to do it.
Last edited on
Thank you so much @jonnin. Actually, I was going to ask that part. In push_back documentations generally one dimension vector is declared like vector<double>v; and they say v. push_back(value). I could not find any example with both dimensions with push_back. How can I implement it in my given code or do you have any example in hand ? Sorry, I am quite beginner in c++. Thank you so much
here is an example of the syntax, 2 versions that likely fit what you need.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

int main()
{
  vector< vector<double> > v;
  v.push_back(vector<double>(10)); //push back a row with 10 columns.
  v[0][8] = 42.24;
  
  v.push_back(vector<double>{}); //push back an empty row
  v[1].push_back(12.34);  //push a column into the empty row...
  
  cout << v[0][8] << endl << v[1][0] << endl;
  
}
  


it really works the same in 2d as 1d. it looks weird because you are pushing back vector objects which in turn are templates, making the syntax a bit mind blowing the first couple of times you see it. But its no different than

vector<int> x;
x.push_back(int{}); //pushes back a defaulted int value of zero
or
x.push_back(value);//push back a variable
or x.push_back(19); //push back a constant int.
and so on. the fact that you are pushing back a vector at the outer level is interesting syntax but its the same thing, once you see past the template/type part into what its really doing. If you studied C style strings, its similar to how you finally make that connection that a 2d array of characters is a one-d array of strings. Here, its a one-d vector of vector objects.
Last edited on
There are a couple of ways to create and fill 2D containers such as a vector. One way is what jonnin explains. Create a no memory blank vector and then create on the fly each row by pushing back the column elements into a temp 1D vector and then push that temp row back into your 2D vector.

OR

Create a 2D vector with known values in an initializer list:
std::vector<std::vector<int>> vec2D { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
C++11 or later.

OR

Figure out the number of rows and columns your 2D vector will contain and then instantiate your vector with the known sizes with the elements being default initialized. Replacing the default element values is as easy as doing to with a 2D array.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <vector>
#include <numeric>

int main()
{
   const unsigned row_size { 3 };
   const unsigned col_size { 4 };

   // create a 2 dimensional int vector with known dimensions
   std::vector<std::vector<int>> aVector(row_size, std::vector<int>(col_size));

   std::cout << "Let's verify the sizes of the 2D vector....\n";
   std::cout << "The vector has " << aVector.size() << " rows.\n";
   std::cout << "The vector has " << aVector[ 0 ].size() << " columns.\n\n";

   // display the empty 2D vector
   std::cout << "Displaying the empty 2D vector:\n";
   for ( unsigned rows { }; rows < aVector.size(); ++rows )
   {
      for ( unsigned cols { }; cols < aVector[ rows ].size(); ++cols )
      {
         std::cout << aVector[rows][cols] << ' ';
      }
      std::cout << '\n';
   }
   std::cout << '\n';

   std::cout << "Initializing the 2D vector with some values....\n";
   // initialize the vector with some values other than zero
   int start  = 101;
   int offset = 100;

   for ( auto& itr : aVector )  // remember the &!!!!!!!!!!!!!!!!!!!!!
   {
      std::iota(itr.begin(), itr.end(), start);
      start += offset;
   }

   // let's display the filled 2D vector
   std::cout << "Displaying the filled 2D vector:\n";
   for ( const auto& rows : aVector )
   {
      for ( const auto& cols : rows )
      {
         std::cout << cols << ' ';
      }
      std::cout << '\n';
   }
}
Let's verify the sizes of the 2D vector....
The vector has 3 rows.
The vector has 4 columns.

Displaying the empty 2D vector:
0 0 0 0
0 0 0 0
0 0 0 0

Initializing the 2D vector with some values....
Displaying the filled 2D vector:
101 102 103 104
201 202 203 204
301 302 303 304


https://coderslegacy.com/c/initialize-vector-initializer-list-cpp/
Last edited on
An example of "push back as you go" with an initially empty 2D vector:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <vector>
#include <numeric>

int main()
{
   const unsigned row_size { 3 };
   const unsigned col_size { 4 };

   // create a 2 dimensional int vector with known dimensions
   std::vector<std::vector<int>> aVector;

   std::cout << "Let's verify the sizes of the 2D vector....\n";
   std::cout << "The vector has " << aVector.size() << " rows.\n\n";

   for ( unsigned rows { }; rows < row_size; ++rows )
   {
      std::vector<int> temp;

      for ( unsigned cols { }; cols < col_size; ++cols )
      {
         temp.push_back((100 * (rows + 1)) + (cols + 1));
      }

      aVector.push_back(temp);
   }

   // let's display the filled 2D vector
   std::cout << "Displaying the filled 2D vector:\n";
   for ( const auto& rows : aVector )
   {
      for ( const auto& cols : rows )
      {
         std::cout << cols << ' ';
      }
      std::cout << '\n';
   }
}
Let's verify the sizes of the 2D vector....
The vector has 0 rows.

Displaying the filled 2D vector:
101 102 103 104
201 202 203 204
301 302 303 304

If a 2D vector has zero rows it will automatically have zero columns, can't programmatically determine there are zero columns.
We can avoid the creation, copy and destruction of a temporary vector (relevant if the dimensions are large).

1
2
3
4
5
6
7
8
const auto value_at = []( std::size_t row, std::size_t col ) { return int( 100*row + col + 101 ) ; };

for( std::size_t row = 0 ; row < NROWS ; ++row )
{
    mtx.resize(row+1); // add an empty row
    // add NCOLS items to the row that was just added
    for( std::size_t col = 0; col < NCOLS; ++col ) mtx.back().push_back( value_at(row,col) );
}


Alternatively, move temp into the matrix: aVector.push_back( std::move(temp) ) ;
Possibly something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <vector>

int main() {
	const std::vector<double> D { 20, 30, 40, 50, 60 };
	const std::vector<double> f { 20, 30, 40, 10, 40 };
	const std::vector<double> h { 2, 4 ,2 ,4, 2 };
	const std::vector<double> c { 5, 10, 15, 6 ,10 };
	const std::vector<int> Period { 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4 };
	const std::vector<int> First { 0, 1, 3, 11, 13 };
	std::vector<int> Opt_cost(14);
	std::vector<std::vector<double>> cost_temp { Period.size() };

	for (size_t i { 1 }; i < Period.size(); ++i) {
		cost_temp[i].resize(First[Period[i]]);

		for (int k {}; k < First[Period[i]]; ++k) {
			double sum {};

			for (auto kk { Period[k] }; kk < Period[i]; ++kk)
				sum += D[kk];

			const double P_sum { c[Period[k]] * sum };
			double h_sum {};

			for (auto kk { Period[k] }; kk < Period[i]; ++kk) {
				h_sum += h[kk] * (sum - D[kk]);
				sum -= D[kk];
			}

			cost_temp[i][k] = h_sum + P_sum + f[Period[k]];
			std::cout << "cost=" << Opt_cost[k] + h_sum + P_sum + f[Period[k]] << '\n';
		}
	}
}

Last edited on
Thank you so much all of you @seeplus, @JLBorges, @George P @jonnin. All your examples and explanations helped me su much. I had difficulties with the syntax of push_back when I need to use it for different cases. There are documentations in the internet but mostly calssical case is given as example so I had struggled a bit, so you you helped me a lot.
Millions of thanks
Topic archived. No new replies allowed.