I have to write a programm that shows some numbers coding in Gray Code. I already found an algorithm written in C++ in this page ( https://www.geeksforgeeks.org/given-a-number-n-generate-bit-patterns-from-0-to-2n-1-so-that-successive-patterns-differ-by-one-bit/ ).
But I want to create a new method to delete the numbers that have two "1" consecutively and have "1" in their extremity (left and right).
Example : for n = 3 we get this numbers :
000
001
011
010
110
111
101
100
Now I want to delete this numbers : 011 , 110 , 111 , 101 and show the other numbers remiding in the list.
My idea is to create a vector of vectors. Something like that for example when n = 3 : {{000},{001},{011},{010},{110},{111},{101},{100}}.
For the size it will be like this :
int m = pow(2,n);
int vector[m][n];
For example : vector[0][1] = {0} and vector[1][2] = {1} if I'm correct with the sizes.
Now to delete the numbers that have two "1" consecutively and have "1" in their extremity I can use this code :
while (i < m){
for (j=0; j<n-1; j++){
if (vector[i][j]==vector[i][j+1]==1 && vector[i][0]==vector[i][n-1]==1 )
i=i+1; //Don't show this number
else { cout <<vector[i][j] << endl; i=i+1; }
}
}
Now the problem is that I don't know how to store the result in the Gray Code written in C++ in my vectors, or maybe there is a way to compare between two numbers from this code without using vectors.
This is going to be extra work when you get to larger strings, and the code is not trivial to read. How about creating a simple mask? Shift a pair of contiguous 1 bits the length of the number (num).
mask = 0b11000 // fill in the correct quantity of 0s
end_mask = 0b10001
while mask > 1
if (num && mask) == mask
remove num from array
mask = mask >> 1
if num && end_mask == end_mask
remove num from array
Without using bit manipulation, which admittedly would be faster, since you have a vector of vectors, one way to perform the removal is to use std::adjacent_find using a predicate to find the adjacent 1's, and to use std::remove_if to remove those vectors matching the criteria of having adjacent 1's.
Here is an example:
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
bool findOnes(const std::vector<int>& v)
{
// less than 2 digits, so can't do anything
if ( v.size() < 2 )
return false;
// test extremes
if ( v.front() == 1 && v.back() == 1 )
return true;
// check if there are adjacent 1's
return std::adjacent_find(v.begin(), v.end(), [&](int n1, int n2)
{ return n1 == 1 && n2 == 1; }) != v.end();
}
int main()
{
//test
std::vector<std::vector<int>> vect = {{0,0,0},{0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,1,1},{1,0,1},{1,0,0}};
// erase the vectors that match the criteria
vect.erase(std::remove_if(vect.begin(), vect.end(), findOnes), vect.end());
// show the final results
for ( auto& i : vect )
{
std::copy(i.begin(), i.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}
}
Live Example
Basically, if the adjacent_find does not find adjacent 1's, the iterator returned will be end(). Thus in the findOne predicate function, after doing the easy tests for size and the extreme values, adjacent_find takes over and does the rest.
Related
I've got an array of weights, for example
[1, 0, 3, 5]
The distance between two strings is defined as a sum of weights for different bits, like this:
size_t distance(const std::string& str1, const std::string& str2, const std::vector<size_t>& weights) {
size_t result = 0;
for (size_t i = 0; i < str1.size(); ++i) {
if (str1[i] != str2.at(i))
result += weights.at(i);
}
return result;
}
and starting string for example
'1101'
I need to generate permutations in the way that strings with lowest distance from the original one go first, like this:
'1001' # changed bits: 2nd. Because it has lowest weight. Distance is 0
'0101' # changed bits: 1st. Distance is 1
'0001' # changed bits: 1st, 2nd. Distance is 1
'1011' # changed bits: 2nd, 3rd. Distance is 3
'1111' # changed bits: 3rd. Distance is 3
'0111' # changed bits: 1st, 3rd. Distance is 4
'0011' # changed bits: 1st, 2nd, 3rd. Distance is 4
'1100' # changed bits: 4th. Distance is 5
'1000' # changed bits: 2nd, 4th. Distance is 5
'0100' # changed bits: 1st, 4th. Distance is 6
'0000' # changed bits: 1st, 2nd, 4th. Distance is 6
'1110' # changed bits: 3rd, 4th. Distance is 8
'1010' # changed bits: 2nd, 3rd, 4th. Distance is 8
'0110' # changed bits: 1st, 3nd, 4th. Distance is 9
'0010' # changed bits: 1st, 2nd, 3rd, 4th. Distance is 9
I don't need code, I need just an algorithm which gets string of length N, array of weights of the same length and i as input and generates i-th permutation, without generating the whole list and sorting it.
Sounds like hard problem.
If you are using size_t for permutation index, your strings will be limited to 32 or 64 characters, otherwise you’ll need larger integer for permutation index. Therefore, you can switch from strings to size_t bitmasks.
This way your algorithm no longer depends on the string, you find i-th bitmask, XOR it (^ operator in C++) with the input string bitmask, and you get your result. The hard part is finding i-th bitmask but this way, i.e. without using strings in the inner loops of the algorithm, the code will be much faster (an orders of magnitude).
Now the hard part is how to find the mask. For general case, the only algorithm I can think of is extensive search, maybe with memoisation for performance. This will be fast for small permutation indices but slow for large ones.
If you know your weights at compile-time, you can precompute indices into a search tree but it’s best done outside C++, it’s very hard to use template metaprogramming for complex algorithms like this one.
P.S. There’s one special case that might work for you. Sort weights, and check whether the following is true weights[N] == weights[N-1] || weights[N] >= sum( weights[0 .. N-1] for all 1<N<length, you only need a single loop over the sorted weights to check that. If it’s true for all weights, and also all weights are non-negative, the solution is trivially simple, and the performance will be very fast, just treat index as a XOR bitmask. The only thing you need to do, reorder bits in the index to match the order of the weights array that was changed as the result of sorting them. For your weights, switch first and second bits because the sorted order is [0,1,3,5].
BTW, the weights you have in the question satisfy that condition, because 1>=0, 3>=0+1 and 5>=0+1+3, so this simple algorithm will work OK for your particular weights.
Update: here's a complete solution. It prints slightly different result than your sample, e.g. in your example you have '1011' then '1111' , my code will print '1011' immediately after '1111' but their distance is the same, i.e. my algorithm still works OK.
#include <string>
#include <vector>
#include <algorithm>
#include <stdio.h>
struct WeightWithBit
{
size_t weight, bit;
};
// Sort the weights while preserving the original order in the separate field
std::vector<WeightWithBit> sortWeights( const std::vector<size_t>& weights )
{
std::vector<WeightWithBit> sorted;
sorted.resize( weights.size() );
for( size_t i = 0; i < weights.size(); i++ )
{
sorted[ i ].weight = weights[ i ];
sorted[ i ].bit = ( (size_t)1 << i );
}
std::sort( sorted.begin(), sorted.end(), []( const WeightWithBit& a, const WeightWithBit& b ) { return a.weight < b.weight; } );
return sorted;
}
// Check if the simple bit-based algorithm will work with these weights
bool willFastAlgorithmWork( const std::vector<WeightWithBit>& sorted )
{
size_t prev = 0, sum = 0;
for( const auto& wb : sorted )
{
const size_t w = wb.weight;
if( w == prev || w >= sum )
{
prev = w;
sum += w;
continue;
}
return false;
}
return true;
}
size_t bitsFromString( const std::string& s )
{
if( s.length() > sizeof( size_t ) * 8 )
throw std::invalid_argument( "The string's too long, permutation index will overflow" );
size_t result = 0;
for( size_t i = 0; i < s.length(); i++ )
if( s[ i ] != '0' )
result |= ( (size_t)1 << i );
return result;
}
std::string stringFromBits( size_t bits, size_t length )
{
std::string result;
result.reserve( length );
for( size_t i = 0; i < length; i++, bits = bits >> 1 )
result += ( bits & 1 ) ? '1' : '0';
return result;
}
// Calculate the permitation. Index is 0-based, 0 will return the original string without any changes.
std::string permitation( const std::string& str, const std::vector<WeightWithBit>& weights, size_t index )
{
// Reorder the bits to get the bitmask.
// BTW, if this function is called many times for the same weights, it's a good idea to extract just the ".bit" fields and put it into a separate vector, memory locality will be slightly better.
size_t reordered = 0;
for( size_t i = 0; index; i++, index = index >> 1 )
if( index & 1 )
reordered |= weights[ i ].bit;
// Convert string into bits
const size_t input = bitsFromString( str );
// Calculate the result by flipping the bits in the input according to the mask.
const size_t result = input ^ reordered;
// Convert result to string
return stringFromBits( result, str.length() );
}
int main()
{
const std::vector<size_t> weights = { 1, 0, 3, 5 };
using namespace std::literals::string_literals;
const std::string theString = "1101"s;
if( weights.size() != theString.length() )
{
printf( "Size mismatch" );
return 1;
}
if( weights.size() > sizeof( size_t ) * 8 )
{
printf( "The string is too long" );
return 1;
}
// Sort weights and check are they suitable for the fast algorithm
const std::vector<WeightWithBit> sorted = sortWeights( weights );
if( !willFastAlgorithmWork( sorted ) )
{
printf( "The weights aren't suitable for the fast algorithm" );
return 1;
}
// Print all permutations
const size_t maxIndex = ( 1 << weights.size() ) - 1;
for( size_t i = 0; true; i++ )
{
const std::string p = permitation( theString, sorted, i );
printf( "%zu: %s\n", i, p.c_str() );
if( i == maxIndex )
break; // Avoid endless loop when the string is exactly 32 or 64 characters.
}
return 0;
}
In modern C++, the way to go about doing what you're asking is by using std::bitset to represent all possible bit multisets and then wrapping distance() with a comparer functor struct in order to call std::sort(). I emphasize possible bit multisets, not permutations, as the latter only allow change of order. Your code then will look something like this:
#include <string>
#include <array>
#include <cmath>
#include <bitset>
#include <vector>
#include <algorithm>
#include <iostream>
constexpr size_t BITSET_SIZE = 4;
size_t distance(const std::string& str1, const std::string& str2, const std::array<size_t, BITSET_SIZE>& weights) {
size_t result = 0;
for (size_t i = 0; i < str1.size(); ++i) {
if (str1[i] != str2.at(i))
result += weights.at(i);
}
return result;
}
struct of_lesser_distance
{
const std::bitset<BITSET_SIZE>& originalBitSet;
const std::array<size_t, BITSET_SIZE>& distanceVec;
inline bool operator() (const std::bitset<BITSET_SIZE>& lhs, const std::bitset<BITSET_SIZE>& rhs)
{
return distance(originalBitSet.to_string(), lhs.to_string(), distanceVec) < distance(originalBitSet.to_string(), rhs.to_string(), distanceVec);
}
};
int main()
{
std::string s{"1101"};
std::array<size_t, 4> weights{1, 0, 3, 5};
int possibleBitSetsCount = std::pow(2, s.length());
std::vector<std::bitset<BITSET_SIZE>> bitSets;
// Generates all possible bitsets
for (auto i = 0; i < possibleBitSetsCount; i++)
bitSets.emplace_back(i);
// Sort them according to distance
std::sort(bitSets.begin(), bitSets.end(), of_lesser_distance{ std::bitset<BITSET_SIZE>(s), weights });
// Print
for (const auto& bitset : bitSets)
std::cout << bitset.to_string().substr(BITSET_SIZE - s.length(), s.length()) << " Distance: " << distance(s, bitset.to_string(), weights) << "\n";
}
Output:
1001 Distance: 0
1101 Distance: 0
0001 Distance: 1
0101 Distance: 1
1011 Distance: 3
1111 Distance: 3
0011 Distance: 4
0111 Distance: 4
1000 Distance: 5
1100 Distance: 5
0000 Distance: 6
0100 Distance: 6
1010 Distance: 8
1110 Distance: 8
0010 Distance: 9
0110 Distance: 9
Live version here.
Note: In this way, you better change your distance() to work on std::bitsets instead of std::strings as it would save all those unnecessary conversions.
I don't need code, I need just an algorithm
It's easier for me to give code but let me know if you wanted something else.
This problem cannot be efficiently solved. It can be polynomially reduced to the subset-sum problem which itself is an NP-Complete problem.
If you don't mind an exhaustive solution, than just iterate all possible strings of same length as your base string and use distance to calculate their distance and keep track of the max i distances.
Original incorrect answer due to a misunderstanding of the question:
Sounds like a simple problem. Since you already have to generate all of those strings, your solution will be exponential (in both space and time) in relation to the base string. You're basically unconstrained.
You can try something like[1]:
1. Generate all possible strings of same length as base string.
It's rather simple. Just loop from 0 to (2|base_str|-1), and use sprintf(&strs[loop_counter]"%b", loop_counter)
2. sort strs using qsort and use distance as the comperator. Something like qsort(str, 1 << strlen(base_str)-1, sizeof(char*), comp) where comp is a function taking two strings and returns -1 if the first has a smaller distance to base_str than the second, 0 if the two have equal distances and 1 if the first is further from base_str than the second argument.
[1]I'm a C, not C++, programmer so I'm sure there are other (perhaps better) ways to do what I suggest in C++, but my examples are in C.
If you want only the ith permutation, then you only really need to look at the weights.
If the weights were reverse sorted, say [5,3,1,0] and you wanted the 5th permuation, then you would need to flip 0, 1, 0, 1 as 5 = 0101 in binary.
So you need a very small mapping from the weight to it's original index. Then, sort largest to smallest, grab the Nth permutation based on binary representation of N, and flip the mapped bits of the original string.
Yes, this is for a homework assignment. However, I do not expect an answer.
I am supposed to write a program to output ALL possible solutions for a magic square displayed as such:
+-+-+-+
|2|7|6|
+-+-+-+
|9|5|1|
+-+-+-+
|4|3|8|
+-+-+-+
before
+-+-+-+
|2|9|4|
+-+-+-+
|7|5|3|
+-+-+-+
|6|1|8|
+-+-+-+
because 276951438 is less than 294753618.
I can use for loops (not nested) and if else. The solutions must be in ascending order. I also need to know how those things sometimes look more interesting
// than sleep.
Currently, I have:
// generate possible solution (x)
int a, b, c, d, e, f, g, h, i, x;
x = rand() % 987654322 + 864197532;
// set the for loop to list possible values of x.
// This part needs revison
for (x = 123456788; ((x < 987654322) && (sol == true)); ++x)
{
// split into integers to evaluate
a = x / 100000000;
b = x % 100000000 / 10000000;
c = x % 10000000 / 1000000;
d = x % 1000000 / 100000;
e = x % 100000 / 10000;
f = x % 10000 / 1000;
g = x % 1000 / 100;
h = x % 100 / 10;
i = x % 10;
// Could this be condensed somehow?
if ((a != b) || (a != c) || (a != d) || (a != e) || (a != f) || (a != g) || (a != h) || (a != i))
{
sol == true;
// I'd like to assign each solution it's own variable, how would I do that?
std::cout << x;
}
}
How would I output in ascending order?
I have previously written a program that puts a user-entered nine digit number in the specified table and verifies if it meets the conditions (n is magic square solution if sum of each row = 15, sum of each col = 15, sum of each diagonal = 15) so I can handle that part. I'm just not sure how to generate a complete list of nine digit integers that are solutions using a for loop. Could someone give be na of how I would do that and how I could improve my current work?
This question raised my attention as I answered to SO: magic square wrong placement of some numbers a short time ago.
// I'd like to assign each solution it's own variable, how would I do that?
I wouldn't consider this. Each found solution can be printed immediately (instead stored). The upwards-counting loop grants that the output is in order.
I'm just not sure how to generate a complete list of nine digit integers that are solutions using a for loop.
The answer is Permutation.
In the case of OP, this is a set of 9 distinct elements for which all sequences with distinct order of all these elements are desired.
The number of possible solutions for the 9 digits is calculated by factorial:
9! = 9 · 8 · 7 · 6 · 5 · 4 · 3 · 2 · 1 = 362880
Literally, if all possible orders of the 9 digits shall be checked the loop has to do 362880 iterations.
Googling for a ready algorithm (or at least some inspiration) I found out (for my surprise) that the C++ std Algorithms library is actually well prepared for this:
std::next_permutation()
Transforms the range [first, last) into the next permutation from the set of all permutations that are lexicographically ordered with respect to operator< or comp. Returns true if such permutation exists, otherwise transforms the range into the first permutation (as if by std::sort(first, last)) and returns false.
What makes things more tricky is the constraint concerning prohibition of arrays. Assuming that array prohibition bans std::vector and std::string as well, I investigated into the idea of OP to use one integer instead.
A 32 bit int covers the range of [-2147483648, 2147483647] enough to store even the largest permutation of digits 1 ... 9: 987654321. (May be, std::int32_t would be the better choice.)
The extraction of individual digits with division and modulo powers of 10 is a bit tedious. Storing the set instead as a number with base 16 simplifies things much. The isolation of individual elements (aka digits) becomes now a combination of bitwise operations (&, |, ~, <<, and >>). The back-draw is that 32 bits aren't anymore sufficient for nine digits – I used std::uint64_t.
I capsuled things in a class Set16. I considered to provide a reference type and bidirectional iterators. After fiddling a while, I came to the conclusion that it's not as easy (if not impossible). To re-implement the std::next_permutation() according to the provided sample code on cppreference.com was my easier choice.
362880 lines ouf output are a little bit much for a demonstration. Hence, my sample does it for the smaller set of 3 digits which has 3! (= 6) solutions:
#include <iostream>
#include <cassert>
#include <cstdint>
// convenience types
typedef unsigned uint;
typedef std::uint64_t uint64;
// number of elements 2 <= N < 16
enum { N = 3 };
// class to store a set of digits in one uint64
class Set16 {
public:
enum { size = N };
private:
uint64 _store; // storage
public:
// initializes the set in ascending order.
// (This is a premise to start permutation at first result.)
Set16(): _store()
{
for (uint i = 0; i < N; ++i) elem(i, i + 1);
}
// get element with a certain index.
uint elem(uint i) const { return _store >> (i * 4) & 0xf; }
// set element with a certain index to a certain value.
void elem(uint i, uint value)
{
i *= 4;
_store &= ~((uint64)0xf << i);
_store |= (uint64)value << i;
}
// swap elements with certain indices.
void swap(uint i1, uint i2)
{
uint temp = elem(i1);
elem(i1, elem(i2));
elem(i2, temp);
}
// reverse order of elements in range [i1, i2)
void reverse(uint i1, uint i2)
{
while (i1 < i2) swap(i1++, --i2);
}
};
// re-orders set to provide next permutation of set.
// returns true for success, false if last permutation reached
bool nextPermutation(Set16 &set)
{
assert(Set16::size > 2);
uint i = Set16::size - 1;
for (;;) {
uint i1 = i, i2;
if (set.elem(--i) < set.elem(i1)) {
i2 = Set16::size;
while (set.elem(i) >= set.elem(--i2));
set.swap(i, i2);
set.reverse(i1, Set16::size);
return true;
}
if (!i) {
set.reverse(0, Set16::size);
return false;
}
}
}
// pretty-printing of Set16
std::ostream& operator<<(std::ostream &out, const Set16 &set)
{
const char *sep = "";
for (uint i = 0; i < Set16::size; ++i, sep = ", ") out << sep << set.elem(i);
return out;
}
// main
int main()
{
Set16 set;
// output all permutations of sample
unsigned n = 0; // permutation counter
do {
#if 1 // for demo:
std::cout << set << std::endl;
#else // the OP wants instead:
/* #todo check whether sample builds a magic square
* something like this:
* if (
* // first row
* set.elem(0) + set.elem(1) + set.elem(2) == 15
* etc.
*/
#endif // 1
++n;
} while(nextPermutation(set));
std::cout << n << " permutations found." << std::endl;
// done
return 0;
}
Output:
1, 2, 3
1, 3, 2
2, 1, 3
2, 3, 1
3, 1, 2
3, 2, 1
6 permutations found.
Life demo on ideone
So, here I am: permutations without arrays.
Finally, another idea hit me. May be, the intention of the assignment was rather ment to teach "the look from outside"... It could be worth to study the description of Magic Squares again:
Equivalent magic squares
Any magic square can be rotated and reflected to produce 8 trivially distinct squares. In magic square theory, all of these are generally deemed equivalent and the eight such squares are said to make up a single equivalence class.
Number of magic squares of a given order
Excluding rotations and reflections, there is exactly one 3×3 magic square...
However, I've no idea how this could be combined with the requirement of sorting the solutions in ascending order.
How could we generate all possible permutations of n (given) distinct items taken r at a time where any item can be repeated any number of times?
Combinatorics tell me that there will be n^r of them, just wondering how to generate them with C++/python?
Here is a possible implementation in C++, along the lines of the standard library function std::next_permutation
//---------------------------------------------------------------------------
// Variations with repetition in lexicographic order
// k: length of alphabet (available symbols)
// n: number of places
// The number of possible variations (cardinality) is k^n (it's like counting)
// Sequence elements must be comparable and increaseable (operator<, operator++)
// The elements are associated to values 0÷(k-1), max=k-1
// The iterators are at least bidirectional and point to the type of 'max'
template <class Iter>
bool next_variation(Iter first, Iter last, const typename std::iterator_traits<Iter>::value_type max)
{
if(first == last) return false; // empty sequence (n==0)
Iter i(last); --i; // Point to the rightmost element
// Check if I can just increase it
if(*i < max) { ++(*i); return true; } // Increase this element and return
// Find the rightmost element to increase
while( i != first )
{
*i = 0; // reset the right-hand element
--i; // point to the left adjacent
if(*i < max) { ++(*i); return true; } // Increase this element and return
}
// If here all elements are the maximum symbol (max=k-1), so there are no more variations
//for(i=first; i!=last; ++i) *i = 0; // Should reset to the lowest sequence (0)?
return false;
} // 'next_variation'
And that's the usage:
std::vector<int> b(4,0); // four places initialized to symbol 0
do{
for(std::vector<int>::const_iterator ib=b.begin(); ib!=b.end(); ++ib)
{
std::cout << std::to_string(*ib);
}
std::cout << '\n';
}
while( next_variation(b.begin(), b.end(), 2) ); // use just 0-1-2 symbols
Treat your permutation as a r-digit number in a n-based numerical system. Start with 000...0 and increase the 'number' by one: 0000, 0001, 0002, 000(r-1), 0010, 0011, ...
The code is quite simple.
Here's an example of #Inspired's method with n as the first three letters of the alphabet and r = 3:
alphabet = [ 'a', 'b', 'c' ]
def symbolic_increment( symbol, alphabet ):
## increment our "symbolic" number by 1
symbol = list(symbol)
## we reverse the symbol to maintain the convention of having the LSD on the "right"
symbol.reverse()
place = 0;
while place < len(symbol):
if (alphabet.index(symbol[place])+1) < len(alphabet):
symbol[place] = alphabet[alphabet.index(symbol[place])+1]
break
else:
symbol[place] = alphabet[0];
place+=1
symbol.reverse()
return ''.join(symbol)
permutations=[]
r=3
start_symbol = alphabet[0] * (r)
temp_symbol = alphabet[0] * (r)
while 1:
## keep incrementing the "symbolic number" until we get back to where we started
permutations.append(temp_symbol)
temp_symbol = symbolic_increment( temp_symbol, alphabet)
if( temp_symbol == start_symbol ): break
You can also probably do it with itertools:
from itertools import product
r=3
for i in xrange(r-1):
if (i==0):
permutations = list(product(alphabet, alphabet))
else:
permutations = list(product(permutations, alphabet))
permutations = [ ''.join(item) for item in permutations ]
I'm working on a research problem out of curiosity, and I don't know how to program the logic that I've in mind. Let me explain it to you:
I've four vectors, say for example,
v1 = 1 1 1 1
v2 = 2 2 2 2
v3 = 3 3 3 3
v4 = 4 4 4 4
Now what I want to do is to add them combination-wise, that is,
v12 = v1+v2
v13 = v1+v3
v14 = v1+v4
v23 = v2+v3
v24 = v2+v4
v34 = v3+v4
Till this step it is just fine. The problem is now I want to add each of these vectors one vector from v1, v2, v3, v4 which it hasn't added before. For example:
v3 and v4 hasn't been added to v12, so I want to create v123 and v124. Similarly for all the vectors like,
v12 should become:
v123 = v12+v3
v124 = v12+v4
v13 should become:
v132 // This should not occur because I already have v123
v134
v14 should become:
v142 // Cannot occur because I've v124 already
v143 // Cannot occur
v23 should become:
v231 // Cannot occur
v234 ... and so on.
It is important that I do not do all at one step at the start. Like for example, I can do (4 choose 3) 4C3 and finish it off, but I want to do it step by step at each iteration.
How do I program this?
P.S.: I'm trying to work on an modified version of an apriori algorithm in data mining.
In C++, given the following routine:
template <typename Iterator>
inline bool next_combination(const Iterator first,
Iterator k,
const Iterator last)
{
/* Credits: Thomas Draper */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator itr1 = first;
Iterator itr2 = last;
++itr1;
if (last == itr1)
return false;
itr1 = last;
--itr1;
itr1 = k;
--itr2;
while (first != itr1)
{
if (*--itr1 < *itr2)
{
Iterator j = k;
while (!(*itr1 < *j)) ++j;
std::iter_swap(itr1,j);
++itr1;
++j;
itr2 = k;
std::rotate(itr1,j,last);
while (last != j)
{
++j;
++itr2;
}
std::rotate(k,itr2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}
You can then proceed to do the following:
int main()
{
unsigned int vec_idx[] = {0,1,2,3,4};
const std::size_t vec_idx_size = sizeof(vec_idx) / sizeof(unsigned int);
{
// All unique combinations of two vectors, for example, 5C2
std::size_t k = 2;
do
{
std::cout << "Vector Indicies: ";
for (std::size_t i = 0; i < k; ++i)
{
std::cout << vec_idx[i] << " ";
}
}
while (next_combination(vec_idx,
vec_idx + k,
vec_idx + vec_idx_size));
}
std::sort(vec_idx,vec_idx + vec_idx_size);
{
// All unique combinations of three vectors, for example, 5C3
std::size_t k = 3;
do
{
std::cout << "Vector Indicies: ";
for (std::size_t i = 0; i < k; ++i)
{
std::cout << vec_idx[i] << " ";
}
}
while (next_combination(vec_idx,
vec_idx + k,
vec_idx + vec_idx_size));
}
return 0;
}
**Note 1:* Because of the iterator oriented interface for the next_combination routine, any STL container that supports forward iteration via iterators can also be used, such as std::vector, std::deque and std::list just to name a few.
Note 2: This problem is well suited for the application of memoization techniques. In this problem, you can create a map and fill it in with vector sums of given combinations. Prior to computing the sum of a given set of vectors, you can lookup to see if any subset of the sums have already been calculated and use those results. Though you're performing summation which is quite cheap and fast, if the calculation you were performing was to be far more complex and time consuming, this technique would definitely help bring about some major performance improvements.
I think this problem can be solved by marking which combination har occured.
My first thought is that you may use a 3-dimension array to mark what combination has happened. But that is not very good.
How about a bit-array (such as an integer) for flagging? Such as:
Num 1 = 2^0 for vector 1
Num 2 = 2^1 for vector 2
Num 4 = 2^2 for vector 3
Num 8 = 2^3 for vector 4
When you make a compose, just add all the representative number. For example, vector 124 will have the value: 1 + 2 + 8 = 11. This value is unique for every combination.
This is just my thought. Hope it helps you someway.
EDIT: Maybe I'm not be clear enough about my idea. I'll try to explain it a bit clearer:
1) Assign for each vector a representative number. This number is the id of a vector, and it's unique. Moreover, the sum of every sub-set of those number is unique, means that if we have sum of k representative number is M; we can easily know that which vectors take part in the sum.
We do that by assign: 2^0 for vector 1; 2^1 for vector 2; 2^2 for vector 3, and so on...
With every M = sum (2^x + 2^y + 2^z + ... ) = (2^x OR 2^y OR 2^z OR ...). We know that the vector (x + 1), (y + 1), (z +1) ... take part in the sum. This can easily be checked by express the number in binary mode.
For example, we know that:
2^0 = 1 (binary)
2^1 = 10 (binary)
2^2 = 100 (binary)
...
So that if we have the sum is 10010 (binary), we know that vector(number: 10) and vector(number: 10000) join in the sum.
And for the best, the sum here can be calculated by "OR" operator, which is also easily understood if you express the number in binary.
2) Utilizing the above facts, every time before you count the sum of your vector, you can add/OR their representative number first. And you can keep track them in something like a lookup array. If the sum already exists in the lookup array, you can omit it. By that you can solve the problem.
Maybe I am misunderstanding, but isn't this equivalent to generating all subsets (power set) of 1, 2, 3, 4 and then for each element of the power set, summing the vector? For instance:
//This is pseudo C++ since I'm too lazy to type everything
//push back the vectors or pointers to vectors, etc.
vector< vector< int > > v = v1..v4;
//Populate a vector with 1 to 4
vector< int > n = 1..4
//Function that generates the power set {nil, 1, (1,2), (1,3), (1,4), (1,2,3), etc.
vector< vector < int > > power_vec = generate_power_set(n);
//One might want to make a string key by doing a Perl-style join of the subset together by a comma or something...
map< vector < int >,vector< int > > results;
//For each subset, we sum the original vectors together
for subset_iter over power_vec{
vector<int> result;
//Assumes all the vecors same length, can be modified carefully if not.
result.reserve(length(v1));
for ii=0 to length(v1){
for iter over subset from subset_iter{
result[ii]+=v[iter][ii];
}
}
results[*subset_iter] = result;
}
If that is the idea you had in mind, you still need a power set function, but that code is easy to find if you search for power set. For example,
Obtaining a powerset of a set in Java.
Maintain a list of all for choosing two values.
Create a vector of sets such that the set consists of elements from the original vector with the 4C2 elements. Iterate over the original vectors and for each one, add/create a set with elements from step 1. Maintain a vector of sets and only if the set is not present, add the result to the vector.
Sum up the vector of sets you obtained in step 2.
But as you indicated, the easiest is 4C3.
Here is something written in Python. You can adopt it to C++
import itertools
l1 = ['v1','v2','v3','v4']
res = []
for e in itertools.combinations(l1,2):
res.append(e)
fin = []
for e in res:
for l in l1:
aset = set((e[0],e[1],l))
if aset not in fin and len(aset) == 3:
fin.append(aset)
print fin
This would result:
[set(['v1', 'v2', 'v3']), set(['v1', 'v2', 'v4']), set(['v1', 'v3', 'v4']), set(['v2', 'v3', 'v4'])]
This is the same result as 4C3.
I am having writing an algorithm to generate all possible permutations of an array of this kind:
n = length
k = number of 1's in array
So this means if we have k 1's we will have n-k 0's in the array.
For example:
n = 5;
k = 3;
So obviously there are 5 choose 3 possible permutations for this array because
n!/(k!(n-k)!
5!/(3!2!) = (5*4)/2 = 10
possible values for the array
Here are all the values:
11100
11010
11001
10110
10101
10011
01110
01101
01011
00111
I am guessing i should use a recursive algorithms but i am just not seeing it. I am writing this algorithm in C++.
Any help would be appreciated!
Just start with 00111 and then use std::next_permutation to generate the rest:
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string s = "00111";
do
{
std::cout << s << '\n';
}
while (std::next_permutation(s.begin(), s.end()));
}
output:
00111
01011
01101
01110
10011
10101
10110
11001
11010
11100
You can split up the combinations into those starting with 1 (n-1, k-1) and those starting with 0 (n-1, k).
This is essentially the recursive formula for the choose function.
What you want is actually a combination since the 1's and 0's are indistinguishable and therefore their order doesn't matter (e.g. 1 1 1 vs 1 1 1).
I recently had to rewrite a combination function myself because my initial version was written recursively in a very straightforward way (pick an element, get all the combinations of the remaining array, insert the element in various places) and did not perform very well.
I searched StackOverflow and just seeing the pictures in this answer lit up the iconic lightbulb over my head.
If you want to do this recursively, observe that the set of permutations you want is equal to all the ones that start with "1", together with all the ones that start with "0". So in calculating (n,k), you will recurse on (n-1,k-1) and (n-1,k), with special cases where k = 0 and k = n.
This recursion is the reason that the binomial coefficients appear as the values in Pascal's triangle.
Homework and recursive algorithm? OK, here you go:
Base case:
You have two elements, name them "a" and "b" and produce the concatenations ab, then ba.
Step: If your second Element is longer than 1, split it up in first field/letter and the other part, and pass that recursively as parameters to the function itself.
That will work for any strings and arrays.
Its about 0-1 permutations, so probably its much more eficient to iteratively increment an integer and in case it has desired bits count, print out its binary representation.
Here a sketch:
void printAllBinaryPermutations(int k, int n)
{
int max = pow(2, n) - 1;
for(int i=0; i<=max;i++)
{
if(hasBitCountOf(i, k)) // i has k 1's?
{
printAsBinary(i, n);
}
}
}
bool hasBitCountOf(int v, int expectedBitCount)
{
int count = 0;
while(v>0 && count<= expectedBitCount)
{
int half = v >> 1;
if(half<<1 != v)
{
// v is odd
count++;
}
v = half;
}
return count==expectedBitCount;
}
void printAsBinary(int number, int strLen)
{
for(int i=strLen-1; i>=0; i--)
{
bool is0 = (number & pow(2,i)) == 0;
if (is0)
{
cout<<'0';
}
else
{
cout<<'1';
}
}
cout<<endl;
}
I am not sure this helps, plus it is just some weird pseudocode, but this should give you the desired ouput.
permutation (prefix, ones, zeros, cur) {
if (ones + zeros == 0) output(cur);
else {
if (cur != -1) prefix = concat(prefix,cur);
if (ones > 0) permutation(prefix, ones - 1, zeros, 1);
if (zeros > 0) permutation(prefix, ones, zeros - 1, 0);
}
}
permutation(empty, 3, 2, -1);
greetz
back2dos