2010-06-24 3 views
0

큰 문제가 있습니다. 정확한 7 숫자 조합을 생성해야하고 7 forloops를 사용하여 코드를 작성했으며 매우 적은 수의 숫자로도 잘 작동합니다. 첨부 파일을 확인하여 실제로 필요한 항목을 분명히 확인하십시오. PHP 결과를 제공하십시오.루프 속도를 줄이는 방법

<?php 
// I need the combinations for this commented numbers 
// 1, 7, 13, 19, 25, 31, 2, 8, 14, 20, 26, 32, 3, 9, 15, 
// 21, 27, 33, 4, 10, 16, 22, 28, 34, 5, 11, 17, 23, 29, 
// 35, 6, 12, 18, 24, 30, 36 
$string=array(1,7,13,19,25,31,2,8,14,20,26,32,3,9,15,21,27,33,4,10,16,22,28,34); 
$len=count($string); 
$c=0; 
ob_start(); 
for ($e = 0; $e < $len - 6; $e++) 
{ 
    for ($f = $e+1; $f < $len - 5; $f++) 
    { 
     for ($g = $f+1; $g < $len - 4; $g++) 
     { 
      for ($h = $g+1; $h < $len - 3; $h++) 
      { 
       for ($i = $h+1; $i < $len - 2; $i++) 
       { 
        for ($j = $i + 1; $j < $len - 1; $j++) 
        { 
         for ($k = $j + 1; $k < $len; $k++) 
         { 
          $c++; 
          $output[] = $string[$e] . "," . 
             $string[$f] . "," . 
             $string[$g] . "," . 
             $string[$h] . "," . 
             $string[$i] . "," . 
             $string[$j] . "," . 
             $string[$k]; 
          ob_flush(); 
         } 
         ob_flush(); 
        } 
        ob_flush(); 
       } 
       ob_flush(); 
      } 
      ob_flush(); 
    } 
    ob_flush(); 
} 
ob_flush(); 
} 
echo count($output); 
?> 

그리고 아래에서 언급 한 것과 같은 출력이 필요합니다. 출력 :

passed numbers $string=array(1, 7, 13, 19, 25, 31, 2, 8, 14) and the out put is below 
count of combinations = 36 
Array 
(
    [0] => 1,7,13,19,25,31,2 
    [1] => 1,7,13,19,25,31,8 
    [2] => 1,7,13,19,25,31,14 
    [3] => 1,7,13,19,25,2,8 
    [4] => 1,7,13,19,25,2,14 
    [5] => 1,7,13,19,25,8,14 
    [6] => 1,7,13,19,31,2,8 
    [7] => 1,7,13,19,31,2,14 
    [8] => 1,7,13,19,31,8,14 
    [9] => 1,7,13,19,2,8,14 
    [10] => 1,7,13,25,31,2,8 
    [11] => 1,7,13,25,31,2,14 
    [12] => 1,7,13,25,31,8,14 
    [13] => 1,7,13,25,2,8,14 
    [14] => 1,7,13,31,2,8,14 
    [15] => 1,7,19,25,31,2,8 
    [16] => 1,7,19,25,31,2,14 
    [17] => 1,7,19,25,31,8,14 
    [18] => 1,7,19,25,2,8,14 
    [19] => 1,7,19,31,2,8,14 
    [20] => 1,7,25,31,2,8,14 
    [21] => 1,13,19,25,31,2,8 
    [22] => 1,13,19,25,31,2,14 
    [23] => 1,13,19,25,31,8,14 
    [24] => 1,13,19,25,2,8,14 
    [25] => 1,13,19,31,2,8,14 
    [26] => 1,13,25,31,2,8,14 
    [27] => 1,19,25,31,2,8,14 
    [28] => 7,13,19,25,31,2,8 
    [29] => 7,13,19,25,31,2,14 
    [30] => 7,13,19,25,31,8,14 
    [31] => 7,13,19,25,2,8,14 
    [32] => 7,13,19,31,2,8,14 
    [33] => 7,13,25,31,2,8,14 
    [34] => 7,19,25,31,2,8,14 
    [35] => 13,19,25,31,2,8,14 
) 
+3

실제로 코드 목적이 무엇인지 설명하고 싶을 수도 있습니다. –

+2

그래요, 코드의 목적을 자세히 설명해 주시면 거의 긍정적입니다./ – RobertPitt

+1

주제, 설명 및 코드 예제간에 가능한 연결이 전혀 보이지 않습니다 ... –

답변

8
function factorial($factVal) { 
    $factorial = 1; 
    while ($factVal > 1) { 
     $factorial *= $factVal--; 
    } 
    return $factorial ; 
} 

function permutations($numObjs,$numInSet) { 
    return round(factorial($numObjs)/factorial($numObjs - $numInSet)); 
} 

function combinations($numObjs,$numInSet) { 
    return round(factorial($numObjs)/factorial($numObjs - $numInSet))/factorial($numInSet); 
} 


$string=array(1,7,13,19,25,31,2,8,14,20,26,32,3,9,15,21,27,33,4,10,16,22,28,34); 
echo 'Number of Combinations = '.combinations(count($string),7).'<br />'; 
echo 'Number of Permutations = '.permutations(count($string),7).'<br />'; 
+2

수학의 실제 사용을위한 만세! –

+0

안녕하세요 mate 배열에서 조합 번호도 필요합니다. 다른 계산을 위해서 필요합니다. 이것 좀 도와주세요 – kamlesh

+0

@kamlesh 다른 계산 방법. 전체 목록을 작성하면 꽤 빨리 메모리를 날려 버릴 것이고 다른 계산을 수행하는 데 더 좋은 방법이있을 것입니다. –

0

내가 당신에게 내가 더 높은 조합 전에 이런 짓을했고 대신 중첩 된 루프를 사용하는 RECURSIVE FUNCTIONS를 사용할 필요가 있음을 알 수 있습니다 전체 코드를 제공하지 못할 그겁니다.

재귀 함수는 ... 당신이 이런 일을 할 수있는, 당신이 실제로 조합을 원하는 경우 7

NLV

+2

수학은 36에서 7보다 훨씬 높은 수치로 작업 할 수 있으며, 재귀보다 훨씬 빠릅니다. –

+0

확실히 받아들입니다! – NLV

+0

메이트 나는 당신이 카운트를 가지고있는 콤비네이션을위한 배열을 생성 할 필요가있다. 나는 이미 콤비네이션의 수를 얻고 그 카운트의 콤비네이션을 생성하는 코드를 가지고있다. 내 코드는 완전히 정확하지만 내 코드는 36 개의 numbers에 대한 출력을 생성하는 데 너무 오랜 시간이 걸립니다. 따라서이 코드를 최적화하는 솔루션이 필요합니다. 그렇지 않으면 내 코드와 동일한 출력을 생성하는 다른 간단한 방법이 필요합니다. 최근 편집 된 게시물을 확인하십시오. 당신은 내가 코드에서 기대하는 바를 알게 될 것입니다. 사전에 감사드립니다 – kamlesh

0

을 넘어 당신에게

  • 주 1 유연성을 제공 :이를 주문한 결과와 순열을 줄 것입니다.
  • 참고 2 : 카운트 만 필요한 경우 Mark의 대답을 사용하십시오.
  • 주 3 :이 전혀 테스트되지 않으므로 일부는 등의 오류가 여기에

을 상쇄가있을 수 있습니다 간다 : 매개 변수의

function combinations($set,$length) { 
    $combinations = array(); 

    for($i = 0, $n = count($set); $i <= ($n - $length); $i++) { 
    $combination = array(); 
    $combination[] = $set[$i]; 

    if($length > 1) { 
     $combination = array_merge(
     $combination, 
     combinations(array_slice($set,1+$i), $length-1) 
    ); 
    } 

    $combinations[] = $combination; 
    } 

    return $combinations; 
} 

$allCombinations = combinations($allYourNumbers, 7); 

편집 변경된 순서가 array_slice하는

+0

안녕하세요, 안녕하세요, 내가 이걸 출력 할 때 빈 배열을 얻고 있습니다 경고 : array_slice()는 배열 1 일 때 array_slice()가 G : \ xampp \ htdocs \ pick1 \ lottocom.php의 줄에 정수가 올것을 기대합니다 – kamlesh

+0

잘못된 순서 array_slice에 매개 변수. 오프셋, 배열에서 오프셋으로 변경되었습니다. –

+0

메이트 나는이 모든 일을했지만 빈 배열에 약간의 오류가 있습니다. 최근 편집 된 게시물을 확인하십시오. 당신은 내가 코드에서 기대하는 바를 알게 될 것입니다. – kamlesh

0

당신의 질문을 이해할 수 있을지 모르겠지만, 배열에서 숫자가 "왼쪽에서 오른쪽으로"구할 수있는 모든 숫자 조합을 생성하고 싶습니다. 즉, 정렬 된 숫자 배열을 사용한다고 가정 해 보겠습니다. 1에서 50까지) 그리고 첫 번째 숫자가 이미 4이면 모든 후속 숫자는 4보다 커야하고 두 번째 숫자가 12이면 모든 후속 숫자는 12보다 커야합니다.

실제로 이러한 조합의 수는 너무 커서 어떤 알고리즘을 사용하든 배열 크기에 상관없이 모든 숫자를 생성하는 데 너무 오래 걸립니다. 그들은 너무 많습니다. 당신이 n 번호 중 m 번호를 가지고가는 경우에

, 당신은 (binomial(n,m)nm의 이항 계수 임) 그렇게 할 binomial(n,m) 많은 가능성을 가지고있다.

따라서 특히 귀하의 경우는 binomial(n,7)이 재미 있습니다. 그러나 이항 계수는 정말로 빠르게 증가하는 함수입니다. 나는. 매개 변수를 조금만 크게하면 결과가 훨씬 커집니다.

binomial(9,7) = 36 
binomial(10,7) = 120 
binomial(11,7) = 330 
binomial(12,7) = 792 
... 
binomial(15,7) = 6435 
binomial(20,7) = 77520 
binomial(30,7) = 2035800 

30 개의 숫자로 이미 많은 가능성이 있으며, 모두를 나열하는 데 시간이 걸립니다. 그렇다면 알고리즘이 얼마나 영리한 지 알 수 있습니다. 배열 크기의 일부 지점에서는 가능성이 희박하기 때문에 포기해야합니다.

나는 C에서 작은 프로그램을 작성 : 당신이하지 인쇄 값을 경우

#define PRINTITEMS 0 

#include <stdio.h> 
#include <stdlib.h> 

typedef struct _comb{ 
    int x1; 
    int x2; 
    int x3; 
    int x4; 
    int x5; 
    int x6; 
    int x7; 
} comb; 

void generateAll7Possibilities(int* a,int n, comb* target){ 
    int i1, i2, i3, i4, i5, i6, i7; 
    int c = 0; 
    for (i1=0; i1<n-6; i1++){ 
    for (i2=i1+1; i2<n-5; i2++){ 
     for (i3=i2+1; i3<n-4; i3++){ 
     for (i4=i3+1; i4<n-3; i4++){ 
      for (i5=i4+1; i5<n-2; i5++){ 
      for (i6=i5+1; i6<n-1; i6++){ 
       for (i7=i6+1; i7<n; i7++){ 
      target[c].x1=a[i1]; 
      target[c].x2=a[i2]; 
      target[c].x3=a[i3]; 
      target[c].x4=a[i4]; 
      target[c].x5=a[i5]; 
      target[c].x6=a[i6]; 
      target[c].x7=a[i7]; 
      if (PRINTITEMS){ 
       printf("%d %d %d %d %d %d %d\n", target[c].x1, target[c].x2, target[c].x3, target[c].x4, target[c].x5, target[c].x6, target[c].x7); 
      } 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 


int main(){ 
    printf("This is enumerator\n"); 
    int array[36]; 
    int i; 
    for (i=0; i<36; ++i){ 
    array[i]=i; 
    printf("%d\n",array[i]); 
    } 
    printf("Starting generation"); 
    comb* target= malloc(sizeof(comb)*8347680); 
    generateAll7Possibilities(array,36,target); 
    printf("Generation finished"); 
} 

위의 프로그램이 잘 실행됩니다. 그러나 값 인쇄를 시작하자 마자 마칠 기회가 없습니다.

출력을 제거하고 가능한 모든 조합을 생성 해보십시오.

+0

예가 맞습니다. 나는 조합이 필요하다. $ string = array (1, 7, 13, 19, 25, 31, 2, 8, 14)의 조합 수이고 출력 수가 조합 수보다 적습니다. Array ([0] => 1 , 7,13,19,25,31,2 [1] => 1,7,13,19,25,31,8 [2] => 1,7,13,19,25,31,14 [3 ] => 1,7,13,19,25,2,8 [4] => 1,7,13,19,25,2,14 [5] => 1,7,13,19,25,8 , 14 [6] => 1,7,13,19,31,2,8 [7] => 1,7,13,19,31,2,14 [8] => 1,7,13,19 , 31,8,14 [9] => 1,7,13,19,2,8,14 [10] => 1,7,13,25,31,2,8 . . . . [35] => 13,19,25,31,2,8,14) – kamlesh

+0

출력 성교 자 수가 조합 수보다 적다고합니다. 이것이 왜 이렇게되어야하는지 설명해 주시겠습니까? 실제로 하위 집합에있는 요소에 대한 요소 만 포함하는 모든 하위 집합을 인쇄하려면이 수가 정확히 조합 수임을 의미합니다. – phimuemue

+0

친구가 아니기 때문에 36 개의 숫자가 미리 정의되어 있지 않습니다. 그래서 사용자 선택에 따라 달라질 수 있습니다. 일부는 예를 들어 (1,101432121820,5,12,8)와 같은 10 개의 숫자를 선택할 수 있으며 일부는 10을 초과 할 수도 있습니다. 그러나 최대 숫자는 36입니다. 따라서 조합은 매번 다를 것이며 나는이 조합들을 저장하지 않을 것이다. 결과 (7 개 숫자)를이 조합과 일치시키고 결과 조합 7과 일치하는 조합 수를 가져 와서 데이터베이스에 저장합니다. 이제 모든 사람들이이 문제로 분명해질 수 있습니다. – kamlesh

0

다음은 조합 세트에서 임의 조합의 조합을 결정할 수있는 대체 방법론입니다 (PHP 제외).

조합 세트에는 유한 조합 수 조합이 있습니다. 즉, 각 조합에 시퀀스 번호가 지정 될 수 있으며 시퀀스 번호를 조합 세트로 변환 할 수 있습니다. 중요한 부분은 다음 루틴 .... get_array_offset()입니다.

int get_array_offset (x, y) { 
    int offset = 0; 
    while (1) { 
     choices = choose (x, y); // x choose y 
     if (sequence <= choices) 
      break; 
     sequence -= choices; 
     x--; 
     offset++; 
    } 
    return offset; 
} 

우리가에서 첫 번째 항목을 찾기 위해, 7 조합을 선택, 우리의 모든 값이 주어진 시퀀스 번호의 배열

valueArray[24] = { ....}; 

에 저장됩니다 우리는 24 다루고있는 가정하자 조합은 ...

sequence = ...;      // sequence number in combination set 
index = 0; 
offset = get_array_offset (24 - 1 - index, 7 - 1); 
index += offset; 
/* valueArray[index] <--- first item in the combination */ 

offset = get_array_offset (24 - 2 - index, 7 - 2); 
index += offset; 
/* valueArray[index] <--- second item in the combination */ 

offset = get_array_offset (24 - 3 - index, 7 - 3); 
index += offset; 
/* valueArray[index] <--- third item in the combination */ 

... And so forth (fits nicely into a loop) ... 

그런 알고리즘을 구현 한 지 오래되었습니다. 요점은 있지만 거기에 하나씩 오류가있을 수 있습니다. 유사한 논리가 순열 문제에도 적용될 수 있습니다.

희망이 도움이됩니다.