The realization of the combination algorithm __ algorithm

Source: Internet
Author: User

"Problem" combinatorial problem
Problem Description: Find all combinations of r numbers from natural numbers 1, 2 、... 、 N. For example, all combinations of n=5,r=3 are:

1,2,3
1,2,4
1,3,4
2,3,4
1,2,5
1,3,5
2,3,5
1,4,5
2,4,5
3,4,5

There are several ways to implement a program:
1) The method of exhaustive

Procedures are as follows
Program
#include <stdio.h>
const int n=5,r=3;
int i,j,k,counts=0;

int main ()
{
for (i=1;i<=r; i++)
for (j=i+1;j<=r+1;j++)
for (k=j+1;k<=r+2;k++) {
counts++;
printf ("%4d%4d%4d/n", i,j,k);
}
printf ("%d", counts);
return 0;
}
But this program has a problem, when r changes, the cyclic weight change, which affects the solution of the problem, that is, there is no general.


2) Recursive method
This recursive idea can be used to consider the algorithm of the combined function in the 10 combinations listed in the analysis.
Set the function to void comb (int m,int k) to find all groups with a K number from the natural number 1, 2 、... 、 m
Collection When the first number in the group is selected, the following number is a combination of k-1 numbers from the remaining number of m-1. This
The combinatorial problem of K number in M number is transformed into the combinatorial problem of finding the number of k-1 in the number of m-1. Set Function Primer
into the work array a[] holds the number of the calculated combination, and the contract function puts the first digit of the combination of k numbers that is determined
In A[k], a combination of a[is output when a combination is obtained. The first number can be M, m-1,
..., k, when the function determines that the first number of a combination is placed in an array, there are two possible choices, since the top group has not yet been
The rest of the elements, continue to be determined by the recursive return, or because all the elements of the combination have been determined, output this combination. Details
See the function comb in the following program.
Program
#include <time.h>
#include <iostream>

using namespace Std;

# define MAXN 100
int A[MAXN];
int counts=0;

void Printtime (void)//function to print the current time
{
Char tmpbuf[128];
time_t Ltime;
struct TM *today;

Time (&ltime);
Today = LocalTime (&ltime);
Strftime (tmpbuf,128, "%y-%m-%d%h:%m:%s", today);
cout<<tmpbuf<<endl;
}


void comb (int m,int k)
{int i,j;
for (i=m;i>=k;i--)
{a[k]=i;
if (k>1)
Comb (i-1,k-1);
Else
{
counts++;
/*
for (j=a[0];j>0;j--)
printf ("%4d", A[j]);
printf ("n");
*/
}
}
}

int main ()
{

int m,r;
cout<< "M" <<endl;
cin>>m;
cout<< "R" <<endl;
cin>>r;
counts=0;
A[0]=r;
Printtime ();
Comb (m,r);
cout<<counts<<endl;
Printtime ();
return 0;
}


This is the program I found on the Internet, slightly modified. The program writes very concise, also has the universality, solves the question.

3) Backtracking method

Using backtracking method to find the solution of the problem, will find the combination of small to large in order to deposit in a[0],a[1],...,a[r-1]
, the grouped elements meet the following properties:

(1) A[i+1]>a[i], the latter number is larger than the previous one;
(2) a[i]-i<=n-r+1.
According to the thought of backtracking method, the process of finding solution can be described as follows:
The condition that the combination number of R is discarded first, the candidate combination begins with only one number 1. Because the candidate
The solution satisfies all conditions except the scale of the problem, expands its scale and satisfies the above conditions (1), the candidate combination
Changed to 1, 2. Continue this process and get the candidate combination 1,2,3. This candidate solution satisfies the problem scale including the whole
Part condition, thus is a solution. On the basis of the solution, the next candidate solution is selected, as 3 of the a[2] is adjusted to 4 to
And then adjust to 5 to meet all the requirements of the problem, get the solution 1,2,4 and 1,2,5. Due to 5 can not be adjusted
The whole, from a[2] back to a[1], at this time, a[1]=2, can be adjusted to 3, and forward test, get solution 1, 3,
4. Repeat the above forward and backward backtracking until you are back from a[0], stating that you have found all the problems
Solution.

I never found a complete program to perform properly on the internet, so I had to spend a day writing this program myself, and changing the output starting at 0 instead of starting at 1, the purpose of this program is to extend the application, to accommodate the needs of C + + language, This way the output can be used as the address sequence of the combined array to select, and you can find a combination of R for an array of any type of length n. I have optimized it, if you think there is a place to optimize, please enlighten,. ^_^

#include <time.h>
#include <iostream>
#include <iomanip>
using namespace Std;

# define MAXN 100
int A[MAXN]; Locates an array that indicates the location of the selected element collection array, and selects the element collection array 0 start
void Comb (int m,int R)
{
int cur;//indicates which member of the anchored array is moving in

unsigned int count=0;

Initializes the location array, where 0 starts, the selection must be position 0,1,2
for (int i=0;i<r;i++)
A[i]=i;

Cur=r-1;//is currently the last member to move in

do{
if (a[cur]-cur<=m-r) {

count++;
/*
for (int j=0;j<r;j++)
COUT&LT;&LT;SETW (4) <<a[j];
cout<<endl;
*/
a[cur]++;

Continue
}
else{
if (cur==0) {
cout<<count<<endl;
Break
}

a[--cur]++;
for (int i=1;i<r-cur;i++) {
A[cur+i]=a[cur]+i;
}

if (a[cur]-cur<m-r)
Cur=r-1;
}
}while (1);
}

