ALI, вот код, который я использовал для проверки (Metrowerks codewarrior 8.0):
Код:
#include <windows.h>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
//------------------------------------
class permutation1
{
vector<int> _current;
vector<int> _avaible;
unsigned _stack_level;
static vector<pair<unsigned,unsigned> > _program;
static unsigned _gp_count, _gp_size, _stats;
permutation1(unsigned size);
permutation1(
const permutation1& prev,
unsigned value_avaible,
unsigned value_permuted);
void exec();
public:
static void main(unsigned gp_count, unsigned gp_size);
};
vector<pair<unsigned,unsigned> > permutation1::_program;
unsigned permutation1::_gp_count, permutation1::_gp_size, permutation1::_stats;
void permutation1::main(unsigned gp_count, unsigned gp_size)
{
if (gp_size && gp_count)
{
_gp_count = gp_count;
_gp_size = gp_size;
_stats = 0;
// составляем программу выборок
_program.reserve(gp_count*gp_size);
unsigned long time1 = GetTickCount();
for (unsigned group1=0; group1<gp_count; ++group1)
{
_program.push_back(make_pair(-1, group1*gp_size));
}
for (unsigned group1=gp_count; 0<group1--; )
{
for (unsigned element1=gp_size; 0<--element1; )
{
unsigned offset1 = group1*gp_size;
_program.push_back(make_pair(offset1, offset1 + element1));
}
}
permutation1(gp_count*gp_size).exec();
unsigned long time2 = GetTickCount();
cout << "permutation count: " << _stats << "\n"
"finished in: " << double(time2-time1)/1000. << " seconds\n";
}
else
{
throw invalid_argument("permutation1::main nonzero both count and size expected");
}
}
permutation1::permutation1(unsigned size) :
_current(size),
_avaible(size),
_stack_level()
{
for (unsigned n=0; n<size; ++n)
{
_avaible[n] = n;
}
}
permutation1::permutation1(
const permutation1& prev,
unsigned value_avaible,
unsigned value_permuted) :
_current(prev._current),
_avaible(prev._avaible.size()-1),
_stack_level(prev._stack_level+1)
{
copy(prev._avaible.begin() + value_avaible + 1, prev._avaible.end(),
copy(prev._avaible.begin(), prev._avaible.begin() + value_avaible, _avaible.begin()));
_current[value_permuted] = prev._avaible[value_avaible];
}
void permutation1::exec()
{
if (_stack_level < _program.size())
{
pair<unsigned,unsigned>& instr1(_program[_stack_level]);
if (instr1.first != -1)
{
unsigned left_to_fill = instr1.second-instr1.first;
// выбор элементов
for (unsigned element1 = _avaible.size();
left_to_fill <= element1 &&
_current[instr1.first]<_avaible[(--element1)-left_to_fill]; )
{
permutation1(*this,
/*доступный элемент*/ element1,
/*что заменить*/ instr1.second).exec();
}
}
else
{
// выбор групп
unsigned group1=0;
for (; group1<_avaible.size() && _avaible[group1]<=int(instr1.second); ++group1)
{
permutation1(*this, group1, instr1.second).exec();
}
if (_avaible.size()<=group1) throw logic_error("bug found: permutation1::avaible no group candidate");
}
}
else
{
for ( unsigned g=0; g<_gp_count; ++g)
{
cout << "group ";
cout.width(3);
cout << g << ": ";
for ( unsigned f=0; f<_gp_size; ++f)
{
cout.width(4);
cout << _current[g*_gp_size + f];
}
cout << "\n";
}
cout << "\n";
++_stats;
}
}
//------------------------------------
int main()
{
filebuf outbuf;
outbuf.open("output.txt", ios::out|ios::app);
streambuf* coutbuf = cout.rdbuf(&outbuf);
try
{
permutation1::main(7,3);
}
catch(exception& e)
{
clog << e.what() << "\n";
}
cout.rdbuf(coutbuf);
return 0;
}
//------------------------------------
На машинке pentium-4, 1600 МГц, 768 МБ ОЗУ, WinXP sp2 результаты следующие:
использование памяти 384 МБ, в памяти:
система, qip, winamp, IDE компилятора, файловый менеджер, браузер, справочная литература, антивирь и диспетчер задач.. ну и программа конечно.
параметры: 4x3 (итого 12 чел)
сборка debug: 127805 вариантов за 10.359 секунд
сборка release: 127805 вариантов за 2.61 секунд
не захлебнулось ;-)
output: