generate data set form members of different arrays or vectors

Dear Friends,
I am a newcomer of C++ programming, I have a problem:
I have 9 sets of numbers that each of them include different numbers for example:
set 1: 10 11 12
set 2: 21 22 23 24 25
set 3: 34 35 36
set 4: 40 41 42 43 44 45 46 45 47 48 49
set 5: 50 51
set 6: 60 61 62 63
set 7: 71 72 73 74
set 8: 81
set 9: 91 92 93
now, I want to create for example 20 sets that include one non repeating of elements of each set randomly (and if it is possible without repeating), such as:
newset 1: 11 22 34 40 50 63 72 81 92
newset 2: 10 21 36 44 51 62 71 81 93
newset 3: 12 25 35 49 51 61 73 81 91
newset 4: 10 24 35 47 50 60 74 81 92
..
..
up to 20 or more as it is possible. Please note that newset1#newset2 or other newsets.
Is there anyone can help me?
Also, I wrote a code that read each set data from an input txt file, and record them as vector and also 2D array, but I do not know what should I do for continuing the code!
Thanks a lot
Morteza
Last edited on
What have you done so far? Show what you have.

Also be specific about the part or parts that you need help with.
this is my code that reads input file and put the numbers in vectors or arrays,
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <conio.h>
#include <algorithm>
#include <iterator>
#include <ctime>
#include <string>

using namespace std;

int main()
{
vector < vector < double > > info;
ifstream file("C:\\tmp\\random_permutation\\input_permutation.txt");
string line;
while ( getline(file, line) )
{
vector < double > data;
double value;
istringstream iss(line);
while (iss >> value)
{
data.push_back(value);
}
info.push_back(data);
}

for ( vector < vector < double > > :: size_type i = 0, size = info.size(); i < size; ++i)
{
cout << "line " << i + 1 << ": ";
for ( vector < double > :: size_type j = 0, length = info.size(); j < length; ++j)
{
cout << info[i][j] << " ";
}
cout << endl;
}
int Number_of_DV=info[0][0];
int Number_of_needed_sets=info[1][0];
cout<<" Number of DV is "<<Number_of_DV<<" number of sets that we need to be generated "<<Number_of_needed_sets<< endl;
int size_of_DV_set[100];

for (int i=1;i<=Number_of_DV;i++)
{
size_of_DV_set[i]=info[i+1].size();
cout<<"size_of_DV_set[ "<<" "<<i<< " ] "<<size_of_DV_set[i]<<" "<<endl;
}
cout<<endl<<endl;

double DV[100][100];
for (int i=1;i<=Number_of_DV;i++)
{
for (int j=1;j<=size_of_DV_set[i];j++)
{
DV[i][j]=info[i+1][j-1];
cout<<DV[i][j]<<" ";
}
cout<<endl;
}

srand(time(NULL));
for (int l=1;l<=Number_of_needed_sets;l++)
{

int rand_index=rand()%size_of_DV_set[1];
cout<<DV[1][rand_index]<<endl;
}




file.close();
system("pause");
return (0);

}

[i][i][b]and this is the input file
:
[/i][/b]
8 number of DV (design variables)
15 number of sets that we need to be generated from each set of DV's 11 to 19 are the DV1, 21 to 25 are DV2, ... we need to pick one value of DV1,DV2,.. and create set#1 to set#15 randoly
11 12 13 14 15 16 17 18 19
21 22 23 24 25
31 32 33 34 35 36 37
41 42 43 44
50 51 52 53 54 55 56 57 58 59
61 62
71 72 73
80 81 82 83 84 85 86

