Modification d'un algo de calculs de somme

Eléphant du PHP | 209 Messages

18 juin 2011, 08:11

me commenter le code afin d'y percer tous ces secrets ?
heuh... non, si tu ne comprend pas un truc, tu peux demander, mais je fais pas tout le travail !
D'ailleurs je ne vois plus d'array_sum, comment fait tu les additions ?
Tous est là :
$trouve = trouve($all_numero,$somme-$numero,$nb_max-1) ;
--
Eric

Eléphant du PHP | 168 Messages

18 juin 2011, 11:08

<?php 

set_time_limit(0);

$somme_a_trouver = 114;
$nb_element_max = 5;
$all_numero = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40);

function super_unique($array) {
  $result = array_map("unserialize", array_unique(array_map("serialize", $array)));
  return $result;
}

function trouve($all_numero,$somme,$nb_max){

		// suppose que cela ne sert qu'a titre de debug/information et que tu aurais pu prendre n'importe qu'elle chiffre du nb d'element max.
        if ($nb_max == 4){
                static $test;
                $test++;
                echo "$test/".count($all_numero)."\n";
        }
		
		// suppose que c'est pour eviter de faire lancer la machine alors que l'on peut calculer bien plus facilement pour un seul nombre.
        if ($nb_max == 1){
                if (in_array($somme,$all_numero)){
                        return array(array($somme));
                        return true;
                } else {
                        return array();
                }
        }
		
		
        $r = false;
        $solution = array();
        foreach($all_numero as $numero){
		
		// on va parcourir tous nos chiffres 40 > 39 > 38 ..
		
                $trouve = trouve($all_numero,$somme-$numero,$nb_max-1) ; // j'avoue ne pas comprendre la subtilité de ce passage.. tu fais a chaque tout 150-40, 150-39, etc.. et 5-1, comprends rien ;-)
                
				
				foreach ($trouve as $i => $s){
                        $trouve[$i][] = $numero;
                        sort($trouve[$i]);
                        $solution[] = $trouve[$i];
                } 
        }
		
		// tu serialize pour avoir un string en comparaison je suppose, pas bete du tout.
        $solution = super_unique($solution);
        return $solution;       
}

// ici rien de compliqué..
$result = trouve($all_numero,$somme_a_trouver,$nb_element_max);

echo '<pre>';
print_r($result);
echo '</pre>'; 
Merci de ton aide et de ta patience.. je suppose que le secret dans la réalisation des algos, c'est.. pratiquer, pratiquer et pratiquer ?

Eléphant du PHP | 209 Messages

18 juin 2011, 12:15

Bon, ok, je vais essayer d'expliquer l'algo.

La fonction "trouve" prend en argument un ensemble de numéro, une somme à trouver et un nombre de numéro ($nb_max).

Je fais ce qu'on appelle une récursion. C'est à dire, que, je sais :
- d'une part résoudre le problème dans un cas très simple (1)
- d'autre part simplifier le problème plus compliqué vers un cas plus simple, jusqu'au cas très simple que je sais résoudre. (2)

Pour (1), le cas que je sais résoudre, c'est :
-> Trouver une somme X avec 1 seul numéro dans un tableau

Pour (2), la récursion proprement dite :
->Trouver une somme X avec N numéro dans un tableau, c'est comme trouver, pour chacun des numéro Y du tableau , X - Y avec N -1 numéro

Ma récursion (2) va progressivement me ramener au cas 1.
je suppose que le secret dans la réalisation des algos, c'est.. pratiquer, pratiquer et pratiquer ?
Dans ce cas, je te conseille de ne pas faire du PHP pour apprendre a faire ce type d'algorithme, mais de te tourner vers des langages comme le LISP ou le Prolog. D'ailleurs, je pense que ton problème serait plus vite résolu en LISP.
--
Eric

Eléphant du PHP | 168 Messages

18 juin 2011, 12:57

Humm.. je vais essayer de prendre de bien plus petits chiffres et débugger un peu toutes les valeurs pour comprendre en parallèle de ton explication, car j'ai du mal à comprendre.

Je dois surement manquer de connaissance théorique ou je sais quoi, car je ne comprends pas le principe, on veut additionner des nombres entre eux, et je ne vois aucune addition (visuellement) ni même pourquoi on réduit la somme par un numéro, "je ne comprends pas le rapport", sur les faits je vois l'efficacité, mais en me penchant sur le code et ton explication, c'est encore plus flou..

Eléphant du PHP | 209 Messages

18 juin 2011, 14:03

Si on a 1,2,3,4 et 5 comme numéro.

Si on cherche a faire 4 avec un numéro, c'est facile 4 € [1,2,3,4,5]

Si on cherche a faire 7 avec deux numéro :
- on cherche a faire 7 - 1 = 6 avec un numéro (KO)
- on cherche à faire 7 - 2 = 5 avec un numéro (OK)
...
- on cherche à faire 7 - 5 = 2 avec un numéro (OK)

Les solutions sont donc 2+5; 3+4; 4+3 et 5+2. (on trie et on prend à chaque fois les somme uniques => il ne reste que 2+5 et 3+4)

Si on cherche à faire 8 avec trois numéro :
- on cherche a faire 8 -1 = 7 avec deux numéro
- on cherche à faire 8 -2 = 6 avec deux numéro

etc...
--
Eric

Eléphant du PHP | 168 Messages

19 juin 2011, 20:58

J'viens de piger le truc !

Merci beaucoup de ton aide.

Résolu !