void Printtime (void)//function to print the current time
{
Char tmpbuf[128];
time_t Ltime;
struct TM *today;

Time (&ltime);
Today = LocalTime (&ltime);
Strftime (tmpbuf,128, "%y-%m-%d%h:%m:%s", today);
cout<<tmpbuf<<endl;
}

int main (int argc, char *argv[])
{

int m,r;
cout<< "M" <<endl;
cin>>m;
cout<< "R" <<endl;
cin>>r;
Printtime ();
Comb (m,r);
Printtime ();
return (0);
}

Compared with the recursive procedure above, it is also optimized with g++ O2. When the n=40,r=11, shielding out the output, the results are 2311801440 items, the recursive program took 23-24 seconds, backtracking 19-20 seconds.

4) using array

Definition:Take a combination of m numbers from the n number.
Implementation mechanism:First, create an array of strings whose subscript represents the number of 1 to N, and the value of 1 for the array element indicates that the number of its subscript is selected, and 0 is not selected.
It then initializes the first M element of the array to 1, representing the number of former m in the initial group.
Then scan the array element values from left to right in 10 combinations, after the first "10" is found, the position of 1 and 0 is changed to 01, and then the 10 and 1 before the combination of 0 are combined (1 in front, the number is 10 before the combination of 1, 0 is placed behind, the number is 10 before 0, And then a 10 inverted combination of 01). When M 1 is all moved to the right end, the last combination is obtained.
For example, find a combination of 3 in 5:
1 1 1 0 0//1,2,3
1 1 0 1 0//1,2,4
1 0 1 1 0//1,3,4
0 1 1 1 0//2,3,4
1 1 0 0 1//1,2,5
1 0 1 0 1//1,3,5
0 1 1 0 1//2,3,5
1 0 0 1 1//1,4,5
0 1 0 1 1//2,4,5
0 0 1 1 1//3,4,5

Realize:
C#

public static ArrayList combination (object[] value,int pick)
{
ArrayList list = new ArrayList ();

   string temp = new String (' 1 ', pick);
   temp + = new string (' 0 ', value. Length-pick);
   int pos = temp. IndexOf ("10");
   while (pos >-1)
   {
    object[] v = new object[ Pick];
    int c = 0;
    for (int i = 0; i < value. Length; i++)
    {
     if (temp. Substring (i,1) = = "1")
      v[c++] = value[i];
&NBSP;&NBSP;&NBSP;&NBSP}
    list. Add (v);
    int onecount = 0;
    for (int i = 0; i < POS; i++)
    {
    & Nbsp;if (temp. Substring (i,1) = = "1")
      onecount++;
    .}

temp = new String (' 1 ', Onecount) + new string (' 0 ', Pos-onecount) + "+" + (pos + 2 < temp.) Length? Temp. Substring (pos + 2): "");
pos = temp. IndexOf ("10");
}
object[] V1 = new Object[pick];
int c1 = 0;
for (int i = 0; i < value. Length; i++)
{
if (temp. Substring (i,1) = = "1")
v1[c1++] = Value[i];
}
List. ADD (v1);

return list;
}

JavaScript translation:

String.getcombine = function (M, n) {
return new Array (M + 1). Join (1) + new Array (n-m + 1). Join (0);
}
Array.prototype.combination = function (pick) {
if (pick >= this.length) return [this];
var temp = string.getcombine (pick, this.length);
var list = [];
var pos;
while (pos = Temp.indexof ("ten")) >-1) {
var v = new Array (pick);
var c = 0;
for (var i = 0; i < this.length; i++)
{
if (Temp.charat (i) = = ' 1 ') v[c++] = this[i];
}
List.push (v);
var onecount = 0;
for (var i = 0; i < POS; i++) {
if (Temp.charat (i) = = ' 1 ')
Onecount + +;
}
temp = String.getcombine (Onecount, POS) + "+" + (pos + 2 < temp.length? Temp.substr (pos + 2): ');
}
var v1 = new Array (pick);
var c1 = 0;
for (var i = 0; i < this.length; i++)
{
if (Temp.charat (i) = = ' 1 ')
v1[c1++] = this[i];
}
List.push (v1);

return list;
}


Optimized JavaScript version:

String.getcombine = function (M, n) {
 return new Array (M + 1). Join (1) + new Ar Ray (n-m + 1). Join (0);
}
Array.prototype.combination = function (m) {
 var n = this.length;
 if (M >= N) return [this];
 if (M = = 0 return [[]];
 var temp = string.getcombine (m, n);
 var list = [];
 var POS;
 while (pos = Temp.indexof (')) >-1) {
  var v = [];
  for (var i = 0; i < n; i + +) if (Temp.charat (i) = = ' 1 ') V.push (this[i));
  list.push (v);
  var onecount = 0;
  for (var i= 0; i < POS; i++) if (Temp.charat (i) = = ' 1 ') Onecount + +;
  temp = String.getcombine (Onecount, POS) + ' + ' + temp.substr (pos + 2);
 }
 var v = [];
 for (var i = 0; i < n; i++) if (Temp.charat (i) = = ' 1 ') V.push (this[i));
 list.push (v);
 return list; 
}


ActionScript is equally able to

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.