Gebindeberechnung

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Gebindeberechnung

    Hallo Leute, mir raucht immoment der Kopf und ich komme auf keine Lösung.

    Ich benötige einen Verbrauchsrechner. Ich habe zwei Variablen

    Variable 1: $v1= 160;
    variable 2: $v2= array('5,'25','30');


    Die erste Variable ist die benötigte Menge. Die Variable zwei definiert, welche Gebindegrößen es gibt.

    Ich komme auf keine schöne Lösung ohne tausende von if Abfragen ect. damit er mir ausgibt, dass ich 5x 30kg und 2x5kg Säcke kaufen muss.

    Habt ihr einen Tipp für mich wie ich es mathematisch in php lösen kann?
  • Eine saubere Lösung wird es da nicht geben. Was ich mal schnell in der Sandbox gemacht habe ist folgendes:

    PHP-Quellcode

    1. function get_perm(array $data, $k, $i)
    2. {
    3. $ret = array();
    4. $n = count($data);
    5. for ($exp = $k - 1; $exp >= 0; $exp--) {
    6. $pow = pow($n, $exp);
    7. $idx = (int) ($i / $pow);
    8. $ret[] = $data[$idx];
    9. $i -= $idx * $pow;
    10. }
    11. return $ret;
    12. }
    13. $sum = 50;
    14. $sizes = array(5, 25, 30);
    15. $maxLength = ($sum - ($sum % min($sizes))) / min($sizes);
    16. for($size = 1; $size <= $maxLength; $size++) {
    17. $pow = pow(count($sizes), $size);
    18. for($i = 0; $i < $pow; $i++) {
    19. $perm = get_perm($sizes, $size, $i);
    20. if(array_sum($perm) == $sum) {
    21. echo implode(', ', $perm) . PHP_EOL;
    22. }
    23. }
    24. }
    Alles anzeigen
    get_perm stammt von php-de.github.io/jumpto/kombinatorik-loesungen/.

    Was gemacht wird ist, dass alle möglichen Kombinationen ausprobiert werden.
  • Das sieht ja schonmal ganz cool aus, danke :) Etwas kompliziert, da steige ich hoffentlich noch ganz durch.

    Einzige problem ist, sobald die Summe mal über 50 geht, braucht das Script so lange, dass ein PHP Fatal Error wegen zu langer Script ausführung gibt.

    Kannst du mir sagen, wie ich das Script so abändern könnte, dass mir nur die zwei oder drei besten Ergebnise angezeigt werden? Das wird relativ schwierig werden was "am besten" ist?

    Also bei 60 Kg wäre ja 25,25,5,5 am Sinnvollsten
    Bei 70 wäre 25,25,25 am besten.

    Das ganze funktionier bei einem Spachtelmassenhersteller sehr gut wenn man unter Verbrauchsrechner schaut.
    Allerdings ist das leider mathematisch für mich zu hoch muss ich ehrlich sagen.
    Verbrauchsrechner
  • Naja, wie willst du die besten Möglichkeiten finden ohne alle Möglichkeiten durchzugehen? :D

    Ansonstens gibt es noch Näherungsverfahren, die mathematisch sehr heftig sind. Ich schau mal nach, ob ich in meinen Unterlagen was dazu finde. Hatte letztes Semester erst Algorithmen und Datenstrukturen belegt.
  • Okey... ich merk gradeich fachidiotisier ein bisschen.

    Wenn gewisse Rahmenbedingungen gelten, kann man das enorm vereinfachen. Beschreibe mal genau, was du machen möchtest mit realen Daten.

    EDIT

    Quellcode

    1. $sizes = [5, 15, 25, 100]; // Annahme: Array ist bereits aufsteigend sortiert
    2. $minSize = min($sizes);
    3. $sum = 1251;
    4. $units = [];
    5. // Summe vorbereiten, dass sie sich notfalls durch unsere kleinste Einheit teilen lässt
    6. while($sum % $minSize !== 0) {
    7. $sum++;
    8. }
    9. $currentSizeIndex = count($sizes) - 1;
    10. while($sum !== 0) {
    11. $rest = $sum % $sizes[$currentSizeIndex];
    12. $units[] = ['Größe' => $sizes[$currentSizeIndex], 'Menge' => ($sum - $rest) / $sizes[$currentSizeIndex]];
    13. $sum = $rest;
    14. $currentSizeIndex--;
    15. }
    16. var_dump($units);
    Alles anzeigen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Arno ()

  • Wieso sortiert ihr nicht einfach das Array der verfügbaren Mengen [30,25,5], sodass man wunderbar mit dem Größten anfangen kann, schaut, wie oft das hineinpasst, dann mit dem Rest weitermachen...

    30 passt 5x in 160, Rest 10, 25 passt gar nicht in 10, 5 passt 2x. Fertig.

    Das Ergebnis ist zwar nicht immer optimal, siehe Menge 75 wär 2x30 + 3x5 statt 3x25, aber dafür sollte die Laufzeit viel kürzer sein.
  • Arno schrieb:

    Naja, wie willst du die besten Möglichkeiten finden ohne alle Möglichkeiten durchzugehen? :D
    Ja gut da hast du auch wieder recht. Vielleicht könnte man nur die Möglichkeiten direkt von anfang an beschränken?
    Sprich die Möglichkeiten bei z.B. 30kg mit 5kg,5kg,5kg,5kg,5kg,5kg. könnte man ja direkt ausgrenzen?

    Arno schrieb:

    Wenn gewisse Rahmenbedingungen gelten, kann man das enorm vereinfachen. Beschreibe mal genau, was du machen möchtest mit realen Daten.
    Also ich habe zwei Felder für Wandwerte. Also a*b. Dadraus werden mir die QM der Wand berechnet und ich berechne dann anhand der Spachtelmassenwerte die benötigten KG.

    Und danach hätte ich dann halt gerne, dass mir automatisch (ohne, dass ich selber Rechnen muss) eine Optimale Gebindeauswahl erstellt wird.

    Ich merke, dass das alles sehr kompliziert ist. Mach dir bitte kein Stress, wenn das zu aufwendig ist. Dann muss ich halt eine Liste erstellen mit den Gebinden und mir selber ausrechnen welche Kombination ab besten ist.

    bYemma schrieb:

    Das Ergebnis ist zwar nicht immer optimal, siehe Menge 75 wär 2x30 + 3x5 statt 3x25, aber dafür sollte die Laufzeit viel kürzer sein.
    Das ist leider das Problem. Preislich liegen 5KG Säcke viel höher als ein 25KG Sack.Somit ist die Berechnung fehlerhaft.

    Wenn man 65KG hat, ist es klar, dass man nicht 2x25 und 3x5 benötigt. Sondern es mehr sinn macht 3x25 zu besorgen.

    Ich denke das es vllt doch eine zu komplexe Rechnung wird




    Edit://
    Wie ich sehe, funktioniert dein Script ja super Arno? :)
    Es kommt zwar nicht immer die optimalste aufteilen zustande. Aber zu 90% schon.
    Dann muss man halt zur not nocheinmal ein Auge drauf werden und ggf. eine änderung per Hand machen.

    Ansonsten ist es möglich ohne großen aufwand eine Abfrage einzubauen, dass wenn das kleinste gebinde zu 3/4 an das nächste höhere gebinde kommt, das große gewählt wird?

    Sprich, dass wenn 4x5kg ausgewählt werden, es automatisch auf 1x25kg rechnet?

    E2://
    Habe mich selber dran versucht, allerdings scheitere ich dadran, dass ich es nur für zwei werte hin bekomme.


    Habe es so versucht:

    PHP-Quellcode

    1. $sizes = [5, 25];
    2. .
    3. ..
    4. .
    5. .
    6. if($rest==$rounding){
    7. $units[] = ['Größe' => $sizes[1], 'Menge' => 1];
    8. $sum=0;
    9. }else{
    10. $units[] = ['Größe' => $sizes[$currentSizeIndex], 'Menge' => ($sum - $rest) / $sizes[$currentSizeIndex]];
    11. $sum = $rest;
    12. }
    Alles anzeigen
    Aber das funkioniert ja nur für den Moment, wo ich als Summe 20 habe und im Array nur die Werte 5 und 25 sind.

    Habe ich jetzt 45KG funktioniert das ganze logischerweise nicht mehr.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Snowflake ()

  • Vielleicht kann ja mal jemand ein Blick drüber werfen und hat vllt ein verbesserungsvorschlag?

    Ich komme mit den Kommazahlen nicht ganz zurecht. Weiß nicht wie ich verfahren soll.

    Ich löse es jetzt mathematisch auf. Sprich wenn Summe/Gebinde 0.8 ist, soll das nächste höhere Gebinde gewählt werden. Allerdings habe ich dann oft 1.6 oder 0.8 gebinde.
    Und dann kommt alles durcheinader. ()

    PHP-Quellcode

    1. <?php
    2. $sizes = [1,2.5,5,12.5]; // Annahme: Array ist bereits aufsteigend sortiert
    3. $minSize = min($sizes);
    4. $sum = 8;
    5. $units = [];
    6. // Summe vorbereiten, dass sie sich notfalls durch unsere kleinste Einheit teilen lässt
    7. while($sum % $minSize !== 0) {
    8. $sum++;
    9. }
    10. $currentSizeIndex = count($sizes) - 1;
    11. while($sum !== 0) {
    12. $rest = $sum % $sizes[$currentSizeIndex];
    13. if($sum/$sizes[$currentSizeIndex] > 0.7 ){
    14. $men =$sum/$sizes[$currentSizeIndex];
    15. $komma = fmod($men, 1);
    16. $units[] = ['Größe' => $sizes[$currentSizeIndex], 'Menge' => $men];
    17. $a=$sum-$sum/$sizes[$currentSizeIndex]*$sizes[$currentSizeIndex];
    18. if($komma!=0){
    19. $sum=round($komma*$sizes[$currentSizeIndex]);
    20. }else{
    21. $sum=$a;
    22. }
    23. }else{
    24. if(round(($sum - $rest) / $sizes[$currentSizeIndex]) < 0){
    25. $wert=0;
    26. }else{
    27. $wert=round(($sum - $rest) / $sizes[$currentSizeIndex]);
    28. }
    29. $units[] = ['Größe' => $sizes[$currentSizeIndex], 'Menge' => $wert];
    30. $sum = $rest;
    31. }
    32. $currentSizeIndex--;
    33. $i++;
    34. if($rest==0) $sum=0;
    35. }
    36. echo "<br>";
    37. foreach($units as $gebinde){
    38. foreach($gebinde as $a =>$key){
    39. echo $key."<br>";
    40. }
    41. echo "<br>";
    42. }
    43. ?>
    Alles anzeigen

    Lohnt es sich da überhaupt noch Zeit reinzustecken? -ich hocke jetzt den ganzen Tag davor.