Nombre de valeur maximum dans un tableau PHP

Résolu/Fermé
Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021 - 15 mars 2020 à 22:51
yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024 - 17 mars 2020 à 08:49
Bonjour,

Dans mon programme PHP, je dois calculer toute les possibilités des calculs possible. Par contre, lorsque je lance mon script, il m'indique que j'ai atteint la capacité maximale du tableau, alors qu'est-ce que je dois faire pour enlever cette erreur et que les changements effectuer n'est aucun impact sur le reste de mon script?

Voici mon code :

<?php

//Fonctions
function getClosest($search, $arr) {
   $closest = null;
   foreach ($arr as $item) {
      if ($closest === null || abs($search - $closest) > abs($item - $search)) {
         $closest = $item;
      }
   }
   return $closest;
}

//Début des tableaux utilisés pour calculer toute les possibilités de ratio possible
$gear1 = [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, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125];
$gear2 = [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, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125];
$gear3 = [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, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125];
$gear4 = [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, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125];
	
$recherche = 0.44444444444445;

$resultats = array();
$debug = array();
foreach($gear4 as $k4=>$v4){
	foreach($gear3 as $k3=>$v3){
		foreach($gear2 as $k2=>$v2){
			foreach($gear1 as $k1=>$v1){
				$calc = ($v1/$v2)*($v3/$v4);
				$resultats [] = $calc;
				$debug[] = array('calc'=>$calc,'valeurs'=>array($v1,$v2,$v3,$v4));
				
			}
		}
	}
}	
sort($resultats);

$valPlusProche = getClosest($recherche,$resultats);
echo "<br> Valeur cherchée : " . $recherche;
echo "<br>Plus proche résultat : "  . $valPlusProche;

echo"<pre>";
print_r($debug);
echo"</pre>";
?>

3 réponses

Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
Modifié le 17 mars 2020 à 08:50
En fait ton problème est très mathématique.
Ton approche par force brute va fonctionner, mais en des temps très longs ou en consommant beaucoup de mémoire.
Il faut trouver des astuces pour réduire ce temps.
Ce que tu veux, c'est trouver les facteurs v1, v2, v3 et v4 qui permettent le mieux d'approcher un résultat donné par la formule $calc = ($v1/$v2)*($v3/$v4);
Ce que je ferais à ta place, c'est déjà simplifier cette écriture en $calc = $v5/$v6;
Tu peux créer un tableau des V qui contient tous les produits de deux nombres v1 et v2. L'avantage c'est que le même tableau peut être utilisé pour v5 et v6.
Pourquoi ? Parce qu'ainsi, on peut contrôler la croissance ou décroissance du résultat au fur et à mesure que les valeurs sont testées. On peut même trouver tout de suite le v6 qui approche le mieux v5 : v6 = v5 / recherche : tu le calcules et trouves les v6 qui encadrent au mieux cette valeur dans le tableau des V (un plus grand et un plus petit que le v6 trouvé, qui ne sera pas forcément entier. Comme le tableau est trié, tu peux aller assez vite sans le parcourir complètement, par exemple par dichotomie). Tu gardes ensuite le meilleur des deux. Et ainsi de suite pour chaque v5.

Une fois que tu as les v5 et v6, tu peux retrouver les v1, v2, v3 et v4 qui correspondent (encore plus facilement si tu les as stockés en mémoire également au début)

Bon c'est peut-être un peu confus à écrire comme ça, mais cette approche pourra t'éviter de très nombreux calculs : je t'invite à y réfléchir sérieusement.
1
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 330
15 mars 2020 à 23:24
Cela fait quand même 244'140'625 possibilités ...
Compte tenu de la taille de chaque entrée dans ton tableau Debug, tu dois un peu exploser la RAM ...

Si tu as besoin juste de la valeur la plus proche, fais-le directement et non après avoir tout calculer.
0
Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021
Modifié le 15 mars 2020 à 23:38
Bonjour,

Pourrais-tu me diriger un peu?
0
yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024 1 468 > Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021
16 mars 2020 à 08:50
bonjour,
décris, avec des mots, ce que fait ton programme.
cela t'aidera à comprendre comment l'optimiser.
0
Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021 > yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024
Modifié le 16 mars 2020 à 16:07
Bonjour,

Je sais comment fonctionne mon programme, c'est seulement que je cherche une solution pour pouvoir mettre dans les tableaux $gear1, $gear2, $gear3 et $gear4, des nombres jusqu'à 125 et qu'il n'y est aucune erreur qui s'affiche.

Pourriez-vous m'aider?
0
yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024 1 468 > Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021
16 mars 2020 à 16:22
en fait, ton programme est extrêmement mal conçu, et j'essaie que tu en prennes conscience, de façon à ce que, la prochaine fois, tu ne fasses plus cette erreur de conception.
je t'invite donc à réfléchir et à découvrir cette erreur.
je suggère que tu écrives, avec des mots, ce que fait ton programme.

une autre façon de faire serait peut-être de partir d'une situation similaire, réelle ou imaginée, sans utilisation d'ordinateur. cela pourrait t'aider à te découvrir comment optimiser.
0
Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021 > yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024
16 mars 2020 à 16:24
Merci d'essayer de me faire prendre conscience, mais ça fait environ deux mois que je travail sur ce programme et je n'arrive pas à trouver ce qu'il ne va pas.
0
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
Modifié le 16 mars 2020 à 16:37
Bonjour,