now based on my last message, I need to generate other sets based on each set of the input file. I mean that the new set should be constructed by one number of each set, and at all of the numbers of each set should be used. for example the new sets should be:
[b]newset 1: 11 22 34 40 50 63 72 81 92
newset 2: 10 21 36 44 51 62 71 81 93
newset 3: 12 25 35 49 51 61 73 81 91
newset 4: 10 24 35 47 50 60 74 81
92[/b]
and each one of these newsets should be recorded in vectors or arrays to make output or other data processing.
thanks
input_permutation.txt contains:
8 number of DV (design variables)
15 number of sets that we need to be generated from each set of DV's 11 to 19 are the DV1, 21 to 25 are DV2, ... we need to pick one value of DV1,DV2,.. and create set#1 to set#15 randoly
11 12 13 14 15 16 17 18 19
21 22 23 24 25
31 32 33 34 35 36 37
41 42 43 44
50 51 52 53 54 55 56 57 58 59
61 62
71 72 73
80 81 82 83 84 85 86
Pure brute force:

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
#include <vector>
#include <cassert>
#include <algorithm>

typedef std::vector<double> data_set ;

std::vector<data_set> create_sets( std::vector<data_set> input_sets, std::size_t nsets )
{
    assert( !input_sets.empty() ) ;
    std::vector<data_set> result_sets ;

    for( data_set& vec : input_sets )
    {
        assert( !vec.empty() ) ;
        const data_set cpy = vec ;
        while( vec.size() < nsets ) vec.insert( vec.end(), cpy.begin(), cpy.end() ) ;
        std::random_shuffle( vec.begin(), vec.end() ) ;
    }

    for( std::size_t i = 0 ; i < nsets ; ++i )
    {
        data_set this_set ;
        for( std::size_t j = 0 ; j < input_sets.size() ; ++j )
              this_set.push_back( input_sets[j][i] ) ;
        result_sets.push_back(this_set) ;
    }

    return result_sets ;
}
Thanks JLBorges,
How can I add this part of code to my basic code?
where it should be added in my code?
I really appreciate your reply.
std::vector<data_set> create_sets( std::vector<data_set> input_sets, std::size_t nsets )
is a function. Just call it.

Typical usage:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
    // intialize input sets (in your case by reading from a file)
    std::vector<data_set> info = { {10,11,12}, {21,22,23,24,25}, {34,35,36},
                                   {40,41,42,43,44,45,46,47,48,49},
                                   {50,51,52,53,54}, {60,61,62,63}, {71,72},
                                   {80,81,82,83,84,85,86} } ;

    enum { NUM_SETS_TO_CREATE = 9 } ; // number of sets to create

    // create the sets
    std::srand( std::time(0) ) ;
    std::vector<data_set> result = create_sets( info, NUM_SETS_TO_CREATE ) ;

    // print them out
    for( const data_set& d : result )
    {
        static int cnt = 0 ;
        std::cout << ++cnt << ". [ " ;
        for( int v : d ) std::cout << v << ' ' ;
        std::cout << "]\n" ;
    }
}

Output for one run:
1. [ 12 25 36 48 54 61 71 84 ]
2. [ 11 21 35 49 53 60 71 86 ]
3. [ 12 23 35 42 52 62 72 86 ]
4. [ 12 22 34 46 53 63 72 82 ]
5. [ 10 24 36 41 51 62 71 85 ]
6. [ 11 25 35 45 50 63 71 80 ]
7. [ 11 23 34 44 50 62 72 80 ]
8. [ 10 24 36 47 54 61 72 85 ]
9. [ 10 21 34 40 51 63 71 81 ]


Note: If your compiler does not have support for range-based for loops, you will have to change those to classical for loops.
Last edited on
Thanks a lot JLBorges,

I want to read vector directly in my code, I do not want to write:
std::vector<data_set> info = { {10,11,12}, {21,22,23,24,25}, {34,35,36},
{40,41,42,43,44,45,46,47,48,49},
{50,51,52,53,54}, {60,61,62,63}, {71,72},
{80,81,82,83,84,85,86} } ;
I want my code read data from vector info as it read them before, what should I do?
this helps me to automatically :
1- Read data from the input file
2-put them in vectors or arrays
3-generate the output

Thanks bro you saved me.
did you use any library that I need to call it?
because I have problem with some parts of the code. I modified my code as:




#include "stdafx.h"
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <conio.h>
#include <algorithm>
#include <iterator>
#include <ctime>
#include <string>
#include <cassert>


using namespace std;

typedef std::vector<double> data_set ;

std::vector<data_set> create_sets( std::vector<data_set> input_sets, std::size_t nsets )
{
assert( !input_sets.empty() ) ;
std::vector<data_set> result_sets ;

for( data_set& vec : input_sets )
{
assert( !vec.empty() ) ;
const data_set cpy = vec ;
while( vec.size() < nsets ) vec.insert( vec.end(), cpy.begin(), cpy.end() ) ;
std::random_shuffle( vec.begin(), vec.end() ) ;
}

for( std::size_t i = 0 ; i < nsets ; ++i )
{
data_set this_set ;
for( std::size_t j = 0 ; j < input_sets.size() ; ++j )
this_set.push_back( input_sets[j][i] ) ;
result_sets.push_back(this_set) ;
}

return result_sets ;
}
int main()
{

vector < vector < double > > info;
ifstream file("C:\\tmp\\random_permutation\\input_permutation.txt");
string line;
while ( getline(file, line) )
{
vector < double > data;
double value;
istringstream iss(line);
while (iss >> value)
{
data.push_back(value);
}
info.push_back(data);
}

for ( vector < vector < double > > :: size_type i = 0, size = info.size(); i < size; ++i)
{
cout << "line " << i + 1 << ": ";
for ( vector < double > :: size_type j = 0, length = info[i].size(); j < length; ++j)
{
cout << info[i][j] << " ";
}
cout << endl;
}
int Number_of_DV=info[0][0];
int Number_of_needed_sets=info[1][0];
cout<<" Number of DV is "<<Number_of_DV<<" number of sets that we need to be generated "<<Number_of_needed_sets<< endl;
int size_of_DV_set[100];

for (int i=1;i<=Number_of_DV;i++)
{
size_of_DV_set[i]=info[i+1].size();
cout<<"size_of_DV_set[ "<<" "<<i<< " ] "<<size_of_DV_set[i]<<" "<<endl;
}
cout<<endl<<endl;

double DV[100][100];
for (int i=1;i<=Number_of_DV;i++)
{
for (int j=1;j<=size_of_DV_set[i];j++)
{
DV[i][j]=info[i+1][j-1];
cout<<DV[i][j]<<" ";
}
cout<<endl;
}

srand(time(NULL));
for (int l=1;l<=Number_of_needed_sets;l++)
{

int rand_index=rand()%size_of_DV_set[1];
cout<<DV[1][rand_index]<<endl;
}

// intialize input sets (in your case by reading from a file)
std::vector<data_set> info;

enum { NUM_SETS_TO_CREATE = 9 } ; // number of sets to create

// create the sets
std::srand( std::time(0) ) ;
std::vector<data_set> result = create_sets( info, NUM_SETS_TO_CREATE ) ;

// print them out
for( const data_set& d : result )
{
static int cnt = 0 ;
std::cout << ++cnt << ". [ " ;
for( int v : d ) std::cout << v << ' ' ;
std::cout << "]\n" ;
}


file.close();
system("pause");
return (0);

}

Thank bro
Have you made an effort to understand what the function create_sets() does? And precisely how it does that?

If you haven't, you don't have anything to thank me for - you have gained nothing from all this. And I've just wasted my time.
Pleas don't be angry, man. I copy and pastes your codes but I got some errors, and the code did not work.
As I said, I am a beginner, I am a mechanical engineer not programmer. So I know about C++ not very deep, and to use some function I need to first of all check the functionality. When I copied and pasted your codes, I got problem. Then I used them in my code but it didn't work. So, please advise me what I should do.
Sometimes, a work seems simple for you but it is not simple for other so please be patient and advise others.
BTW, I appreciate your help because I thought that I need to switch to MATLAB or other programming language, but your posted results shows C++ can handle my problem.
I thank you else you do not reply and help me again, man.
Best Regards
> I copy and pastes your codes but I got some errors, and the code did not work. ...
> So, please advise me what I should do.

First, try and understand the code that you copied and pasted.


> Then I used them in my code but it didn't work.

You need to be much more specific than 'but it didn't work'. What is the precise error that yo got? Is it a compile-time error? If so what is the compiler error diagnostic?



> thank you else you do not reply and help me again, man.

I will always reply to a question, try to help, if I perceive that it was asked as a part of a genuine effort to learn something.



