Sum of 2d vector

Hi everyone. I'm a new to c++ programming. Given a task to calculate the total distance for each route. I had try to coded it but I had calculate the total distance manually. I would like to ask, is there any ways I could calculated it automatically without adding manually one by one. Really need help from someone. I cant figure it out how to do it automatically. Hopefully you understand what I'm trying to explain.

Here is the input file for 3 routes.
0 1 2 3 4 5 6 7 8 9 0
0 9 8 7 6 5 4 3 2 1 0
0 5 4 3 2 1 9 8 7 6 0

For example, route 0 start with 0 then 1, 2, 3, 4, 5, 6, 7, 8, 9 and return back to 0 as starting point.

Here is the input file for distance.
0 10.1843 9.29856 8.96788 9.12499 9.34745 9.49533 9.82055 9.97055 10.3772
10.1843 0 14.1696 14.6873 14.5624 14.4044 14.3381 14.1902 14.2204 14.0042
9.29856 14.1696 0 0.517772 0.392882 0.23489 0.196771 0.521997 0.671996 1.07866
8.96788 14.6873 0.517772 0 0.15711 0.379562 0.527443 0.852669 1.00267 1.40933
9.12499 14.5624 0.392882 0.15711 0 0.222452 0.370333 0.695559 0.845558 1.25222
9.34745 14.4044 0.23489 0.379562 0.222452 0 0.147881 0.473107 0.623106 1.02977
9.49533 14.3381 0.196771 0.527443 0.370333 0.147881 0 0.325226 0.475225 0.881889
9.82055 14.1902 0.521997 0.852669 0.695559 0.473107 0.325226 0 0.149999 0.556663
9.97055 14.2204 0.671996 1.00267 0.845558 0.623106 0.475225 0.149999 0 0.406664
10.3772 14.0042 1.07866 1.40933 1.25222 1.02977 0.881889 0.556663 0.406664 0

For example, distance from 0 to 1 is 10.1843. 1 to 2 is 14.1696 and so on.

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
59
60
61
62
63
64
65
66
67
68
69
#include <iostream> 
#include <vector> 
#include <iomanip>	// setw
#include <fstream>

using namespace std;

const int m = 3;
const int n = 11;
const int c = 10;

vector<vector<int> > route(m, vector <int>(n, 0));
vector<vector<long double> > dist(c, vector <long double>(c, 0));

int i, j;
long double totalDistance = 0;

int main()
{
	// Input file
	ifstream inpData("mydata.txt");
	ifstream inpDistance("mydistance.txt");

	// Assign route into array 
	cout << "The routes are: "; 
		cout << endl;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{
			inpData >> route[i][j];
			cout << setw(3) << route[i][j] << ' ';
		}
		cout << endl;
	}
	cout << endl;

	// Assign distance into array 
	cout << "The distances are: "; 
		cout << endl;
	for (i = 0; i < c; i++)
	{
		for (j = 0; j < c; j++)
		{
			inpDistance >> dist[i][j];
			cout << setw(10) << dist[i][j] << ' ';
		}
		cout << endl;
	}
	cout << endl;

	// Close input files
	inpData.close();
	inpDistance.close();

	cout << "Total distance for each route: "; 
		cout << endl;

	totalDistance = dist[0][1] + dist[1][2] + dist[2][3] + dist[3][4] + dist[4][5] + dist[5][6] + dist[6][7] + dist[7][8] + dist[8][9] + dist[9][0];
	cout << "Route 0" << " = " << totalDistance << endl;

	totalDistance = dist[0][9] + dist[9][8] + dist[8][7] + dist[7][6] + dist[6][5] + dist[5][4] + dist[4][3] + dist[3][2] + dist[2][1] + dist[1][0];
	cout << "Route 1" << " = " << totalDistance << endl;

	totalDistance = dist[0][5] + dist[5][4] + dist[4][3] + dist[3][2] + dist[2][1] + dist[1][9] + dist[9][8] + dist[8][7] + dist[7][6] + dist[6][0];
	cout << "Route 2" << " = " << totalDistance << endl;

	return 0;
}


The output should be:
Route 0 = 36.6582
Route 1 = 36.6582
Route 2 = 48.7958

