Minimal Weight
A. First(Second, Third) Edition
This is the programming assignment of comp6661 and we are requested to use "revolving door algorithm" to find minimal
weight for an error-correcting-code. I struggled for a whole day and finally finished as planned even though a little bit
more time than expected.
[first version]
1. Using revolve-door unrank function in textbook to generate index array for
subset combination. So, by incrementing rank
one by one, we can iterate all subset. This method is comparatively a bit slow
than other "successor" function.
However, I am using it with purpose to make a distributed program.
[improved version]
1. Improved on basis of first version so that two consecutive subset combination
don't need calculate repeated xor. Instead
I compare the difference in two subsets and use previous result to xor with two
changed vector. In order to keep both
current and previous subset combination, I use two integer array, oddArray and
evenArray, and use a pointer to point to
them alternatively depending whether the current rank is odd or even.
[MPI version]
1. Based on second version and use MPI to distribute computation to other nodes.
My idea is straight forward. If we can
start any computation by giving a rank, then we can divide the total computation
job with different range of rank. That's
why I implement my algorithm by using "unrank" function.
2. Root node read from data file and broadcast n,k,d and vector to all other
nodes.
3. Then all slave nodes start computation by iterate all subset size from 1 to
k. And each node knows its part of range
because of its MPI_Rank. For example, for n=32,k=16,d=7 the total number of
combination of subset 5 is (16,5)=11440. If
MPI_Size=9 which means 8 slave nodes, then each node will be given a range of
11440/8 and they don't need further instruction
from root node and can start working as soon as they receive all setup
information.
4. I choose to let root node be specializing in listening to simplify
programming because we don't know when and which node
will report discovery. So, we have to use non-blocking "recv" method in MPI. If
I give computation job to root node, I have
to use multi-thread for listening which is too complicated and has only
suspicious performance gain. Therefore, the root
node will "post" a recieve request to all slave nodes and then "test" requests
in a loop. The slave nodes will first answer
"yes" or "no" to discovery. If "yes", it will send combination of vector which
has smaller weight than d seperately. If "no",
no further informatio is sent. By counting "no" replies or receiving "yes"
reply, root node can decide if we find or not.
[platform]
Originally I write my program in windows and in order to run and test in Linux,
I have to change some data type. For example,
in windows, "size_t" is one of primitive type while in Linux, I have to typedef
it to "unsigned int". And in windows, I am
using VC++ special type __int64 which is 64 bit integer while in Linux, I have
to type define it to "long long". So, if you
need to run them in windows, comment out those typedef's in "myset.h".
In both text book and Knuth's notes, there are generating algorithms for subset of order of minimal change. However, I
choose unusual "unrank" function to implement it which is not efficient. There is another simple reason apart from that MPI
mentioned above. It is the only thing I can work out!. I even tried both algorithms and repeatedly got error. Then I suspected
both of them. And time is ticking. I only got one whole day for this program because I must leave some time for theory and
possible testing, documenting. So, I have to give it up. And you can find the commented Knuth's code. Efficient and
terrible with no offence. You see, his style is typical assembly language like and I both envy and hate.
The only useful, stupid and painful tip I got is that in windows VC++ long is not __int64 and it is only meaningful in java.
In VC++, long is similar to int and the counterpart of __int64 in Linux is long long.
E.Further improvement
F.File listing
MPI-version:
const size_t DefaultGroundSetSize=32;//4*8=32
const size_t DigitBitCount=sizeof(size_t)*8;//one byte
const size_t DefaultBitState=0;
const size_t HashTableSize=256;
const size_t DeleteMask=0xFFFFFFFF;
const size_t ComplementMask=DeleteMask;
const size_t SetOrderMask=0xFF;
const size_t SetOrderMaskCount=sizeof(size_t)/sizeof(HashTableType);
const size_t MaxGroundSetSize=1024;
const size_t MaxDigitCount=MaxGroundSetSize/8/sizeof(size_t);
size_t fact(size_t size);
size_t combine(size_t n, size_t k);
class MySet
{
public:
//constructor
MySet(size_t size=DefaultGroundSetSize);
~MySet();
//copy constructor
MySet(const MySet& copy);
//basic set operations
//unary operations
bool MemberOfSet(size_t index) const;
void SetInsert(size_t index);
void SetDelete(size_t index);
size_t SetOrder();
MySet Complement();
//binary operations
MySet Union(const MySet& other);
MySet Intersection(const MySet& other);
MySet Difference(const MySet& other);
//operator overloading
//set assignment
MySet& operator=(const MySet& other);
MySet& operator=(const size_t* array);
//xor operation
MySet& operator^(const MySet& other);
bool operator==(const MySet& other);
bool operator[](size_t index);
//utility operations
void display() const;
void initialize(size_t size);
void randomSet();
size_t getSize(){ return groundSetSize;}
void flip(size_t index);
void createByArray(size_t array[], size_t arraySize);
//special set utility operations
size_t LexRank();
void LexUnrank(size_t number);
//subset utility
//lexico
size_t SubsetLexRank(size_t subsetSize);
void SubsetLexUnRank(size_t subsetSize, size_t rank);
void SubsetLexSuccessor(size_t subsetSize);
//colex
void SubsetColexSuccessor(size_t subsetSize);
int getDigitCount()const {return digitCount;}
protected:
static HashTableType hashTable[HashTableSize];
static bool need2hash;
int groundSetSize;
size_t digitCount;
size_t* digits;
//int lastDigitSize;
void initHashTable();
void checkSize(size_t index)const;
void checkSize(const MySet& other) const;
void setSize(size_t size);//this should not be called by user!!!! try initialize(i);
void clear();
};
#endif
file name: myset.cpp
#include "myset.h"
#include <iostream>
//typedef int* set ;
using namespace std;
//pure for testing
long lastResult;
HashTableType MySet::hashTable[256];
bool MySet::need2hash=true;
MySet::MySet(size_t size)
{
groundSetSize=0;
initialize(size);
//because we only need to initialize hash table once for all set objects
if (need2hash)
{
initHashTable();
need2hash=false;
}
}
MySet::~MySet()
{
delete[]digits;
}
//a copy constructor
MySet::MySet(const MySet& copy)
{
//set groundsetsize to 0 to indicate this is the first time creating set
groundSetSize=0;
initialize(copy.groundSetSize);
for (size_t i=0; i<digitCount; i++)
{
digits[i]=copy.digits[i];
}
}
void MySet::initHashTable()
{
size_t i, j;
//int lowIndex=0, highIndex=1;
//initialize half byte first
hashTable[0]=0;
hashTable[1]=1;
hashTable[2]=1;
hashTable[3]=2;
hashTable[4]=1;
hashTable[5]=2;
hashTable[6]=2;
hashTable[7]=3;
for (i=0; i<8; i++)
{
hashTable[8+i]=hashTable[i]+1;
}
//initialize one byte and use it as a pattern in following
for (i=1; i<16; i++)
{
for (j=0; j<16; j++)
{
hashTable[i*16+j]=hashTable[i]+hashTable[j];
}
}
}
void MySet::display() const
{
cout<<"\n[";
for (int i=0; i<groundSetSize; i++)
{
if (MemberOfSet(i))
{
cout<<"1";
}
else
{
cout<<"0";
}
}
cout<<"]\n";
}
void MySet::checkSize(size_t index) const
{
if (index>=groundSetSize)
{
cout<<"error exceeding boundary";
exit(1);
}
}
//difference=A intersection complement(B)
MySet MySet::Difference(const MySet& other)
{
checkSize(other);
MySet result=other;
result.Complement();
return Intersection(result);
}
MySet MySet::Complement()
{
for (size_t i=0; i<digitCount; i++)
{
digits[i] ^= ComplementMask;
}
return *this;
}
//element starts from 1 instead of 0
bool MySet::MemberOfSet(size_t index) const
{
size_t i,j;
checkSize(index);
i=index/DigitBitCount;
j=index%DigitBitCount;
return (digits[i]>>j)&1==1;
}
//assume element is starting from 1 instead of 0
void MySet::SetInsert(size_t index)
{
size_t i,j;
checkSize(index);
i=index/DigitBitCount;
j=index%DigitBitCount;
digits[i]|=(((size_t)1)<<j);
}
//assume element starts from 1 instead of 0
void MySet::SetDelete(size_t index)
{
size_t i,j;
size_t mask=DeleteMask;
checkSize(index);
i=index/DigitBitCount;
j=index%DigitBitCount;
mask^=(1<<j);
digits[i]&=mask;
}
void MySet::checkSize(const MySet& other) const
{
if (groundSetSize!=other.groundSetSize)
{
cout<<"two set has different ground set size!\n";
exit(1);
}
}
//return value instead of dynamic new memory
MySet MySet::Union(const MySet& other)
{
checkSize(other);
//choose the bigger groundsetsize of two
MySet result(groundSetSize);
for (size_t i=0; i<digitCount; i++)
{
result.digits[i]=digits[i] | other.digits[i];
}
return result;
}
//set assignment maybe use set variable with old data
MySet& MySet::operator =(const MySet& other)
{
//initialize(other.groundSetSize);
for (size_t i=0; i<digitCount; i++)
{
digits[i]=other.digits[i];
}
return *this;
}
MySet& MySet::operator =(const size_t* array)
{
for (size_t i=0; i<digitCount; i++)
{
digits[i]=array[i];
}
return *this;
}
MySet& MySet::operator ^(const MySet& other)
{
for (size_t i=0; i<digitCount; i++)
{
digits[i]^=other.digits[i];
}
return *this;
}
//set is equal only when the ground set size is equal and all element equal
bool MySet::operator ==(const MySet& other)
{
if (groundSetSize!=other.groundSetSize)
{
return false;
}
for (size_t i=0; i<digitCount; i++)
{
if (digits[i]!=other.digits[i])
{
return false;
}
}
return true;
}
//set intersection
MySet MySet::Intersection(const MySet& other)
{
checkSize(other);
MySet result(groundSetSize);
for (size_t i=0; i<digitCount; i++)
{
result.digits[i]=digits[i]&other.digits[i];
}
return result;
}
size_t MySet::SetOrder()
{
size_t result=0;
size_t index;
for (size_t i=0; i<digitCount; i++)
{
for (size_t j=0; j<SetOrderMaskCount; j++)
{
index=(digits[i]>>(j*8))&SetOrderMask;
result+=hashTable[index];
}
} return result; } void MySet::flip(size_t index) { size_t i,j; checkSize(index); i=index/DigitBitCount; j=index%DigitBitCount; digits[i]^=((size_t)1<<j); } void MySet::setSize(size_t size) { groundSetSize=size; //DigitBitCount=ByteSize=8 digitCount=groundSetSize/DigitBitCount; //last digit size is stored so that calculation will only be //done once for all //if modulo 8==0, we don't need extra digit if (groundSetSize%DigitBitCount!=0) { digitCount++; } } void MySet::initialize(size_t size) { //DefaultBitState is 0 for unset; if (size>0) { if (groundSetSize>=size) { //we don't have to reallocate memory setSize(size); } else { if (groundSetSize!=0) { delete[]digits; } setSize(size); digits= new size_t[digitCount]; if (digits==NULL) { cout<<"unable allocate memory for ground set size of "<<groundSetSize<<endl; exit(1); } } //memset(digits, DefaultBitState, digitCount); for (size_t i=0; i<digitCount; i++) { digits[i]=0; } //memset(digits, 0, digitCount); } else { groundSetSize=digitCount=0; digits=NULL; } } //colex void MySet::SubsetColexSuccessor(size_t subsetSize) { size_t result=0, i,j; size_t* array; if (SetOrder()!=subsetSize) { cout<<"subset size is not what it should be!\n"; exit(1); } //first create an index array array=new size_t[subsetSize+1]; array[0]=0; j=0; //translate into index array for (i=groundSetSize; i>=1; i--) { if (MemberOfSet(i-1)) { array[j+1]=i; j++; } } i=1; while (i<=subsetSize&&array[i]==groundSetSize-i+1) { i++; } if (i==subsetSize+1) { cout<<"undefined"; } else { result=array[i]; for (j=i; j<=subsetSize; j++) { array[j]=result+1-(j-i); } j=subsetSize; for (i=0; i<groundSetSize; i++) { if (i+1==array[j]) { SetInsert(i); j--; } else { SetDelete(i); } } } delete[]array; } //this is limited within groundset size of 32 or less //the order is lexicographic order void MySet::SubsetLexUnRank(size_t subsetSize, size_t rank) { size_t x=1, temp; if (subsetSize>groundSetSize) { cout<<"wrong subset size!\n"; exit(1); } clear(); for (size_t i=1; i<=subsetSize; i++) { temp=combine(groundSetSize-x, subsetSize-i); while (temp<=rank) { rank-=temp; x++; temp=combine(groundSetSize-x, subsetSize-i); } SetInsert(x-1); x++; } } //this is limited within groundset size of 32 or less //the order is lexicographic order void MySet::SubsetLexSuccessor(size_t subsetSize) { size_t result=0, i,j; size_t* array; if (SetOrder()!=subsetSize) { cout<<"subset size is not what it should be!\n"; exit(1); } //first create an index array array=new size_t[subsetSize+1]; array[0]=0; j=0; //translate into index array for (i=0; i<groundSetSize; i++) { if (MemberOfSet(i)) { array[j+1]=i+1; j++; } } i=subsetSize; while (i>=1&&array[i]==(groundSetSize-subsetSize+i)) { i--; } if (i==0) { cout<<"undefined"; } else { result=array[i]; for (j=i; j<=subsetSize; j++) { array[j]=result+1+j-i; } j=1; for (i=0; i<groundSetSize; i++) { if (i+1==array[j]) { SetInsert(i); j++; } else { SetDelete(i); } } } delete[]array; } //this is limited within groundset size of 32 or less //the order is lexicographic order size_t MySet::SubsetLexRank(size_t subsetSize) { size_t result=0, i,j; size_t* array; if (SetOrder()!=subsetSize) { cout<<"subset size is not what it should be!\n"; exit(1); } //first create an index array array=new size_t[subsetSize+1]; array[0]=0; j=0; //translate into index array for (i=0; i<groundSetSize; i++) { if (MemberOfSet(i)) { array[j+1]=i+1; j++; } } for (i=1; i<=subsetSize; i++) { if (array[i-1]+1<array[i]) { for (j=array[i-1]+1; j<array[i]; j++) { result+=combine(groundSetSize-j, subsetSize-i); } } } delete []array; return result; } void MySet::createByArray(size_t array[], size_t arraySize) { //let's have a simple groundsetsize as for initialize(arraySize*sizeof(size_t)*8); for (size_t i=0; i<digitCount; i++) { digits[i]=array[i]; } } //I would leave big number problem to future size_t MySet::LexRank() { //temporarily I would assume there is only a small set return digits[0]; } //I would wait for future for big ground set problem void MySet::LexUnrank(size_t number) { initialize(sizeof(size_t)*8); digits[0]=number; } void MySet::randomSet() { for (size_t i=0; i<digitCount; i++) { digits[i]=rand(); } } bool MySet::operator [](size_t index) { return MemberOfSet(index); } void MySet::clear() { size_t mask=0; for (size_t i=0; i<digitCount; i++) { digits[i]=mask; } } size_t fact(size_t size) { size_t result=1; for (int i=2; i<=size; i++) { result*=i; } return result; } size_t combine(size_t n, size_t k) { size_t result=1; if (n<k) { cout<<"combine number is wrong!\n"; exit(1); } for (int i=0; i<k; i++) { result*=(n-i); } return result/fact(k); }
file name: revolve.h
#include <iostream>
#include "myset.h"
using namespace std;
void revolveUnRank(long theRank, size_t subSize);
void readFromFile(char* fileName);
bool weightTest(__int64 startRank, __int64 count, int subSize);
void initialize(size_t theN, size_t theK, size_t theD, size_t* array);
__int64 combineNumber(size_t n, size_t k);
//void algoR(size_t t);
file name: revolve.cpp
#include "revolve.h"
#include "myset.h"
#include <iostream>
#include <fstream>
using namespace std;
extern long lastResult;
size_t groundsetSize, subsetSize;
size_t n, k, d;
size_t* buffer;
size_t bufferSize;
MySet* sets;
MySet current;
size_t* oddArray=NULL;
size_t* evenArray=NULL;
__int64 combineNumber(size_t n, size_t k)
{
__int64 result =1;
for (size_t i=0; i<k; i++)
{
result=result*(n-i)/(i+1);
}
lastResult=result;
return result;
}
void revolveUnRank(__int64 theRank, size_t subSize)
{
__int64 last=-1, curr=-1, r=theRank;
int i;
size_t x=groundsetSize;
subsetSize=subSize;
size_t* c;
if (theRank%2==0)
{
c=evenArray;
}
else
{
c=oddArray;
}
for (i=subsetSize; i>=1; i--)
{
do
{
last=curr;
curr=combineNumber(x, i);
if (curr>r)
{
x--;
}
else
{
break;
}
}while (true);
if (last==r)
{
c[i-1]=x-1;
}
else
{
c[i-1]=x;
}
r=last-r-1;
}
/*
cout<<"now show rank="<<theRank<<endl;
for ( i=0; i<subsetSize; i++)
{
cout<<revolveArray[i]+1<<",";
}
cout<<"\n";
*/
}
int findSmallest(int& oddIndex, int& evenIndex)
{
while (oddIndex<subsetSize&&evenIndex<subsetSize)
{
if (oddArray[oddIndex]==evenArray[evenIndex])
{
oddIndex++;
evenIndex++;
}
else
{
if (oddArray[oddIndex]<evenArray[evenIndex])
{
//must make easy for next
return oddArray[oddIndex++];
}
else
{
return evenArray[evenIndex++];
}
}
}
if (oddIndex==evenIndex&&oddIndex==subsetSize)
{
cout<<"find smallest failed, check array!\n";
exit(1);
}
else
{
if (oddIndex<evenIndex)
{
return oddArray[oddIndex];
}
else
{
return evenArray[evenIndex];
}
}
}
void findChangedVectorIndex(int& first, int& second)
{
int oddIndex=0, evenIndex=0;
first=findSmallest(oddIndex, evenIndex);
second=findSmallest(oddIndex, evenIndex);
}
bool weightTest(__int64 startRank, __int64 count, int subSize)
{
subsetSize=subSize;
int left, right;
size_t* c;
for (__int64 i=0; i<count; i++)
{
revolveUnRank(startRank+i, subSize);
if ((startRank+i)%2==0)
{
c=evenArray;
}
else
{
c=oddArray;
}
if (i==0)
{
current=sets[c[0]];
for (int j=1; j<subSize; j++)
{
current^(sets[c[j]]);
}
}
else
{
findChangedVectorIndex(left, right);//not the index of array
current^(sets[left]);
current^(sets[right]);
}
if (current.SetOrder()<d)
{
cout<<"this is for test:\n";
for (int m=0; m<subSize; m++)
{
cout<<c[m]<<",";
}
return false;
}
}
return true;
}
void initialize(size_t theN, size_t theK, size_t theD, size_t* array)
{
groundsetSize=theK;
n=theN;
k=theK;
d=theD;
sets=new MySet[k];
for (int i=0; i<k; i++)
{
sets[i].initialize(n);
sets[i]=array+(i*sets[i].getDigitCount());
}
current.initialize(n);
oddArray=new size_t[n+1];
evenArray=new size_t[n+1];
}
void readFromFile(char* fileName)
{
//size_t* array;
size_t temp, size, mask=1;
int i, j;
int number;
ifstream in(fileName);
in>>n;
in>>k;
in>>d;
size=n/32;
if (n%32!=0)
{
size++;
}
bufferSize=size*k;
buffer=new size_t[bufferSize];
for (i=0; i<k; i++)
{
number=-1;//the number of int
for (j=0; j<n; j++)
{
if (j%32==0)
{
number++;
buffer[i*size+number]=0;
}
in>>temp;
if (temp!=0)
{
buffer[i*size+number] |= (mask<<j);
}
}
}
}
/*
void algoR(size_t t)
{
size_t j;
size_t* c=revolveArray;
c[0]=0;
for (j=1; j<=t; j++)
{
c[j]=j-1;
}
c[t+1]=n;
R2:
for (size_t i=0; i<t+1; i++)
{
cout<<c[i]<<",";
}
cout<<"\n";
if (t%2==1)
{
if (c[1]+1<c[2])
{
c[1]++;
goto R2;
}
else
{
j=2;
goto R4;
}
}
else
{
if (c[1]>0)
{
c[1]--;
goto R2;
}
else
{
j=2;
goto R5;
}
}
R4:
if (c[j]>=j)
{
c[j]=c[j-1];
c[j-1]=c[j-2];
goto R2;
}
else
{
j++;
}
R5:
if (c[j]+1<c[j+1])
{
c[j-1]=c[j];
c[j]++;
goto R2;
}
else
{
j++;
if (j<=t)
{
goto R4;
}
}
}
*/
test files:
1. test0.txt
2. test1.txt
3. test2.txt
4. test3.txt
5. test4.txt
6. test5.txt
file name: test0.txt
7 4 4
1 0 0 0 1 1 0
0 1 0 0 1 0 1
0 0 1 0 0 1 1
0 0 0 1 1 1 1
file name: test1.txt 23 12 8 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 1 1 1 0 0 0
file name: test2.txt
24 12 8
1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1
0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 1 0
0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 1 0 1
0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 1 1
0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 1 1 0
0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0 1 1 0 1
0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 1 1
0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 1
0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 1 0 1 1 1 0
0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 1 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 1 1 1 0 0 0 1
file name: test3.txt
32 16 7
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 1
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 0 0 1 0 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 0 0 1 1
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 0 1 1 0 0 1 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 1 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 1 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 1 1
file name: test4.txt
48 24 12
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 0 1
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 1
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 1 1
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 0 0 1 0 1 1 0 0 1
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 0 0 1 0 1 1 0 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 0 0 1 0 1 1 1
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 0 1 1 1 1 0 0 0 0 1 1 0 1
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 1 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1
file name: test5.txt
72 36 12
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 1
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1 0 1 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 1 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1 0 1 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 1 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 0 1 1 0 0 1 0 0 1 1 1 0 1
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 0 1 1 0 0 1 0 0 1 1 1 1
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 1 1
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 1 0 1 1 0 0 0 1 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 0 1 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 1 1 1 0 1 1 1 0 0 0 0 1 0 1 1 1 0 1 0 0 1 1 0 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 1 0 0 0 1 1 0 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 1 1
(There are originally more test cases but I haven't even finished running test5!)
A snapshot of running automated testing:
[testing result]
1. The following is running result of those simple test cases. The data file "test*.txt" is ordered by course website except
that "test0.txt" is hamming code with d=4 for testing.
2. All following test cases finishes very soon. Even the test4.txt
D:\Program Files\Microsoft Visual Studio\MyProjects\MySet\Debug>myset test0.txt
[1000110]
[0100101]
[0010011]
[0001111]
now try subset of 1
we find a weight smaller than d=4with such combination:
0,current is:
[1000110]
this means we cannot find a weight smaller than d=4
D:\Program Files\Microsoft Visual Studio\MyProjects\MySet\Debug>myset test1.txt
[10000000000001111111111]
[01000000000011101110001]
[00100000000011011100010]
[00010000000010111000101]
[00001000000011110001011]
[00000100000011100010110]
[00000010000011000101101]
[00000001000010001011011]
[00000000100010010110111]
[00000000010010101101110]
[00000000001011011011100]
[00000000000110110111000]
now try subset of 1
we find a weight smaller than d=8with such combination:
2,current is:
[00100000000011011100010]
D:\Program Files\Microsoft Visual Studio\MyProjects\MySet\Debug>myset test3.txt
[10000000000000001110001100001001]
[01000000000000000111000110000101]
[00100000000000000011100011000011]
[00010000000000001111111101101000]
[00001000000000000111111110110100]
[00000100000000000011111111011010]
[00000010000000001111110011100101]
[00000001000000000111111001110011]
[00000000100000001101110000110000]
[00000000010000000110111000011000]
[00000000001000000011011100001100]
[00000000000100000001101110000110]
[00000000000010001110111011001011]
[00000000000001001001010001101100]
[00000000000000100100101000110110]
[00000000000000011100011000010011]
now try subset of 1
now try subset of 2
now try subset of 3
now try subset of 4
now try subset of 5
now try subset of 6
now try subset of 7
now try subset of 8
now try subset of 9
now try subset of 10
now try subset of 11
now try subset of 12
now try subset of 13
now try subset of 14
now try subset of 15
now try subset of 16
this means we cannot find a weight smaller than d=7
D:\Program Files\Microsoft Visual Studio\MyProjects\MySet\Debug>
D:\Program Files\Microsoft Visual Studio\MyProjects\MySet\Debug>myset test4.txt
[100000000000000000000000111101110110111000110001]
[010000000000000000000000011110111011011100011001]
[001000000000000000000000001111011101101110001101]
[000100000000000000000000000111101110110111000111]
[000010000000000000000000111110000001100011010010]
[000001000000000000000000100010110110001001011001]
[000000100000000000000000010001011011000100101101]
[000000010000000000000000001000101101100010010111]
[000000001000000000000000111001100000001001111010]
[000000000100000000000000100001000110111100001101]
[000000000010000000000000010000100011011110000111]
[000000000001000000000000110101100111010111110010]
[000000000000100000000000100111000101010011001001]
[000000000000010000000000010011100010101001100101]
[000000000000001000000000001001110001010100110011]
[000000000000000100000000111001001110010010101000]
[000000000000000010000000011100100111001001010100]
[000000000000000001000000001110010011100100101010]
[000000000000000000100000111010111111001010100101]
[000000000000000000010000011101011111100101010011]
[000000000000000000001000110011011001001010011000]
[000000000000000000000100011001101100100101001100]
[000000000000000000000010001100110110010010100110]
[000000000000000000000001111011101101110001100011]
now try subset of 1
now try subset of 2
now try subset of 3
now try subset of 4
now try subset of 5
now try subset of 6
now try subset of 7
now try subset of 8
now try subset of 9
now try subset of 10
now try subset of 11
now try subset of 12
now try subset of 13
now try subset of 14
now try subset of 15
now try subset of 16
now try subset of 17
now try subset of 18
now try subset of 19
now try subset of 20
now try subset of 21
now try subset of 22
now try subset of 23
now try subset of 24
this means we cannot find a weight smaller than d=12
D:\Program Files\Microsoft Visual Studio\MyProjects\MySet\Debug>