![]() |
|
#1
|
|||
|
|||
combinationsHi,
I have a problem to obtain all combinations... The vector lastroute={1, 2, 2, 3} yields 12 combinations (1x2x2x3 = 12) matrix of combinations: a b c d 1 1 1 1 ---> combination 1 1 1 1 2 ---> combination 2... 1 1 1 3 1 1 2 1 1 1 2 2 1 1 2 3 1 2 1 1 1 2 1 2 1 2 1 3 1 2 2 1 1 2 2 2 1 2 2 3 The logic we can see is: the last (d) column vary between 1 and 3. (see lastroute[]) the last-1 (c) column vary between 1 and 2 (but on each column it repeat 3 times because the last column vary between 1 and 3). the last-2 (b) column vary between 1 and 2 (but repeat 6 times each value because the columns d vary up to 3 and c up to 2, then 3x2=6). the last-3 (a) do not vary (but repeat 3x2x2= 12 times). I thought in this way to create a matrix of combinations, my recursive function reserves memory to routes = new int[nroutes*lastroute.size()] = 12x4 => routes = new int[48] and fill it column by column from the last to first column. This strategy runs for small combinations, but I need to treat values like 15.925.248 combinations with 91 columns, or be, I would need a 15.925.248x98 matrix. Thus, the program needs a lot of memory (about 5GB for this matrix) and I need an alternative form to create all combinations. The question is: Can you help-me to obtain the combinations through a line by line strategy and not column by column? In this way I would can obtain the first combination, perform what I want and discard it, obtain the second combination, perform what I want and discard it... and so on. regards, CPIT |
|
#2
|
||||
|
||||
Re: combinationsQuote:
2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 1 2 1 1 2 2 1 2 1 2 2 1 1 2 1 1 1 2 3 2 2 2 2 3 2 2 2 2 3 2 3 3 2 2 3 2 3 etc... I think there are more than 12. __________________
Age is unimportant -- except in cheese |
|
#3
|
|||
|
|||
Re: combinationsQuote:
A couple of things come to mind. I assume you want a generic program that can handle any number of columns with varying numbers of entries in each. First of all, consider an iterative solution. With a fixed number of columns, you have a fixed number of loops. I'll show a program that works with your example. This only works for problems with four columns, but I hope you can see how to generalize it: CPP / C++ / C Code:
Output: Code:
Now, if you want to handle a problem with five columns, you have to change the program (change the arrays and add a fifth nested loop). Note that the innermost loop (the one with j) has nothing to do with generating the combinations; it's just there to see what you have each time through the other loops. I have tried to write it in a way that anyone can see how to create a program with any number of columns. And when I say "anyone", I also mean a program. You could write a program whose output is the C-code (or C++ if you prefer) for a program like this, where the number of columns (and their count values) is an input to the generator program. The generator program could be written in practically any language. (Perhaps perl or java or python or ...) The generator program could be written in C. I'll get you started: CPP / C++ / C Code:
Compiling and executing this, you can see the output program test.c: CPP / C++ / C Code:
I haven't tried to maintain any indentation or other stylistic standards here; the idea is to get something that works. (Automatically generated programs like test.c are, typically, ugly from an human's point of view.) Now, if you compile and execute test.c, you should see something like: Code:
It may or may not be tough to work through generation code for the nested loops, but I think it's a definite possibility. The other possibility that comes to mind: Forget the code generator, forget the 91 nested loops for the 91-column project. Just use recursion. In this case recursion is probably very practical; the code will probably be shorter, and the maximum recursion depth need be no deeper than the number of columns. It may or may not be faster than going through the program generator, and that little issue might be an easy topic for research for the interested student. A number of recursive methods for generating combinations can be found on the web; most are concerned with the number of combinations of n things taken k at a time, and not with your problem, where each of the n things has its own modulus. (You might or might not find specific solutions, but if you get a basic recursive combination generator program running, you might see how to enhance it to suit your requirements. Regards, Dave Regards, Dave |
|
#4
|
|||
|
|||
Re: combinationsThank you for help me.
I tried to implement a recursive form to: CPP / C++ / C Code:
1 1 1 1 1 1 1 2 1 1 1 3 1 1 2 1 1 1 2 2 1 1 2 3 1 2 1 1 1 2 1 2 1 2 1 3 1 2 2 1 1 2 2 2 1 2 2 3 Here is my piece of program in c++ CPP / C++ / C Code:
output 1 1 1 1 1 1 1 2 1 1 2 1 1 1 2 2 1 2 1 1 1 2 1 2 1 2 2 1 1 2 2 2 But the output is wrong and I'm not getting my mistakes. regards, CPIT |
|
#5
|
|||
|
|||
Re: combinationsQuote:
I won't try to "fix" the code you showed, since recursive techniques are kind of hard to get ones brain around sometimes, and everyone looks at them a little differently. Here's a way that occurred to me: Start at the leftmost column. Call a routine that displays that column and everything to the right of it by calling that routine recursively. The actual display is done when the recursion reaches the right most column. It's almost easier to do than it is to think about. I will use fixed values of N and the vector of counts just for simplicity. In actuality, these would be inputs to the program. (Command-line inputs, or maybe even from a file.) CPP / C++ / C Code:
Output: Code:
I've done it in C for a couple of reasons: Everyone can play along (I know this is the C++ board, but this program doesn't really need any C++ features). It emphasises the fact that no new arrays are needed as the recursion proceeds. Using a vector instead of an array would allow you to write the funciton it without having to pass the size of the array (the number of columns) as an argument, but the basic operation would be the same. Note that if you did it with a vector in C++, the vector parameters would be declared as "pass by reference", since the method I showed uses the original array (vector) throughout, and does not allocate more array (vector) storage within the function. Now, the implementation is simple but the function merely prints all of the required combinations. Your application, if I understand it, would need a function that, once initialized, would supply a new combination every time it is called. Recursive procedures like this are not particularly well suited for this application. I am trying to envision ways to set it up with some static variables that would allow the function to generate a single combination and then "keep its place" so that the next call would supply the next. I can think of a thing or two that might be worth pursuing, but I think that for purposes of testing, I would simply compile this program as a standalone process (with user inputs that would allow the program to get the value of N and then N values for the array (vector) that I call "col". Then in a program that needed the output from this program, I would open a pipe and use fgets to read a line at a time from the combinations program. Then I would use sscanf() or some such thing to get the values into the main program to use as it needs. CPP / C++ / C Code:
Code:
Note that I make no claims of optimality or even of suitability. It's a learning process, and I start with methods that occur to me and that are easy to implement and easy to test, There are, perhaps, many more elegant (or in some cases, less elegant but more efficient) methods. Some may even be "prettier", but ya gotta start somewhere, and this is where I choose to start. Your Mileage May Vary. I would be very interested to see examples and elaborations of alternatives. Regards, Dave Last edited by davekw7x : 13-Oct-2006 at 23:02.
|
|
#6
|
|||
|
|||
Re: combinationsMy previous response showed a complicated (but correct, I claim) way to generate the combinations with loops. It required a separate nested loop for each column of the vector. You can't do that in C directly, so I showed an approach that used a code generator function to actually write a C program that had the proper number of loops properly structured to do the deed.
Seeing that approach made me think immediately of an approach using recursion (something that I usually avoid ---primarily for reasons of documentation and maintenance--- unless there is a clear advantage). Here, I present a non-recursive approach that is shorter and simpler than the original one, and can be implemented directly in C or C++, since it only uses two loops, and I will hide one of the loops in a function. The idea is to create a "word" (a vector or array) with as many elements as you have columns. Start with values of the elements equal to 1. That's the first word. To create the next word, then increment the word as follows: Code:
Here's an example, along the lines of my previous ones: CPP / C++ / C Code:
Output: Code:
Regards, Dave |
Recent GIDBlog
Meeting the local Iraqis by crystalattice
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| combinations of elements on vectors | cpit | C++ Forum | 2 | 28-Sep-2006 04:36 |
| How to interpret characters as they are being entered? | nkhambal | C Programming Language | 18 | 14-Feb-2006 10:41 |
| paging file control | cpit | C++ Forum | 10 | 03-Feb-2006 13:18 |
| [c++] number combinations | balusss | C++ Forum | 8 | 11-Dec-2005 22:41 |
| String Combination Algorithm | yevi | C++ Forum | 2 | 13-Jan-2005 08:02 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The