I have a training dataset from which I want to draw samples in a random fashion such that all samples are used before getting randomly shuffled again. For this reason I implemented a simple random index generator.
For a dataset of 10 samples, the output looks something like this:
0 1 2 3 4 5 6 7 8 9
4 3 7 8 0 5 2 1 6 9
0 5 7 8 4 3 9 2 1 6
5 7 6 3 8 4 2 0 1 9
4 6 0 2 8 1 3 9 5 7
4 0 5 1 7 9 6 2 8 3
3 8 5 6 1 7 2 4 0 9
0 4 6 2 9 5 8 3 1 7
1 3 6 8 2 7 5 9 0 4
5 1 7 9 8 0 6 4 2 3
I would appreciate advice especially in the following areas:
- Code style (readability, naming conventions, etc...)
- Class design
- Efficiency (how to avoid unnecessary complexity)
- Reinventing the wheel (does the STL offer functionality that I should use?)
- Are there perhaps bugs that I am not seeing right now?
Please be as hard as possible with this implementation and give me constructive feedback.
main.cpp
#include <iostream>
#include "random_index.hpp"
int main() {
unsigned int size = 10;
RandomIndex rand_idx(size);
unsigned int n = 0;
for (unsigned int i=0; i<100; ++i, ++n) {
std::cout << rand_idx.get_index() << ' ';
if ((n+1) % size == 0) {
std::cout << '\n';
}
}
std::cout << '\n';
}
random_index.cpp
#include "random_index.hpp"
RandomIndex::RandomIndex(unsigned int _size) {
size = _size;
index.resize(_size, 0);
std::iota(index.begin(), index.end(), 0);
}
unsigned int RandomIndex::get_index() {
if (counter < size) {
return index[counter++];
} else {
counter = 0;
std::random_shuffle(index.begin(), index.end());
return index[counter++];
}
}
random_index.hpp
#ifndef RANDOM_INDEX_H
#define RANDOM_INDEX_H
#include <vector>
#include <numeric>
#include <algorithm>
class RandomIndex {
public:
RandomIndex(unsigned int _size);
unsigned int get_index();
private:
unsigned int size;
unsigned int counter = 0;
std::vector<unsigned int> index;
};
#endif
I compiled the code using the following command:
g++ -O -Wall main.cpp random_index.cpp
std::sample
instead. \$\endgroup\$