Anyway, here is the code again - modified to read the data from a file, and with range-based for loops translated. With a fair amount of annotations thrown in to help you try and understand what it is all about.

Go through this. If in the end you understand it, and can explain what it does and how it does what it does; you can modify it on your own if the need arises; you have made it your code instead it remaining as my code, I would be very gratified.

If you haven't made an effort to do that, please don't thank me - that would be adding insult to injury.

Caveat: obviously untested code.

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <vector>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <ctime>
#include <fstream>
#include <sstream>

typedef std::vector<double> data_set ; // are these real numbers? or should it be int?

// function to create the result data sets
// input_sets - the input data sets from which values have to be picked
// nsets - the number of output sets that we need to generate
std::vector<data_set> create_sets( std::vector<data_set> input_sets, std::size_t nsets )
{
    assert( !input_sets.empty() ) ;
    std::vector<data_set> result_sets ;

    for( std::size_t i = 0 ; i < input_sets.size() ; ++i )
    {
        data_set& vec = input_sets[i] ;
        assert( !vec.empty() ) ;

        // make the size of the data set sufficiently large ( >= nsets )
        // so that we need not fear that there may be no more values in the sequence
        // we do this by appending additional copies of the values to the data set
        const data_set cpy = vec ;
        while( vec.size() < nsets ) vec.insert( vec.end(), cpy.begin(), cpy.end() ) ;

        // randomly shuffle the elements in the set randomly so that
        // we can go through the sequence from beginning to end, in order,
        // and the value we pick up would be a randomly chosen value
        std::random_shuffle( vec.begin(), vec.end() ) ;
    }

    for( std::size_t i = 0 ; i < nsets ; ++i ) // create n result sets
    {
        data_set this_set ; // data set # i

        // pick up the value at position 'i' from each sequence in turn
        // and add it to data set # i. the value at position 'i'
        // is a randomly chosen one - we had shuffled the sequence earlier
        for( std::size_t j = 0 ; j < input_sets.size() ; ++j )
              this_set.push_back( input_sets[j][i] ) ;

        // add data set # i to the result set
        result_sets.push_back(this_set) ;
    }

    return result_sets ;
}

int main()
{
    std::ifstream file( "C:\\tmp\\random_permutation\\input_permutation.txt" ) ;

    std::size_t number_of_dv ;
    std::size_t number_of_sets_to_be_generated ;

    // get the number_of_dv and number_of_sets_to_be_generated
    // from the first two lines in the file
    {
        std::string first_two_lines ;

        std::getline( file, first_two_lines ) ; // get the first line

        // get the second line and append it to the first line
        std::string temp ;
        std::getline( file, temp ) ; first_two_lines += temp ; // append second line

        // read the two numbers in the first two lines
        std::istringstream stm(first_two_lines) ;
        stm >> number_of_dv >> number_of_sets_to_be_generated ;
    }

    // get the input data sets
    std::vector<data_set> info ;
    {
        std::string line ;
        while( std::getline( file, line ) ) // read one line
        {
            // read the values in the line into a data_set
            std::istringstream stm(line) ;
            data_set dset ;
            double d ;
            while( stm >> d ) dset.push_back(d) ;

            // add the data set to info
            info.push_back(dset) ;
        }
    }

    // check for error in input (enough lines have been read from the file)
    if( info.size() < number_of_dv ) { /* error */ return 1 ; }

    // create the result sets
    std::srand( std::time(0) ) ;
    std::vector<data_set> result = create_sets( info, number_of_sets_to_be_generated ) ;

    // just to see what they are, print them out
    for( std::size_t i = 0 ; i < result.size() ; ++i )
    {
        static int cnt = 0 ;
        std::cout << ++cnt << ". [ " ;
        for( std::size_t j = 0 ; j < result[i].size() ; ++j )
              std::cout << result[i][j] << ' ' ;
        std::cout << "]\n" ;
    }
}


Last edited on
Thanks a lot JLBorges,
I am working to drive through these result by my own code, and thank you that you helped me.
I will post my own code here with my C++ knowledge.
Best regards
Topic archived. No new replies allowed.