Ce qu'essaie de te dire yg_be, c'est que ton programme ne pourra pas fonctionner comme ça.
Ce n'est pas une question de changer un ou deux trucs pour que « ça marche ». Le problème, c'est juste que tu essaies de stocker en mémoire des centaines de millions de valeurs. C'est énorme, c'est trop pour php.

Donc yg_be essaie de comprendre ce que tu veux que ton programme fasse, pour trouver une autre façon de le faire sans avoir à stocker tout ça.

Par exemple, pourquoi vouloir stocker tous les ratios résultant des combinaisons de ces quatre valeurs ? Pourquoi ne pas simplement recalculer un ratio quand il est utile ?

Xavier
0
Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021
16 mars 2020 à 17:00
Bonjour,

D'accord je comprend. Alors mon programme fonctionne de sorte que je calcul tous les ratios de chaque possibilité et je les stock dans un tableau. Par la suite, je trouve le nombre parmi les ratios le plus proches du nombre de la variable $recherche. Par la suite, je recherche dans ma liste des ratios que j'ai trouver précédemment et j'affiche les nombre qui ont été utilisé pour calculer le ratio qui correspond au nombre le plus proche.

Il ce peut que mon explication ne soit pas claire mais je vais joindre mon code de nouveau et inclure quelque commentaire.

Voici mon code :

<?php
//Début fonctions pour nombre le plus proche
function getClosest($search, $arr) {
   $closest = null;
   foreach ($arr as $item) {
      if ($closest === null || abs($search - $closest) > abs($item - $search)) {
         $closest = $item;
      }
   }
   return $closest;
}
//Fin fonctions pour nombre le plus proche

//Début des tableaux utilisés pour calculer toute les possibilités de ratio possible
$gear1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,/* 17, 18, 19, 20*/];
$gear2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,/* 17, 18, 19, 20*/];
$gear3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,/* 17, 18, 19, 20*/];
$gear4 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,/* 17, 18, 19, 20*/];
//Fin des tableaux utilisés pour calculer toute les possibilités de ratio possible

//Début de la variable stockant le nombre recherché
$recherche = 4.8888888888889;
//Fin de la variable stockant le nombre recherché


//Début du calcul des ratios
$resultats = array();
$debug = array();
foreach($gear4 as $k4=>$v4){
	foreach($gear3 as $k3=>$v3){
		foreach($gear2 as $k2=>$v2){
			foreach($gear1 as $k1=>$v1){
				$calc = ($v1/$v2)*($v3/$v4);
            $resultats [] = $calc;
				$debug[] = array('calc'=>$calc,'valeurs'=>array($v1,$v2,$v3,$v4));
				
			}
		}
	}
}	
//Fin du calcul des ratios

//Début affichage du nombre rechercher et du nombre le plus proche du nombre rechercher
sort($resultats);
$valPlusProche = getClosest($recherche,$resultats);
echo "<br> Valeur cherchée : " . $recherche;
echo "<br>Plus proche résultat : "  . $valPlusProche;
//Fin affichage du nombre rechercher et du nombre le plus proche du nombre rechercher

echo"<pre>";
//Début affichage du tableau
print_r($debug);
echo"</pre>";
//Fin affichage du tableau
0
yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024 1 468 > Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021
16 mars 2020 à 17:42
c'est hyper clair:
mon programme fonctionne de sorte que je calcul tous les ratios de chaque possibilité et je les stock dans un tableau. Par la suite, je trouve le nombre parmi les ratios le plus proches du nombre de la variable $recherche. Par la suite, je recherche dans ma liste des ratios que j'ai trouver précédemment et j'affiche les nombre qui ont été utilisé pour calculer le ratio qui correspond au nombre le plus proche.

essayons une analogie:
- tu as un atlas avec une page par pays, chaque page étant une carte du pays avec toutes les villes de ce pays, et leur nombres d'habitants.
- tu dois déterminer quelle ville a le nombre d'habitants le plus proche d'un nombre donné.
- tu as un crayon et une grande feuille, aussi grande que tu le souhaites
Comment fais-tu ce travail?
0
Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021 > yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024
16 mars 2020 à 17:45
Je note sur la feuille grâce à mon crayon chaque nombre qui semble le plus proche du nombre d'habitant.
0
yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024 1 468 > Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021
16 mars 2020 à 17:54
c'est un peu flou comme réponse, ce serait mieux d'être plus précis: décris les instructions que tu donnerais à quelqu'un pour faire exactement ce que tu veux qu'il fasse.

si tu appliquais la même logique que ton programme, que noterais-tu sur la feuille?
0
Anonyme1234_7288 Messages postés 65 Date d'inscription samedi 14 mars 2020 Statut Membre Dernière intervention 8 avril 2021 > yg_be Messages postés 22679 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 14 avril 2024
16 mars 2020 à 17:56
Je noterais le nom du pays et le nombre d'habitant pour chaque. Je ferais ceci pour chacun et par la suite je les comparerais au nombre recherché. Finalement, je retiens le nombre d'habitant le plus proche du nombre recherché.
0