User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Computer Science and Software Design section within the Software Development category of DaniWeb, a massive community of 391,899 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,583 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Computer Science and Software Design advertiser:
Views: 12572 | Replies: 14
Reply
Join Date: Mar 2006
Posts: 3
Reputation: dirt_bagz is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
dirt_bagz dirt_bagz is offline Offline
Newbie Poster

Question The fastest combination generator

  #1  
Mar 21st, 2006
Dear all,

I am looking for an expert opinion on what the fastest combination generator is. I am currently facing a problem of generating a huge combinations (k elements out of n) and as it stands now, the running time of my program will take more than three years. My current implementation uses the Algorithm R (see Knuth's book pre-fascicle 3a), a revolving-door algorithm.

If anyone knows a better/faster way of enumerating combinations, please let me know. Many thanks.
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Aug 2005
Posts: 4,665
Reputation: iamthwee is just really nice iamthwee is just really nice iamthwee is just really nice iamthwee is just really nice 
Rep Power: 16
Solved Threads: 297
iamthwee's Avatar
iamthwee iamthwee is offline Offline
Industrious Poster

Re: The fastest combination generator

  #2  
Mar 22nd, 2006
Originally Posted by dirt_bagz
Dear all,

I am looking for an expert opinion on what the fastest combination generator is. I am currently facing a problem of generating a huge combinations (k elements out of n) and as it stands now, the running time of my program will take more than three years. My current implementation uses the Algorithm R (see Knuth's book pre-fascicle 3a), a revolving-door algorithm.

If anyone knows a better/faster way of enumerating combinations, please let me know. Many thanks.

Well unless you have access to a quantum computer I doubt you will be able to cut down on run time. Knuth's work is generally accepted as being the best for algorithms and reducing time complexity.

However, you may be looking at your problem in the wrong way. Take for example the classic travelling salesman problem.

Applying a brute force algorithm to calculate the shortest route for a journey with 100+ pit-stops will take an unfathomable amount of time.

However, if you adopt a heuristic approach you can find a high probabilistic solution,within a much smaller time scale.

Perhaps you need to think about approaching your problem from a different angle.

See this:

http://en.wikipedia.org/wiki/Dynamic_programming

Incase anyone wanted to know here is Knuth's algorithm for producing combinations in C.

 
/* Algorithm by Donald Knuth. */
 
#include <stdio.h>
#include <stdlib.h> 
void main( void)
{
	int i, j=1, k, n, *c, x;
	printf( "Enter n,k: ");
	scanf( "%d,%d", &n, &k);
	c = malloc( (k+3) * sizeof(int));
 
	for (i=1; i <= k; i++) c[i] = i;
	c[k+1] = n+1;
	c[k+2] = 0;
	j = k;
visit:
	for (i=k; i >= 1; i--) printf( "%3d", c[i]);
	printf( "\n");
	if (j > 0) {x = j+1; goto incr;}
	if (c[1] + 1 < c[2])
	 {
	 c[1] += 1;
	 goto visit;
	 }
	j = 2;
do_more:
	c[j-1] = j-1;
	x = c[j] + 1;
	if (x == c[j+1]) {j++; goto do_more;}
	if (j > k) exit(0);
incr:
	c[j] = x;
	j--;
	goto visit;
}


And java
 
//CombinationGenerator.java
//--------------------------------------
// Systematically generate combinations.
//--------------------------------------
import java.math.BigInteger;
public class CombinationGenerator {
private int[] a;
private int n;
private int r;
private BigInteger numLeft;
private BigInteger total;
//------------
// Constructor
//------------
public CombinationGenerator (int n, int r) {
	if (r > n) {
	 throw new IllegalArgumentException ();
	}
	if (n < 1) {
	 throw new IllegalArgumentException ();
	}
	this.n = n;
	this.r = r;
	a = new int[r];
	BigInteger nFact = getFactorial (n);
	BigInteger rFact = getFactorial (r);
	BigInteger nminusrFact = getFactorial (n - r);
	total = nFact.divide (rFact.multiply (nminusrFact));
	reset ();
}
//------
// Reset
//------
public void reset () {
	for (int i = 0; i < a.length; i++) {
	 a[i] = i;
	}
	numLeft = new BigInteger (total.toString ());
}
//------------------------------------------------
// Return number of combinations not yet generated
//------------------------------------------------
public BigInteger getNumLeft () {
	return numLeft;
}
//-----------------------------
// Are there more combinations?
//-----------------------------
public boolean hasMore () {
	return numLeft.compareTo (BigInteger.ZERO) == 1;
}
//------------------------------------
// Return total number of combinations
//------------------------------------
public BigInteger getTotal () {
	return total;
}
//------------------
// Compute factorial
//------------------
private static BigInteger getFactorial (int n) {
	BigInteger fact = BigInteger.ONE;
	for (int i = n; i > 1; i--) {
	 fact = fact.multiply (new BigInteger (Integer.toString (i)));
	}
	return fact;
}
//--------------------------------------------------------
// Generate next combination (algorithm from Rosen p. 286)
//--------------------------------------------------------
public int[] getNext () {
	if (numLeft.equals (total)) {
	 numLeft = numLeft.subtract (BigInteger.ONE);
	 return a;
	}
	int i = r - 1;
	while (a[i] == n - r + i) {
	 i--;
	}
	a[i] = a[i] + 1;
	for (int j = i + 1; j < r; j++) {
	 a[j] = a[i] + j - i;
	}
	numLeft = numLeft.subtract (BigInteger.ONE);
	return a;
}
}


 
/*
* test.java
*
* Created on 14 January 2006, 16:29
*/
/**
*
* @author iamthwee
*/
public class test {
 
	/** Creates a new instance of test */
	public test() {
	}
 
	/**
	 * @param args the command line arguments
	 */
	public static void main(String[] args) {
		String[] elements = {"a", "b","c","d"};
int[] indices;
CombinationGenerator x = new CombinationGenerator (elements.length, 2);
StringBuffer combination;
while (x.hasMore ()) {
combination = new StringBuffer ();
indices = x.getNext ();
for (int i = 0; i < indices.length; i++) {
	combination.append (elements[indices[i]]);
}
System.out.println (combination.toString ());
}
 
	}
 
}
 
Member of: F-ugly code club

Join today don't delay!
Reply With Quote  
Join Date: Mar 2006
Posts: 3
Reputation: dirt_bagz is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
dirt_bagz dirt_bagz is offline Offline
Newbie Poster

Re: The fastest combination generator

  #3  
Mar 22nd, 2006
Originally Posted by iamthwee
Well unless you have access to a quantum computer I doubt you will be able to cut down on run time. Knuth's work is generally accepted as being the best for algorithms and reducing time complexity.

However, you may be looking at your problem in the wrong way. Take for example the classic travelling salesman problem.

Applying a brute force algorithm to calculate the shortest route for a journey with 100+ pit-stops will take an unfathomable amount of time.

However, if you adopt a heuristic approach you can find a high probabilistic solution,within a much smaller time scale.

Perhaps you need to think about approaching your problem from a different angle.

See this:

http://en.wikipedia.org/wiki/Dynamic_programming

Incase anyone wanted to know here is Knuth's algorithm for producing combinations in C.

 
/* Algorithm by Donald Knuth. */
 
#include <stdio.h>
#include <stdlib.h> 
void main( void)
{
	int i, j=1, k, n, *c, x;
	printf( "Enter n,k: ");
	scanf( "%d,%d", &n, &k);
	c = malloc( (k+3) * sizeof(int));
 
	for (i=1; i <= k; i++) c[i] = i;
	c[k+1] = n+1;
	c[k+2] = 0;
	j = k;
visit:
	for (i=k; i >= 1; i--) printf( "%3d", c[i]);
	printf( "\n");
	if (j > 0) {x = j+1; goto incr;}
	if (c[1] + 1 < c[2])
	 {
	 c[1] += 1;
	 goto visit;
	 }
	j = 2;
do_more:
	c[j-1] = j-1;
	x = c[j] + 1;
	if (x == c[j+1]) {j++; goto do_more;}
	if (j > k) exit(0);
incr:
	c[j] = x;
	j--;
	goto visit;
}


And java
 
//CombinationGenerator.java
//--------------------------------------
// Systematically generate combinations.
//--------------------------------------
import java.math.BigInteger;
public class CombinationGenerator {
private int[] a;
private int n;
private int r;
private BigInteger numLeft;
private BigInteger total;
//------------
// Constructor
//------------
public CombinationGenerator (int n, int r) {
	if (r > n) {
	 throw new IllegalArgumentException ();
	}
	if (n < 1) {
	 throw new IllegalArgumentException ();
	}
	this.n = n;
	this.r = r;
	a = new int[r];
	BigInteger nFact = getFactorial (n);
	BigInteger rFact = getFactorial (r);
	BigInteger nminusrFact = getFactorial (n - r);
	total = nFact.divide (rFact.multiply (nminusrFact));
	reset ();
}
//------
// Reset
//------
public void reset () {
	for (int i = 0; i < a.length; i++) {
	 a[i] = i;
	}
	numLeft = new BigInteger (total.toString ());
}
//------------------------------------------------
// Return number of combinations not yet generated
//------------------------------------------------
public BigInteger getNumLeft () {
	return numLeft;
}
//-----------------------------
// Are there more combinations?
//-----------------------------
public boolean hasMore () {
	return numLeft.compareTo (BigInteger.ZERO) == 1;
}
//------------------------------------
// Return total number of combinations
//------------------------------------
public BigInteger getTotal () {
	return total;
}
//------------------
// Compute factorial
//------------------
private static BigInteger getFactorial (int n) {
	BigInteger fact = BigInteger.ONE;
	for (int i = n; i > 1; i--) {
	 fact = fact.multiply (new BigInteger (Integer.toString (i)));
	}
	return fact;
}
//--------------------------------------------------------
// Generate next combination (algorithm from Rosen p. 286)
//--------------------------------------------------------
public int[] getNext () {
	if (numLeft.equals (total)) {
	 numLeft = numLeft.subtract (BigInteger.ONE);
	 return a;
	}
	int i = r - 1;
	while (a[i] == n - r + i) {
	 i--;
	}
	a[i] = a[i] + 1;
	for (int j = i + 1; j < r; j++) {
	 a[j] = a[i] + j - i;
	}
	numLeft = numLeft.subtract (BigInteger.ONE);
	return a;
}
}


 
/*
* test.java
*
* Created on 14 January 2006, 16:29
*/
/**
*
* @author iamthwee
*/
public class test {
 
	/** Creates a new instance of test */
	public test() {
	}
 
	/**
	 * @param args the command line arguments
	 */
	public static void main(String[] args) {
		String[] elements = {"a", "b","c","d"};
int[] indices;
CombinationGenerator x = new CombinationGenerator (elements.length, 2);
StringBuffer combination;
while (x.hasMore ()) {
combination = new StringBuffer ();
indices = x.getNext ();
for (int i = 0; i < indices.length; i++) {
	combination.append (elements[indices[i]]);
}
System.out.println (combination.toString ());
}
 
	}
 
}
 

Dear iamthwee, thanks for your response. I understand that there is a probabilistic way of looking at this problem. However, for my this particular problem, probabilistic solution is not acceptable. This problem is similar to the search for optimum Golomb Ruler of certain marks or minimum distance computation in linear error correcting codes. As you can see here, in order to prove something, a non probabilistic solution is required. Anyway, many thanks.
Reply With Quote  
Join Date: Aug 2005
Posts: 4,665
Reputation: iamthwee is just really nice iamthwee is just really nice iamthwee is just really nice iamthwee is just really nice 
Rep Power: 16
Solved Threads: 297
iamthwee's Avatar
iamthwee iamthwee is offline Offline
Industrious Poster

Re: The fastest combination generator

  #4  
Mar 23rd, 2006
>This problem is similar to the search for optimum Golomb Ruler Well finding a solution AND proving it is quite beyond me. Oh dear brain lock...:cry: Sorrie.
Member of: F-ugly code club

Join today don't delay!
Reply With Quote  
Join Date: Mar 2006
Posts: 219
Reputation: Lord Soth is an unknown quantity at this point 
Rep Power: 3
Solved Threads: 2
Lord Soth's Avatar
Lord Soth Lord Soth is offline Offline
Posting Whiz in Training

Re: The fastest combination generator

  #5  
Mar 26th, 2006
Hi,

Do you need a solution which is in a smaller time complexity class than Knuth's or have a bound for n,k and just need a faster code to get it done in less than 3 years ? +what is the maximum acceptable time span for you ? because I have some ideas for optimization which can reduce your 3 year but not for n limit to infinity.

Loren Soth
Reply With Quote  
Join Date: Mar 2006
Posts: 3
Reputation: dirt_bagz is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
dirt_bagz dirt_bagz is offline Offline
Newbie Poster

Re: The fastest combination generator

  #6  
Mar 26th, 2006
Hi Loren Soth,

Thanks for your response. I just need a faster code to get my computation done. The value of n does not go to infinity, in fact n <= 512 and 1 <= k <= n/2. If possible, I would like to have to computation done in less than 1 year. Well, 1 year may seem rather long, but I probably can run this computation in parallel using many computers. Hope to hear your optimisation ideas soon.

dirt_bagz.


Originally Posted by Lord Soth
Hi,

Do you need a solution which is in a smaller time complexity class than Knuth's or have a bound for n,k and just need a faster code to get it done in less than 3 years ? +what is the maximum acceptable time span for you ? because I have some ideas for optimization which can reduce your 3 year but not for n limit to infinity.

Loren Soth
Reply With Quote  
Join Date: Jun 2006
Location: Bangalore, India
Posts: 1
Reputation: sandysat is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
sandysat sandysat is offline Offline
Newbie Poster

Re: The fastest combination generator

  #7  
Jun 30th, 2006
Hi there!...I'd like to point you to http://www.merriampark.com/comb.htm
I don't know if it's any faster than your current considerations but hope it'll open up some more avenues for thinking...
rgds,
Sandeep
Reply With Quote  
Join Date: Jul 2007
Posts: 1
Reputation: piagina is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
piagina piagina is offline Offline
Newbie Poster

Re: The fastest combination generator

  #8  
Jul 13th, 2007
I doubt it is as fast as the Knuth code but here is a slightly more modern version of a combination generator using some features of C++ so I guess its C++

nb. if you copy the code and run it you may like to change the lines that set j and k as this currently give all possible combinations of the letters of the English alphabet.

#include <iostream>
#include <vector>
#include <string>

using namespace std;

// just to check the numbers are right

long totalcombs(int n, int r){
	long c=1;
	if (r > n) return 0;
	for (long d=1; d <= r; d++) {
		c *= n--;
		c /= d;
	}
	return c;
}

// example code to get all combination 

int main(){
	vector<int> indx;
	string alpha("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
	int n=26;
	int j=1;
	int k=26;
	for(int twk=j;twk<=k;twk++){
		int r=twk;
		int total=totalcombs(n,r);
		int ccount=1;
		bool done=true;
		for(int iwk=0;iwk<r;iwk++)indx.push_back(iwk);
		while(done){
			done=false;
			cout << ccount++ << " of " << total << " ";
			for(int owk=0;owk<r;owk++){
				cout << alpha[indx[owk]] << " ";
			}
			cout << endl;
			for(int iwk=r-1;iwk>=0;iwk--){
				if(indx[iwk]<=(n-1)-(r-iwk)){
					indx[iwk]++;
					for(int swk=iwk+1;swk<r;swk++){
						indx[swk]=indx[swk-1]+1;
					}
					iwk=-1;
					done=true;
				}	
			}	
		}
		cout << " --------------------------- " << endl;
		indx.clear();
	}
	return 0;
}
Reply With Quote  
Join Date: Dec 2007
Posts: 2
Reputation: wwx is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
wwx wwx is offline Offline
Newbie Poster

Re: The fastest combination generator

  #9  
Dec 8th, 2007
Does the problem resolved ? Can you describe what you're doing ? Generate C(N,1..N/2) ?
Reply With Quote  
Join Date: May 2006
Location: ★ ijug.net ★
Posts: 834
Reputation: ithelp is on a distinguished road 
Rep Power: 4
Solved Threads: 61
ithelp ithelp is offline Offline
Practically a Posting Shark

Re: The fastest combination generator

  #10  
Dec 9th, 2007
It is an NP complete problem , so you can only get some approximation algorithm to get it faster.
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

DaniWeb Computer Science and Software Design Marketplace
Thread Tools Display Modes

Similar Threads
Other Threads in the Computer Science and Software Design Forum

All times are GMT -4. The time now is 7:30 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC