Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> permutacje? kombinacje? php c++ excel - help needed ..
pwsmile
post
Post #1





Grupa: Zarejestrowani
Postów: 2
Pomógł: 0
Dołączył: 24.10.2006

Ostrzeżenie: (0%)
-----


Witam i proszę o pomoc ..

nie mogę rozgryźć następującej sprawy..

mam dane :

- x liczb (np.5 liczb i np. takie : 1 2 3 4 5 , ale może być też: 1 3 3 5 5)

- sumę którą chcę otrzymać z dodania którychś (obojętnie ilu) z danych liczb (np. suma=11)

.. i potrzebuję program / skrypt / arkusz excel, który powie mi jak Abel krowie, które liczby ze zbioru muszą być dodane, żeby utworzyły sumę jaką chcę.

Dla zbioru: 1 2 3 4 5 i danej żądanej sumy 11 byłyby to następujące możliwości:

1_2_3___5 (suma: 11)
__2___4_5 (suma: 11)

Dla zbioru: 1 3 3 5 5 i danej żądanej sumy 11 są 3 możliwości:

__3_3_5__ (suma: 11)
__3_3___5 (suma: 11)
1_____5_5 (suma: 11)

Nie jest ważne ile z liczb podanych w zbiorze złoży się na podaną sumę, jednak każda kolejna z liczb w zbiorze powtarzać się może tylko 1 raz (np. pierwsza liczba w ostatnim przykładzie (1) może byż brana pod uwagę tylko raz, czyli rozwiązaniem nie może być

1_1_1_1_1_1_1_1_1_1_1 (bo liczba 1 w zbiorze wystepuje tylko raz)

ale

liczba 5 - też w drugim przykładzie - powtórzyć się może 2 razy, bo tyle razy wystepuje w zbiorze


Super optymalnie byłoby, gdyby programik w przypadku nie znalezienia pasujących składników dających szukaną sumę, podał najbliższą możliwą kombinację w górę i najbliższą możliwą w dół ..

.. np jezeli żądaną sumą byłaby liczba 2, to mając dany zbiór jak w przykładzie drugim: 1 3 3 5 5 program nie znajdzie wprawdzie odpowiednika, bo suma żadnych ze składników w tym zbiorze nie daje liczby 2, ale wypisze:

1________ (suma: 1, reszta 1)
__3______ (suma: 3, reszta -1)
____3____ (suma: 3, reszta -1)

podobnie dla szykanej sumy 12 i tego samego zbioru: 1 3 3 5 5 pasujący odpowiednik nie zostanie znaleziony, jednak najbliższymi dodatnimi i ujemnymi wartościami będą:

1_____5_5 (suma: 11, reszta 1)
1_3___5_5 (suma: 13, reszta -1)
1___3_5_5 (suma: 13, reszta -1)




Jeżeli ktoś ma jakiś pomysł, lub może już nad czymś takim myslał i ma gotowca, byłbym wdzięczny za udostępnienie.

Pozdrawiam
pwsmile
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
jarrod
post
Post #2





Grupa: Zarejestrowani
Postów: 312
Pomógł: 9
Dołączył: 14.10.2006
Skąd: warszawa

Ostrzeżenie: (0%)
-----


  1. <?php
  2. function test($suma=null)
  3. {
  4. if(!$suma) $suma = rand(0,45); // 45 ponieważ 9+9+9+9+9 = 45
  5. if($suma == 0) return 'Zbiór nie zawiera liczb ujemnych. Nie można wykonać działania.';
  6. elseif($suma == 1) return 'Suma == 1 zatem nie można wykonać działań.';
  7.  
  8. $liczby[0] = rand(0,9);
  9. $liczby[1] = rand(0,9);
  10. $liczby[2] = rand(0,9);
  11. $liczby[3] = rand(0,9);
  12. $liczby[4] = rand(0,9);
  13. // posiadamy już pięć losowych liczb które mogą się powtarzać
  14.  
  15. // dla porządku można je posortować
  16. sort($liczby);
  17.  
  18.  
  19. // sprawdzam czy suma wszystkich liczb jest większa od szukanej sumy
  20. // inaczej szykanie nie mam sensu
  21. if(array_sum($liczby) >= $suma) 
  22. {
  23. $breakAll = false; // kontrola wyników
  24. $nSuma = 0; // suma kontrolna
  25. $wynik = array(); // wynik działania funkcji
  26. $tmpKeys = array(); // tu przechowuję indexy liczb użytych w działaniu 
  27.  
  28. // zaczynamy iterowanie po tablicy
  29. for($i=0; $i<5;$i++)
  30. {
  31.  
  32. for($e=$i;$e<5;$e++)
  33. {
  34.  
  35. $tmpKeys[] = $e;
  36. $nSuma += $liczby[$e];
  37.  
  38. if($nSuma == $suma) // znaleziono pasujący wynik
  39. {
  40. $wyn = '';
  41. foreach($tmpKeys as $key)
  42. {
  43. $wyn .= $liczby[$key].'+';
  44. }
  45.  
  46. $wyn = substr($wyn,0,strlen($wyn)-1);
  47. $wyn .= '='.$nSuma;
  48.  
  49. $wynik['dokladnie'][] = $wyn;
  50.  
  51. $nSuma = 0;
  52. $tmpKeys = array();
  53. break;
  54. }
  55. elseif($nSuma > $suma) // znaleziono pierwszy wyższy wynik
  56. {
  57. $wyn = '';
  58. foreach($tmpKeys as $key)
  59. {
  60. $wyn .= $liczby[$key].'+';
  61. }
  62. $wyn = substr($wyn,0,strlen($wyn)-1);
  63. $wyn .= '='.$nSuma;
  64. $resta = $suma-$nSuma;
  65.  
  66. $wynik['wieksze'][] = array($wyn,$resta);
  67.  
  68. $nSuma = 0;
  69. $tmpKeys = array();
  70. break;
  71. }
  72. elseif($e == 4) // ostatni element -> suma wszystkich pozostałych jest mniejsza od szukanej sumy
  73. {
  74. $breakAll = true;
  75.  
  76. $wyn = '';
  77. foreach($tmpKeys as $key)
  78. {
  79. $wyn .= $liczby[$key].'+';
  80. }
  81. $wyn = substr($wyn,0,strlen($wyn)-1);
  82. $wyn .= '='.$nSuma;
  83. $resta = $suma-$nSuma;
  84.  
  85. $wynik['mniejsze'][] = array($wyn,$resta);
  86.  
  87. $nSuma = 0;
  88. $tmpKeys = array();
  89. break;
  90. }
  91. }
  92.  
  93. if($breakAll) break;
  94.  
  95. }
  96. }
  97. else
  98. {
  99. $wynik['max'] = array_sum($liczby);
  100. }
  101. $wynik['liczby'] = $liczby;
  102. $wynik['suma'] = $suma;
  103. return $wynik;
  104. }
  105.  
  106. $wyniki = test();
  107.  
  108. $ret = 'Wynik działania programu:<br/>';
  109.  
  110. if(is_array($wyniki))
  111. {
  112. $ret .= '<br/>Liczby w zbiorze: '.implode(',',$wyniki['liczby']);
  113. $ret .= '<br/>szukana suma: '.$wyniki['suma'].'<br/>';
  114.  
  115. if(isset($wyniki['dokladnie']))
  116. {
  117. $ret .= '<br/>Dokładny wynik daje suma liczb:<br/>';
  118.  
  119. foreach($wyniki['dokladnie'] as $wyn)
  120. $ret .= $wyn.'<br/>';
  121. }
  122. if(isset($wyniki['wieksze']))
  123. {
  124. $ret .= '<br/>Sumę minimalnie większą dają liczby:<br/>';
  125.  
  126. foreach($wyniki['wieksze'] as $wyn)
  127. $ret .= $wyn[0].' reszty: '.$wyn[1].'<br/>';
  128. }
  129. if(isset($wyniki['mniejsze']))
  130. {
  131. $ret .= '<br/>Sumę minimalnie mniejszą dają liczby:<br/>';
  132.  
  133. foreach($wyniki['mniejsze'] as $wyn)
  134. $ret .= $wyn[0].' pozostaje: '.$wyn[1].'<br/>';
  135. }
  136.  
  137. if(isset($wyniki['max']))
  138. {
  139. $ret .= 'Suma wszyskich liczb zbioru ('.$wyniki['max'].') jest mniejsza od podanej sumy.';
  140. }
  141. }
  142. else
  143. {
  144. $ret .= $wyniki;
  145. }
  146. echo $ret;
  147. ?>


uff (IMG:http://forum.php.pl/style_emoticons/default/aarambo.gif)
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 4.10.2025 - 13:37