Combination of point coordinates from limit values

Hello
I have an lower and upper limit values of n dimension coordinate system, like
[2,5,8]- lower and [6,12,16] - upper for 3 dim. I want to get points from those limit values like [2,5,8],[6,5,8],[6,12,8],[6,5,16] ... and goes on in total there must be 2^n points.
How should do with recursion in C++??

Thnks:)
why recursion?

A point is 'inside' the limits if all the values in the random point are between the upper and lower for the same position, right?
so you need [{2..6}, {5..12}, {8..16} ] (inclusive) in your example.

you can randomly generate these, using <random>, or you can divide it up evenly and iterate a 'grid' of points, or something like that. Being iteration, you *could* make it recursive if you wanted to do so, but recursion does not appreciably shorten the code or bring anything to the table except an extra layer of convolution.

so something like..
- make a little struct of <random> bits, one for each dimension, packed into a vector..
then, in pseudocode:
for(all the points you need)
for(each coordinate)
{
point[which][coordinate] = random_vec[coordinate].distribution(generator);
}

or with recursion (still pseudocodeish) the simple way (you can probably make this cute and small and hard to follow if you want to, and eliminate some parameters with statics, if you only call the function once)

void wtf(point, random_vec, which, int count, const int n)
{
if(count == n) return;
for(each coordinate)
{
point[which][coordinate] = random_vec[coordinate].distribution(generator);
}
wtf(point, random_vec, which+1, count+1, n);
}

you don't 'have' to make a generator for each dimension, but that save a lot of tracking the upper and lower bounds for each one and adjusting a random value to fit between them for each one etc. Its easier to let the generator do that work for you for each one.
** I treated n as if it were already expanded to 2^n, if you want to put the power computation inside the logic here you can.
Last edited on
actually this is also good, I was not looking for between values , just the coordinates of limit points. So, limits have big difference (bettwen up and low) in my code and I do not want to generate random numbers between.them because the code will run lot of times and speed is important
I think he just wants to enumerate the corner points of the bounding (hyper-)cube. That's why there's 2^n of them. Also, recursion makes more sense with this interpretation.
This is pretty basic, but perhaps something like this:

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
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

// pre: a.size() == b.size()
void ff(const vector<int>& a, const vector<int>& b, vector<int>& c) {
    if (c.size() == a.size()) {
        for (int x: c) cout << setw(4) << x << ' ';
        cout << '\n';
    }
    else {
        c.push_back(a[c.size()]);  ff(a, b, c);  c.pop_back();
        c.push_back(b[c.size()]);  ff(a, b, c);  c.pop_back();
    }
}

void f(const vector<int>& a, const vector<int>& b) {
    vector<int> c;
    ff(a, b, c);
}

int main() {
    vector<int> a{1, 2, 3, 4}, b{10, 20, 30, 40};
    f(a, b);
}

If it's only ever going to be the ends of the interval then each dimension will be isomorphic to {0,1}, so you might as well just count upwards and map the relevant bits to the ends of their interval.
@dutch Oh nice, I could not say that I totally understood, how it works after first pop.back ??
Last edited on
How does it works??
Forget about the stack frame. It's uninteresting in this code since we pass the exact same references for the arguments every time.

Focus instead on the contents of c for each call to ff. Suppose main was

1
2
    vector<int> a{1, 2, 3}, b{10, 20, 30};
    f(a, b);

Then the calls to ff would be (with indentation level showing the recursion level):

ff(a, b, {})
    ff(a, b, {1})
        ff(a, b, {1,2})
            ff(a, b, {1,2,3})
                <print>
            ff(a, b, {1,2,30})
                <print>
        ff(a, b, {1,20})
            ff(a, b, {1,20,3})
                <print>
            ff(a, b, {1,20,30})
                <print>
    ff(a, b, {10})
        ff(a, b, {10,2})
            ff(a, b, {10,2,3})
                <print>
            ff(a, b, {10,2,30})
                <print>
        ff(a, b, {10,20})
            ff(a, b, {10,20,3})
                <print>
            ff(a, b, {10,20,30})
                <print>
thanks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

int main()
{
   vector<int> first{ 1, 2, 3, 4 }, last{ 10, 20, 30, 40 };
   int N = first.size();
   for ( int i = 0; i < ( 1 << N ); i++ )
   {
      for ( int j = 0; j < N; j++ ) cout << setw( 4 ) << ( ( 1 << j ) & i ? last[j] : first[j] );
      cout << '\n';
   }
}
The OP question has two n-dimensional points and seems to assume that they are "opposing" vertices of cuboid* (in 3D), rectangle (in 2D), etc that have their edges are parallel to axes of the frame of reference. The task seems to be to list all vertices of said shape.


* https://en.wikipedia.org/wiki/Cuboid

It looks like half then half then half . . . either way.
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

#include<vector>
#include<iostream>
#include<cmath>
#include <iomanip>

using namespace std;

using MATRIX =	vector<vector<double>>;

MATRIX create(vector<double> a,vector<double> b)
{
MATRIX answer;
int p=pow(2,a.size()),tog;
answer.resize(p,vector<double>(a.size()));
int g=p;
for(int m=0;m<a.size();m++)
{
	tog=-1;
	g=(int)g/2;//keep halfing
	for(int n=0;n<p;n++)
	{
		if((n % g)==0) tog=-tog;
		if(tog==1)  answer[n][m]=a[m];
		else        answer[n][m]=b[m];
	}
}
return answer;
}


void print (MATRIX M)
{
	for (int n=0;n<M.size();n++)
	{
	for(int m=0;m<M[0].size();m++)
	{
		cout<<setw(4)<<M[n][m];
	}
	cout<<endl;
}
cout<<endl;
}

int main()
{
vector<double> a={1,2,3};
vector<double> b={10,20,30};
MATRIX result=create(a,b);
print(result);

a.clear();
b.clear();
result.clear();
a={1, 2, 3, 4};
b={10, 20, 30, 40};
 result=create(a,b);
print(result);
system("pause");

}
 

Last edited on
Topic archived. No new replies allowed.