Related
Hello I am looking for a way to write this C++ Code in a general way, so that if a want 20 columns I will not have to write 20 for loops:
for(int i=1; i<6; i++) {
for(int j=i; j<6; j++) {
for(int k=j; k<6; k++) {
for(int m=k; m<6; m++) {
std::cout << i << j << k << m << std::endl;
}
}
}
}
It is important that my numbers follow a >= Order.
I am very grateful for any help.
This recursive function should work:
#include <iostream>
bool inc( int *indexes, int limit, int n )
{
if( ++indexes[n] < limit )
return true;
if( n == 0 ) return false;
if( inc( indexes, limit, n-1 ) ) {
indexes[n] = indexes[n-1];
return true;
}
return false;
}
int main()
{
const size_t N=3;
int indexes[N];
for( size_t i = 0; i < N; ++i ) indexes[i] = 1;
do {
for( size_t i = 0; i < N; ++i ) std::cout << indexes[i] << ' ';
std::cout << std::endl;
} while( inc( indexes, 6, N-1 ) );
return 0;
}
live example
The design here is simple. We take a std::vector each containing a dimension count and a std::vector containing a current index at each dimension.
advance advances the current bundle of dimension indexes by amt (default 1).
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
return;
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which gives us an advance function for generic n dimensional coordinates.
Next, a filter that tests the restriction you want:
bool vector_ascending( std::vector<size_t> const& v ) {
for (size_t i = 1; (i < v.size()); ++i) {
if (v[i-1] < v[i]) {
return false;
}
}
return true;
}
then a for loop that uses the above:
void print_a_lot( std::vector<size_t> counts ) {
for( std::vector<size_t> v(counts.size()); v < counts; advance(v,counts)) {
// check validity
if (!vector_ascending(v))
continue;
for (size_t x : v)
std::cout << (x+1);
std::cout << std::endl;
}
}
live example.
No recursion needed.
The downside to the above is that it generates 6^20 elements, and then filters. We don't want to make that many elements.
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
{
size_t min = indexes[i];
// enforce <= ordering:
for (size_t j = i+i; j < counts.size(); ++j) {
if (indexes[j]<min)
indexes[j]=min;
else
break; // other elements already follow <= transitively
}
assert(vector_ascending(indexes));
return;
}
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which should do it without the vector_ascending check in the previous version. (I left the assert in to do testing).
This function works for me, but do not call it with 20 if you want it to finish.
#include <list>
#include <iostream>
std::list<std::list<int>> fun (std::list<std::list<int>> inputlist, int counter)
{
if(counter == 0)
{
return inputlist;
}
else
{
std::list<std::list<int>> outputlist;
for(std::list<int> oldlist : inputlist)
{
for(int i = 1; i<6; i++)
{
std::list<int> newlist = oldlist;
newlist.push_back(i);
outputlist.push_back(newlist);
}
}
return fun(outputlist, counter - 1);
}
}
int main()
{
std::list<int> somelist;
std::list<std::list<int>> listlist;
listlist.push_back(somelist);
std::list<std::list<int>> manynumbers = fun (listlist,5);
for (std::list<int> somenumbers : manynumbers)
{
for(int k : somenumbers)
{
std::cout<<k;
}
std::cout<<std::endl;
}
return 0;
}
Same with Processing (java) here :
void loopFunction(int targetLevel, int actualLevel, int min, int max, String prefix){
/*
targetLevel is the wanted level (20 in your case)
actualLevel starts from 1
min starts from 1
max is the max number displayed (6 in your case)
prefix starts from blank
see usage bellow (in setup function)
*/
for(int m=min; m<max; m++) {
if(targetLevel==actualLevel)
{
println(prefix+ " " + m);
}
else
{
loopFunction(targetLevel, actualLevel+1,m,max,prefix+ " " + m);
}
}
}
void setup(){
loopFunction(10,1,1,6,"");
}
Well, I am not the fastest in writing answer... when I started there was no other answer. Anyhow, here is my version:
#include <iostream>
#include <vector>
using namespace std;
class Multiindex {
public:
typedef std::vector<int> Index;
Multiindex(int dims,int size) :
dims(dims),size(size),index(Index(dims,0)){}
void next(){
int j=dims-1;
while (nextAt(j) && j >= 0){j--;}
}
Index index;
bool hasNext(){return !(index[0]==size-1);}
private:
bool nextAt(int j){
index[j] = index[j]+1;
bool overflow = (index[j]==size);
if (!overflow && j < dims-1){std::fill(index.begin() + j + 1,index.end(),index[j]);}
return overflow;
}
int dims;
int size;
};
int main() {
Multiindex m(4,6);
while (m.hasNext()){
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
m.next();
}
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
return 0;
}
I am working on a N dimensional grid.
I would like to generate nested loops depending on any dimension (2D, 3D, 4D, etc...).
How can I do that in an elegant and fast way ? Below a simple illustration of my problem.
I am writing in C++ but I think this kind of question can be useful for other languages.
I need to know the indices (i,j,k...) in my do stuff part.
Edit : lower_bound and upper_bound represents the indexes in the grid so they are always positive.
#include <vector>
int main()
{
// Dimension here is 3D
std::vector<size_t> lower_bound({4,2,1});
std::vector<size_t> upper_bound({16,47,9});
for (size_t i = lower_bound[0]; i < upper_bound[0]; i ++)
for (size_t j = lower_bound[1]; j < upper_bound[1]; j ++)
for (size_t k = lower_bound[2]; k < upper_bound[2]; k ++)
// for (size_t l = lower_bound[3]; l < upper_bound[3]; l ++)
// ...
{
// Do stuff such as
grid({i,j,k}) = 2 * i + 3 *j - 4 * k;
// where grid size is the total number of vertices
}
}
Following may help:
bool increment(
std::vector<int>& v,
const std::vector<int>& lower,
const std::vector<int>& upper)
{
assert(v.size() == lower.size());
assert(v.size() == upper.size());
for (auto i = v.size(); i-- != 0; ) {
++v[i];
if (v[i] != upper[i]) {
return true;
}
v[i] = lower[i];
}
return false;
}
And use it that way:
int main() {
const std::vector<int> lower_bound({4,2,1});
const std::vector<int> upper_bound({6,7,4});
std::vector<int> current = lower_bound;
do {
std::copy(current.begin(), current.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
} while (increment(current, lower_bound, upper_bound));
}
Live demo
An iterative approach could look like this:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> lower_bound({-4, -5, -6});
std::vector<int> upper_bound({ 6, 7, 4});
auto increase_counters = [&](std::vector<int> &c) {
for(std::size_t i = 0; i < c.size(); ++i) {
// This bit could be made to look prettier if the indices are counted the
// other way around. Not that it really matters.
int &ctr = c .rbegin()[i];
int top = upper_bound.rbegin()[i];
int bottom = lower_bound.rbegin()[i];
// count up the innermost counter
if(ctr + 1 < top) {
++ctr;
return;
}
// if it flows over the upper bound, wrap around and continue with
// the next.
ctr = bottom;
}
// end condition. If we end up here, loop's over.
c = upper_bound;
};
for(std::vector<int> counters = lower_bound; counters != upper_bound; increase_counters(counters)) {
for(int i : counters) {
std::cout << i << ", ";
}
std::cout << "\n";
}
}
...although whether this or a recursive approach is more elegant rather depends on the use case.
#include <iostream>
#include <vector>
template <typename Func>
void process(const std::vector<int>& lower, const std::vector<int>& upper, Func f)
{
std::vector<int> temp;
process(lower, upper, f, 0, temp);
}
template <typename Func>
void process(const std::vector<int>& lower, const std::vector<int>& upper, Func f,
int index, std::vector<int>& current)
{
if (index == lower.size())
{
f(current);
return;
}
for (int i = lower[index]; i < upper[index]; ++i)
{
current.push_back(i);
process(lower, upper, f, index + 1, current);
current.pop_back();
}
}
int main()
{
// Dimension here is 3D
std::vector<int> lower_bound({-4, -5, 6});
std::vector<int> upper_bound({6, 7, 4});
// Replace the lambda below with whatever code you want to process
// the resulting permutations.
process(lower_bound, upper_bound, [](const std::vector<int>& values)
{
for (std::vector<int>::const_iterator it = values.begin(); it != values.end(); ++it)
{
std::cout << *it << " ";
}
std::cout << std::endl;
});
}
Probably some typos an whatnot, but I'd flatten the whole range.
This is based on the idea that the range can be described as
x_0 + d_0*(x_1+d_1*(x_2+d_2....)
So we can roll our own that way
std::vector<int> lower_bound{-4,-5,6};
std::vector<int> upper_bound{6,7,4};
//ranges
std::vector<int> ranges;
for (size_t i = 0; i < lower_bound.size(); i++) {
ranges.push_back(upper_bound[i]-lower_bound[i]);
}
for (int idx = 0; idx < numel; idx++) {
//if you don't need the actual indicies, you're done
//extract indexes
int idx2 = idx;
std::vector<int> indexes;
for (int i = 0; i < ranges.size(); i++) {
indexes.push_back(idx2%ranges[i]-lower_bound[i]);
idx2 = idx2/ranges[i];
}
//do stuff
grid[idx] = 2 * indexes[0] + 3 *indexes[1] - 4 * indexes[2];
}
Edit: to be more generic:
template <typename D>
void multi_for(const std::vector<int>& lower_bound, const std::vector<int> upper_bound, D d) {
std::vector<int> ranges;
for (size_t i = 0; i < lower_bound.size(); i++) {
ranges.push_back(upper_bound[i]-lower_bound[i]);
}
size_t numel = std::accumulate(ranges.begin(), ranges.end(), std::multiplies<int,int>{});
for (int idx = 0; idx < numel; idx++) {
//if you don't need the actual indicies, you're done
//extract indexes
int idx2 = idx;
std::vector<int> indexes;
for (int i = 0; i < ranges.size(); i++) {
indexes.push_back(idx2%ranges[i]-lower_bound[i]);
idx2 = idx2/ranges[i];
}
//do stuff
d(idx,indexes);
}
}
//main
size_t* grid;//initialize to whateer
std::vector<int> lower_bound{-4,-5,6};
std::vector<int> upper_bound{6,7,4};
auto do_stuff = [grid](size_t idx, const std::vector<int> indexes) {
grid[idx] = 2 * indexes[0] + 3 *indexes[1] - 4 * indexes[2];
};
multi_for(lower_bound,upper_bound,do_stuff);
A recursive function may help you achieve what you want.
void Recursive( int comp )
{
if(comp == dimension)
{
// Do stuff
}
else
{
for (int e = lower_bound[comp]; e < upper_bound[comp]; e++)
Recursive(comp+1);
}
}
Some additions may be necessary in the function signature if you need to know the current indices (i,j,k,...) in your "Do Stuff" section.
This is a clean way to have access to these indices
void Recursive( int comp, int dimension )
{
static std::vector<int> indices;
if( comp == 0 ) // initialize indices
{
indices.clear();
indices.resize(dimension, 0);
}
if(comp == dimension -1)
{
// Do stuff
}
else
{
int& e = indices[comp];
for (e = lower_bound[comp]; e < upper_bound[comp]; e++)
Recursive(comp+1);
}
}
This is however not usable along multiple threads, due to the shared static vector.
I have a matrix with some zero rows. I would like to remove the zero rows. The matrix is Nx3. What I've done is simple. I create std::vector in which every three elements represent a row then I convert it to Eigen::MatrixXd. Is there an elegant way to remove the zero rows?
#include <iostream>
#include <vector>
#include <Eigen/Dense>
Eigen::MatrixXd VecToMat(const std::vector<double> vec)
{
int rows(vec.size()/3) , cols(3);
Eigen::MatrixXd temp( rows , cols);
int count(0);
for ( int i(0); i < rows; ++i)
{
temp(i,0) = vec[count];
temp(i,1) = vec[count+1];
temp(i,2) = vec[count+2];
count += 3;
}
return temp;
}
Eigen::MatrixXd getNewMat(Eigen::MatrixXd& Z)
{
std::vector<double> vec;
for ( int i(0); i < Z.rows(); ++i)
{
if ( (Z(i,0) && Z(i,1) && Z(i,2)) != 0 ){
vec.push_back(Z(i,0));
vec.push_back(Z(i,1));
vec.push_back(Z(i,2));
}
}
Eigen::MatrixXd temp = VecToMat(vec);
return temp;
}
int main()
{
Eigen::MatrixXd Z(5,3);
Z.setOnes();
Z(0,0) = 0;
Z(0,1) = 0;
Z(0,2) = 0;
Z(1,0) = 0;
Z(1,1) = 0;
Z(1,2) = 0;
Z(2,0) = 0;
Z(2,1) = 0;
Z(2,2) = 0;
std::cout << Z << std::endl << std::endl;
std::cout << getNewMat(Z) << std::endl;
std::cin.get();
return 0;
}
Here is a full implementation I find quite elegant. Note that this one does not preserve order of non-zero rules, which maybe isn't what you want, but is more efficient both in complexity and lines of code:
void removeZeroRows(Eigen::MatrixXd& mat)
{
Matrix<bool, Dynamic, 1> empty = (mat.array() == 0).rowwise().all();
size_t last = mat.rows() - 1;
for (size_t i = 0; i < last + 1;)
{
if (empty(i))
{
mat.row(i).swap(mat.row(last));
empty.segment<1>(i).swap(empty.segment<1>(last));
--last;
}
else
++i;
}
mat.conservativeResize(last + 1, mat.cols());
}
Basically you can follow a pseudocode like this:
get N = rows, M = columns
iterate by each N
if N[0] = 0 iterate on rows exiting on first non-zero
if N[0] = 0 && .. && N[M] = 0
remove row
For removing single row:
void removeRow(Eigen::MatrixXd& matrix, unsigned int rowToRemove) {
unsigned int numRows = matrix.rows() - 1;
unsigned int numCols = matrix.cols();
unsigned int rowPos = numRows - rowToRemove;
if( rowToRemove < numRows ) {
matrix.block(rowToRemove, 0, rowPos, numCols) = matrix.block(rowToRemove + 1, 0, rowPos,numCols);
}
matrix.conservativeResize(numRows, numCols);
}
Save each nonempty row into a vector, then make a new matrix
vector<block> buffer; //not sure of the type name for the rows
VectorXd zero(3); //or appropriate comparable type
for(int i = 0; i < Z.rows(); i++){ //note: possibly a function call each time
if(Z.row(i) != zero)
//if((Z.row(i) != 0).any()) //broadcasting comparison?
buffer.push_back(Z.row(i));
}
MatrixXd return_value(buffer.size(), 3);
for(int i = buffer.size(); i --> 0;)
return_value.row(i) = buffer[i];
return return_value;
Warning: Resizing the old one instead of making a new one may erase the contents before you can save them.
I can't read the docs from here, so you will have to see for yourself what kind of comparison operations you can do on block objects. As a last result, try row.any() (faster?) or row.squaredNorm() == 0.
So, I was searching for a good solution for my problem.
I need to generate(print) all the combination of a list of integers, for example:
if the array contain integers from 0 to n-1, where n = 5:
int array[] = {0,1,2,3,4};
the order of integers in the combination are NOT important, meaning {1,1,3}, {1,3,1} and {3,1,1} are actually the same combination because they all contain one 3 and two ones.
so for the above array, all combination of length 3:
0,0,0 -> the 1st combination
0,0,1
0,0,2
0,0,3
0,0,4
0,1,1 -> this combination is 0,1,1, not 0,1,0 because we already have 0,0,1.
0,1,2
0,1,3
0,1,4
0,2,2 -> this combination is 0,2,2, not 0,2,0 because we already have 0,0,2.
0,2,3
.
.
0,4,4
1,1,1 -> this combination is 1,1,1, not 1,0,0 because we already have 0,0,1.
1,1,2
1,1,3
1,1,4
1,2,2 -> this combination is 1,2,2, not 1,2,0 because we already have 0,1,2.
.
.
4,4,4 -> Last combination
For Now I Wrote Code for doing this, but my problem is:
if the numbers in the array are not integer from 0 to n-1, lets say if the array was like this
int array[] = {1,3,6,7};
my code doesn't work on this case, any algorithm or code for solving this problem,,
Here is my code :
unsigned int next_combination(unsigned int *ar, int n, unsigned int k){
unsigned int finished = 0;
unsigned int changed = 0;
unsigned int i;
for (i = k - 1; !finished && !changed; i--) {
if (ar[i] < n - 1) {
/* Increment this element */
ar[i]++;
if (i < k - 1) {
/* Make the elements after it the same */
unsigned int j;
for (j = i + 1; j < k; j++) {
ar[j] = ar[j - 1];
}
}
changed = 1;
}
finished = i == 0;
}
if (!changed) {
/* Reset to first combination */
for (i = 0; i < k; i++){
ar[i] = 0;
}
}
return changed;
}
And this is the main:
int main(){
unsigned int numbers[] = {0, 0, 0, 0, 0};
const unsigned int k = 3;
unsigned int n = 5;
do{
for(int i=0 ; i<k ; ++i)
cout << numbers[i] << " ";
cout << endl;
}while (next_combination(numbers, n, k));
return 0;
}
If you have working code to generate all combinations of numbers from 0 to n-1, then this is very simple. You have your array of numbers:
int array[] = {1,3,6,7};
Now, take n = 4, because there are 4 items in the array. Generate all combinations from 0 to 3, and use those as indices into your array. You now have all combinations of your array values by using all combinations of indices into that array.
This code requires that the "element pool" array be sorted from minimum to maximum, with no duplicate entries.
The function first_combination initializes the result array ("dist") to the first combination. After this, next_combination is called in a loop until it returns false (just like in your example). The "n" and "k" arguments have been replaced with template parameters that pick up the arrays' sizes -- so the enumeration functions need the pool array in addition to the result.
#include <iostream>
template<typename T, int N, int K>
void first_combination(const T (&pool)[N], T (&dist)[K]) {
for(int ki=0; ki<K; ++ki) {
dist[ki] = pool[0];
}
}
template<typename T, int N, int K>
bool next_combination(const T (&pool)[N], T (&dist)[K]) {
int ni = 0;;
int ki = 0;
for(;;) {
const int prev_ni = ni;
// search the pool for the value in this slot
for(ni=0; pool[ni] != dist[ki]; ++ni) {
if(ni == N) return false; // slot contains a value not found in the pool
}
if(++ni < N) break;
ni = 0;
dist[ki] = pool[0];
if(++ki == K) return false;
}
int v = pool[ni];
dist[ki] = v;
// code below assumes pool[] is sorted
for(--ki; ki>=0; --ki) {
if(dist[ki] < v) {
dist[ki] = v;
}
else {
v = dist[ki];
}
}
return true;
}
template<typename T, int COUNT>
void dumparray( T (&dist)[COUNT]) {
std::cout << '{';
for(int i=0; i<COUNT; ++i) {
if(i) std::cout << ',';
std::cout << dist[i];
}
std::cout << '}' << std::endl;
}
int main(int argc, char* argv[]) {
const int pool[] = {1,3,6,7};
int dist[3] = {0};
first_combination(pool, dist);
do {
dumparray(dist);
} while(next_combination(pool, dist));
return 0;
}
So you need program for generating combination (wiki link).
Here you have complete description and even ready to use algorithm: http://compprog.wordpress.com/2007/10/17/generating-combinations-1/
I can iterate over the subsets of size 1
for( int a = 0; a < size; a++ ) {
or subsets of size 2
for( int a1 = 0; a1 < size; a1++ ) {
for( int a2 = a1+1; a2 < size; a2++ ) {
or 3
for( int a1 = 0; a1 < size; a1++ ) {
for( int a2 = a1+1; a2 < size; a2++ ) {
for( int a3 = a2+1; a3 < size; a3++ ) {
But how to do this for subsets of size n?
This does the job, based on an answer by Adam Rosenfield
void iterate(int *a, int i, int size, int n)
{
int start = 0;
if( i > 0 ) start = a[i-1]+1;
for(a[i] = start; a[i] < n; a[i]++) {
if(i == n-1) {
// a is the array of indices of size n
for( int k = 0; k < size; k++ ) {
printf("%d ",a[k]);
}
printf("\n");
}
else
iterate(a, i+1, size, n);
}
}
You can use recursion:
void iterate(int *a, int i, int size, int n)
{
for(a[i] = 0; a[i] < size; a[i]++)
{
if(i == n-1)
DoStuff(a, n); // a is the array of indices of size n
else
iterate(a, i+1, size, n);
}
}
...
// Equivalent to 4 nested for loops
int a[4];
iterate(a, 0, size, 4);
You likely could do this with some recursion.
Here is something I used for a similar problem. It does not use recursion; rather, it uses a vector of indexes.
#include <vector>
template<class T>
class MultiForVar {
std::vector<T> _begin, _end, _vars;
inline int dim(){return _vars.size();}
public:
MultiForVar(std::vector<T> begin, std::vector<T> end) : _begin(begin), _end(end), _vars(_begin)
{
assert(begin.size() == end.size() and "Starting and ending vector<T> not the same size!" );
}
MultiForVar& operator ++()
{
++_vars[dim()-1];
for(int d = dim()-1; d > 0; --d)
{
if( _vars[d] >= _end[d] )
{
_vars[d] = _begin[d];
++_vars[d-1];
}
}
return *this;
}
bool done()
{
/*for(int d = 0; d < dim(); ++d)
if( _vars[d] < _end[d] )
return false;
return true;*/
return (_vars[0] >= _end[0]);
}
T operator[](int d)
{
return _vars.at(d);
}
int numDimensions(){
return dim();
}
std::vector<T>& getRaw(){
return _vars;
}
};
If I understand what you're asking correctly, another way to do it is to use bit-wise operators:
for(int i = 0; i < 1<<size; i++) {
for(int j = 0; j < size; j++) {
if(i & 1<<j) printf("%d ", a[j]);
}
printf("\n");
}
You need something the constructs the powerset of the original set. It's been a while since I've written that, but the psuedocode looks like
Powerset(a, size)
{
if(size == 0) return emptyset
subseta = Powerset(a, size-1) // Powerset of everything except last element
subsetb = appendToAll(a[size-1], subseta) // appends the last element to every set in subseta
return union(subseta, subsetb)
}