muis2002
asked on
Algorithm (Combination)
Anyone know any good algorithm to print all "N" combinations from 13?
What I meant of combination is like this :
numbers = 0,1,2,3,4,5,6,7,8,9,10,11, 12
5 combination from numbers :
0,1,2,3,4
0,1,2,3,5
0,1,2,3,6
0,1,2,3,7
...
... etc.
The sequence is not important. So, because you have 0,1,2,3,4, you do not need to output 1,2,3,4,0
I am not good in math, so maybe the correct terms is not combination.
What I meant of combination is like this :
numbers = 0,1,2,3,4,5,6,7,8,9,10,11,
5 combination from numbers :
0,1,2,3,4
0,1,2,3,5
0,1,2,3,6
0,1,2,3,7
...
... etc.
The sequence is not important. So, because you have 0,1,2,3,4, you do not need to output 1,2,3,4,0
I am not good in math, so maybe the correct terms is not combination.
Lesko987,
Sorry, a few sintax errors. Here is corrected one.
Var I1, I2, I3, I4, I5, MinNum, MaxNum: Integer; S : String;
Begin
MinNum := 0;
MaxNum := 12;
For I1 := MinNum To MaxNum - 4 Do
For I2 := I1 To MaxNum - 3 Do
For I3 := I2 To MaxNum - 2 Do
For I4 := I3 To MaxNum - 1 Do
For I5 := I4 To MaxNum Do Begin
S := IntToStr (I1) + ',' + IntToStr (I2) + ',' + IntToStr (I3) + ',' + IntToStr (I4) + ',' + IntToStr (I5);
// depending on where you want to write
WriteLn (S);
End;
End;
Regards Aleš
Sorry, a few sintax errors. Here is corrected one.
Var I1, I2, I3, I4, I5, MinNum, MaxNum: Integer; S : String;
Begin
MinNum := 0;
MaxNum := 12;
For I1 := MinNum To MaxNum - 4 Do
For I2 := I1 To MaxNum - 3 Do
For I3 := I2 To MaxNum - 2 Do
For I4 := I3 To MaxNum - 1 Do
For I5 := I4 To MaxNum Do Begin
S := IntToStr (I1) + ',' + IntToStr (I2) + ',' + IntToStr (I3) + ',' + IntToStr (I4) + ',' + IntToStr (I5);
// depending on where you want to write
WriteLn (S);
End;
End;
Regards Aleš
ASKER
Not correct unfortunately.
I printed some of the first result :
0,0,0,0,0
0,0,0,0,1
0,0,0,0,2
0,0,0,0,3
0,0,0,0,4
0,0,0,0,5
0,0,0,0,6
0,0,0,0,7
0,0,0,0,8
0,0,0,0,9
0,0,0,0,10
0,0,0,0,11
0,0,0,0,12
I printed some of the first result :
0,0,0,0,0
0,0,0,0,1
0,0,0,0,2
0,0,0,0,3
0,0,0,0,4
0,0,0,0,5
0,0,0,0,6
0,0,0,0,7
0,0,0,0,8
0,0,0,0,9
0,0,0,0,10
0,0,0,0,11
0,0,0,0,12
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
+ 1 was missing.
Var I1, I2, I3, I4, I5, MinNum, MaxNum: Integer; S : String;
Begin
MinNum := 0;
MaxNum := 12;
For I1 := MinNum To MaxNum - 4 Do
For I2 := I1 + 1 To MaxNum - 3 Do
For I3 := I2 + 1 To MaxNum - 2 Do
For I4 := I3 + 1 To MaxNum - 1 Do
For I5 := I4 + 1 To MaxNum Do Begin
S := IntToStr (I1) + ',' + IntToStr (I2) + ',' + IntToStr (I3) + ',' + IntToStr (I4) + ',' + IntToStr (I5);
// depending on where you want to write
WriteLn (S);
End;
End;
Var I1, I2, I3, I4, I5, MinNum, MaxNum: Integer; S : String;
Begin
MinNum := 0;
MaxNum := 12;
For I1 := MinNum To MaxNum - 4 Do
For I2 := I1 + 1 To MaxNum - 3 Do
For I3 := I2 + 1 To MaxNum - 2 Do
For I4 := I3 + 1 To MaxNum - 1 Do
For I5 := I4 + 1 To MaxNum Do Begin
S := IntToStr (I1) + ',' + IntToStr (I2) + ',' + IntToStr (I3) + ',' + IntToStr (I4) + ',' + IntToStr (I5);
// depending on where you want to write
WriteLn (S);
End;
End;
// Here is a completely different approach!
// + you can change "TheSampleSize" (default 5 items), "TheNumber of elements" (default 13 items), and
// the "elements" could be almost anything; not just consecutive numbers from 0..12.
//
// Flexibility, I like it.
//
const
maxelements: integer=13;
samplesize: integer=5;
elements: array[1..13] of string=( ' 0',' 1',' 2',' 3',' 4',' 5',' 6',' 7',' 8',' 9','10','11','12');
procedure TForm1.Button1Click(Sender : TObject);
var
i1,i2,i3: Integer;
s1: String;
sall: String;
begin
sall:='';
// memo1.Lines.clear;
for i2:=1 to maxelements do sall:=sall+elements[i2]+', ';
for i1:=1 to maxelements-(samplesize-2) do
begin
for i2:=1 to maxelements do
begin
s1:='';
for i3:=1 to pred(samplesize) do
s1:=s1+elements[i1+i3-1]+' ,';
if ((i1=1) or ((i1>1) and (abs(i2-i1)>1))) then
if pos(elements[i2]+',',s1)=0 then
begin
s1:=s1+elements[i2];
// memo1.Lines.add(s1);
writeln(s1);
end;
end;
end;
end;
// + you can change "TheSampleSize" (default 5 items), "TheNumber of elements" (default 13 items), and
// the "elements" could be almost anything; not just consecutive numbers from 0..12.
//
// Flexibility, I like it.
//
const
maxelements: integer=13;
samplesize: integer=5;
elements: array[1..13] of string=( ' 0',' 1',' 2',' 3',' 4',' 5',' 6',' 7',' 8',' 9','10','11','12');
procedure TForm1.Button1Click(Sender
var
i1,i2,i3: Integer;
s1: String;
sall: String;
begin
sall:='';
// memo1.Lines.clear;
for i2:=1 to maxelements do sall:=sall+elements[i2]+',
for i1:=1 to maxelements-(samplesize-2)
begin
for i2:=1 to maxelements do
begin
s1:='';
for i3:=1 to pred(samplesize) do
s1:=s1+elements[i1+i3-1]+'
if ((i1=1) or ((i1>1) and (abs(i2-i1)>1))) then
if pos(elements[i2]+',',s1)=0
begin
s1:=s1+elements[i2];
// memo1.Lines.add(s1);
writeln(s1);
end;
end;
end;
end;
Although I don't have time to create a fully coded solution, I did something similar as part of an NP Complete problem (EE question Q_20908880 in the MSAccess forum).
If anyone is interested in doing a Delphi implementation of this is welcome to do so. Here are the elements of this solution.
1. Create a bitCount[0..255] array of byte or short integer datatype;
2. Fill the bitCount array items with a loop from 1 to 255. The zero position is already = 0. For each of the first 8 bit positions in the iteration variable for this loop, check for the presence of a 1 at each position.
Example:
for J := 1 to 255 do begin
count := 0;
for I := 0 to 7 do begin
//do an AND bitwise operation
if ((J AND (2^I)) <> 0) then
count := count +1;
end;
bitCount[J] := count;
end;
3. Allocate a four byte array. (Fourbytes[0..3])
4. Look for all numeric values whose binary representation contains the number of bits you are looking for. (in this question, this is 5 items out of a 12 item list)
for J := (2^5-1) to (2^12-1) do begin
Fourbytes[0] := ntohl(J); // you might need to copy the bytes
if (bitCount[Fourbytes[0]]+bi tCount[Fou rbytes[1]] +bitCount[ Fourbytes[ 2]]+bitCou nt[Fourbyt es[3]] ) = 5 do begin
// do your output here associating the 1 bit positions with the
// items in your list
end;
end;
========================
Notes:
* This works for all list sizes up to 30 items and all items between 1 and the list size.
* Once the bitCount table is initialized, this process is FAST
* The ntohl is required to reverse the bytes of a long iteger in the Windows little-endian environment. ntohl is a Windows API.
* If you match the order of the long integer bytes with the order of the items in your list, you should be able to just (memory) copy the long integer bytes to the FourBytes array space.
* This is a flexible implementation.
* Counting bits efficiently was one of the keys to solving this problem in a reasonable amount of time.
If anyone is interested in doing a Delphi implementation of this is welcome to do so. Here are the elements of this solution.
1. Create a bitCount[0..255] array of byte or short integer datatype;
2. Fill the bitCount array items with a loop from 1 to 255. The zero position is already = 0. For each of the first 8 bit positions in the iteration variable for this loop, check for the presence of a 1 at each position.
Example:
for J := 1 to 255 do begin
count := 0;
for I := 0 to 7 do begin
//do an AND bitwise operation
if ((J AND (2^I)) <> 0) then
count := count +1;
end;
bitCount[J] := count;
end;
3. Allocate a four byte array. (Fourbytes[0..3])
4. Look for all numeric values whose binary representation contains the number of bits you are looking for. (in this question, this is 5 items out of a 12 item list)
for J := (2^5-1) to (2^12-1) do begin
Fourbytes[0] := ntohl(J); // you might need to copy the bytes
if (bitCount[Fourbytes[0]]+bi
// do your output here associating the 1 bit positions with the
// items in your list
end;
end;
========================
Notes:
* This works for all list sizes up to 30 items and all items between 1 and the list size.
* Once the bitCount table is initialized, this process is FAST
* The ntohl is required to reverse the bytes of a long iteger in the Windows little-endian environment. ntohl is a Windows API.
* If you match the order of the long integer bytes with the order of the items in your list, you should be able to just (memory) copy the long integer bytes to the FourBytes array space.
* This is a flexible implementation.
* Counting bits efficiently was one of the keys to solving this problem in a reasonable amount of time.
<<...maybe the correct terms is not combination>>
It is the correct term for N things taken P at a time.
The formula for this is: N! / (P! * ((N-P)!) )
So you can expect to 1287 items (13 things taken 5 at a time)
It is the correct term for N things taken P at a time.
The formula for this is: N! / (P! * ((N-P)!) )
So you can expect to 1287 items (13 things taken 5 at a time)
You must create 5 loops
Var I1, I2, I3, I4, I5, MinNum, MaxNum: Integer
Begin
MinNum := 0;
MaxNum := 12
For I1 := MinNum To MaxNum - 4 Do
For I2 := I1 To MaxNum - 3 Do
For I3 := I2 To MaxNum - 2 Do
For I4 := I3 To MaxNum - 1 Do
For I5 := I4 To MaxNum Do Begin
S := IntToStr (I1) + ',' + IntToStr (I2) + ',' + IntToStr (I3) + ',' + IntToStr (I4) + ',' + IntToStr (I5);
// depending on where you want to write
WriteLn (S);
End;
Regards Aleš