Hoping for help from someone. Thank you.
you need a vector for the route, and then peel pairs off of it to look up in your table, in a running sum, in a loop.
for each of the pairs of elements in the route (overlapping pairs!)
0 1 2 3 4 5 6 7 8 9 0
[0][1] loop iteration 0
[1][2] loop 1
[2][3] loop 3
...
[8][9]
[9][0]

putting that all together its something like
for(route pairs)
total+= table[route[first++]][route[second++]];


Last edited on
For your case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int i = 0, j = 1;
	long double route1=0, route2=0, route3=0;
	for (int i = 0; i < 10; i++)
	{
		route1+= dist[i][j];
		route2 +=dist[j][i];
		
		if (i > 0 && i < 9 && j != 0)
			route3 +=dist[j][i];
++i; ++j;
		if (j == 10)//last iteration
			j = 0;
	}
	route3 = dist[0][5] + dist[6][0] + dist[1][9];
Last edited on
Hi Jonnin,

you need a vector for the route, and then peel pairs off of it to look up in your table, in a running sum, in a loop.


Did you mean, i need to create one additional vector for the pair of nodes for each route?

If yes, its difficult for me to create the additional vector of pair of nodes manually for each routes. Its because later on i need to run it on several bigger dataset involving up to 2000 nodes.

Its there any other ways I can do it, if i want to refer to only both input data (route and distance) to calculates the distance for each route.

Sorry for asking this, i really dont have idea how i supposed to do it.
Last edited on
You definitely do not need to do all of these manually. This kind of problem can be solved with a loop.
The fact that you are adding up the numbers manually tells me that you don't understand loops well enough yet to utilize them when needed.

Take a careful look at your "manual" coding. You should notice a pattern.
1
2
3
4
5
6
7
8
totalDistance = dist[0][1] + dist[1][2] + dist[2][3] + dist[3][4] + dist[4][5] + dist[5][6] + dist[6][7] + dist[7][8] + dist[8][9] + dist[9][0];
	cout << "Route 0" << " = " << totalDistance << endl;

	totalDistance = dist[0][9] + dist[9][8] + dist[8][7] + dist[7][6] + dist[6][5] + dist[5][4] + dist[4][3] + dist[3][2] + dist[2][1] + dist[1][0];
	cout << "Route 1" << " = " << totalDistance << endl;

	totalDistance = dist[0][5] + dist[5][4] + dist[4][3] + dist[3][2] + dist[2][1] + dist[1][9] + dist[9][8] + dist[8][7] + dist[7][6] + dist[6][0];
	cout << "Route 2" << " = " << totalDistance << endl;


Here's a couple of observations that I made.

Given dist[i][j],
1. j is always the route number
2. i is always the route number from the previous dist unless it's the first dist - then it's 0.


With just 2 points above, I came up with this loop. This loop should print the same answer as your manual coding.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    // Iterate route rows
    for(int routeRow = 0; routeRow < route.size(); routeRow ++) {
        // Initialize totalDistance after each route row iteration
        double totalDistance = 0;

        // Store the next route number
        int nextRoute = 0;

        for(int routeCol = 0; routeCol < route[routeRow].size(); routeCol++) {
            // Accumulate distance
            totalDistance += dist[nextRoute][route[routeRow][routeCol]];

            // Set the next route (The row index of dist)
            nextRoute = route[routeRow][routeCol];
        }

        // Print output for each route row
        std::cout << "Route " << routeRow << " = " << totalDistance << std::endl;
    }

Make sure you analyze this loop thoroughly and try to understand how it works. Ask any questions you may have. Once you understand it, you can even try to optimize it or find a different way to solve the problem.


I will give you some tips for loops.

1. There is no rule that says index always has to be named i or j in the for-loop. You can give it a more descriptive name if it helps you. If you look at my above code, I use routeRow and routeCol. Since we are dealing with 2D array, it helps to clearly identify which index is for the row and which index is for the column, hence the names.

2. Write a pseudocode and loop a small example array on a piece of paper.
You can come up with very small arrays (2 x 2) and iterate the array items on paper before you write the actual code. If you can get the loop logic to work with a small example, you will likely get it to work with bigger and realistic examples as well. At least, this should give you an idea of how to implement the loop.

3. Just practice. For any programmers, their first encounter with loops or recursion (Look this up if you don't know what it is) was probably a very confusing and humbling experience. But if you keep practicing loops and recursion, you will get the hang of them.
Last edited on
you need a vector that has the route. you don't need the pairs specifically because you can iterate the vector in a way that gives them.

look.

vector <int> route = {3,4,5,0};
int f = 0;
int s = 1;
table[route[f++]][route[s++]]; resolves to table[3][4], and f = 1 s = 2 now.
table[route[f++]][route[s++]]; resolves to table[4][5], and f = 2, s = 3 now..
loop that pattern. add up the result.

edit changed route index to avoid happenstance confusion





Last edited on
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
#include <iostream>
#include <vector>

using distance_vec = std::vector< std::vector<double> > ;

double route_length( const std::vector<std::size_t>& route, const distance_vec& distance )
{
    double length = 0 ;
    
    // for each position i in the route up to the last but one position
    for( std::size_t i = 0 ; i < (route.size()-1) ; ++i )
    {
        // add the distance between the location at this position 
        // and the location at the next position in the route
        // note: we use at() rather than [] to defend against invalid data
        length += distance.at( route[i] ).at( route[i+1] ) ;
    }

    return length ;
}

int main()
{
    const std::vector< std::vector<std::size_t> > routes
    {
        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 },
        { 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
        { 0, 5, 4, 3, 2, 1, 9, 8, 7, 6, 0 },
        { 0, 5, 4, 3, 2, 1, 99, 8, 7, 6, 0 } // invalid route
    };

    const distance_vec distances
    {
        { 0, 10.1843, 9.29856, 8.96788, 9.12499, 9.34745, 9.49533, 9.82055, 9.97055, 10.3772 },
        { 10.1843, 0, 14.1696, 14.6873, 14.5624, 14.4044, 14.3381, 14.1902, 14.2204, 14.0042 },
        { 9.29856, 14.1696, 0, 0.517772, 0.392882, 0.23489, 0.196771, 0.521997, 0.671996, 1.07866 },
        { 8.96788, 14.6873, 0.517772, 0, 0.15711, 0.379562, 0.527443, 0.852669, 1.00267, 1.40933 },
        { 9.12499, 14.5624, 0.392882, 0.15711, 0, 0.222452, 0.370333, 0.695559, 0.845558, 1.25222 },
        { 9.34745, 14.4044, 0.23489, 0.379562, 0.222452, 0, 0.147881, 0.473107, 0.623106, 1.02977 },
        { 9.49533, 14.3381, 0.196771, 0.527443, 0.370333, 0.147881, 0, 0.325226, 0.475225, 0.881889 },
        { 9.82055, 14.1902, 0.521997, 0.852669, 0.695559, 0.473107, 0.325226, 0, 0.149999, 0.556663 },
        { 9.97055, 14.2204, 0.671996, 1.00267, 0.845558, 0.623106, 0.475225, 0.149999, 0, 0.406664 },
        { 10.3772, 14.0042, 1.07866, 1.40933, 1.25222, 1.02977, 0.881889, 0.556663, 0.406664, 0 }
    };

    for( std::size_t i = 0 ; i < routes.size() ; ++i )
    {
        std::cout << "route #" << i+1 << "  length == " ;
        
        try { std::cout << route_length( routes[i], distances ) << '\n' ; }
        catch( const std::out_of_range& ) { std::cout << "  *** error: invalid route\n" ; }
    }

}

http://coliru.stacked-crooked.com/a/8dc40f6285a579be
Hi mpark4656, thanks a lot for your help and patience in teaching me. To be honest, I like the way you to teach me in order to solve this problem where I could understand it. I had learn a new knowledge from you regards to loops. It almost 3 months I learned about c++ programming. And it look like there is a lot more I need to study. I will keep doing practice to familiarize with it. Once again, thanks and really appreciated.

Hijonnin and JLBorges, thanks for your help. Most appreciated.
Topic archived. No new replies allowed.