Komplizierte Schleife in PHP realisierbar?

Bash, Shell, PHP, Python, Perl, CGI
materia
Posts: 21
Joined: 2005-03-15 15:06

Komplizierte Schleife in PHP realisierbar?

Post by materia » 2005-04-16 05:29

Hi Leute,

ich zerbreche mir seit Stunden den Kopf darüber wie ich in PHP folgendes Problem lösen kann:

Ich habe ein 2-Dimensionales Array folgender Art:

Code: Select all

$array[$kategorie][$item]
$kategorie geht von minimal 1 bis maximal 11.
$item geht von minimal 0 bis unbegrenzt.

Das Array ist zur Laufzeit schon gefüllt von [0][0] bis [2][1] zum Beispiel.
Also drei Kategorien mit je zwei Items.

Und jetzt wird es Kompliziert:
Ich möchte in einem Array für ergebnisse die Summe der verschiedenen Kategorien speichern. Und dabei jede Mögliche Kombination durchgehen. Aber es dürfen keine Kategorien zweimal in einem Ergebnis vorkommen:

Beispiel:

Code: Select all

$ergebnis[0] = $array[0][0] + $array[1][0] + $array[2][0];
$ergebnis[1] = $array[0][1] + $array[1][0] + $array[2][0];
$ergebnis[2] = $array[0][0] + $array[1][1] + $array[2][0];
$ergebnis[3] = $array[0][0] + $array[1][0] + $array[2][1];
$ergebnis[4] = $array[0][1] + $array[1][1] + $array[2][0];
$ergebnis[5] = $array[0][0] + $array[1][1] + $array[2][1];
$ergebnis[6] = $array[0][1] + $array[1][0] + $array[2][1];
Das wären alle möglichen und gültigen Kombinationen wie ich sie brauche.

Dies möchte ich aber in einer Schleife oder Funktion automatisieren, da ich ca. 12 Kategorien habe in denen sich jeweils bis zu 100 Items befinden.

Wieviel Kategorien ich zur Laufzeit habe und wieviel Items sich in der jeweiligen Kategorie befinden ist mir bekannt.

Es dürfen auch keine Werte von zwei Items aus der gleichen Kategorie addiert werden. Ich habe schon zig Schleifen entworfen und verschachtelt aber komme auf keinen vernünftigen Lösungsansatz. :(

Wenn ich was vergessen haben sollte nur fragen.
Bin für jede Hilfe und jeden Tip dankbar!

[tom]
RSAC
Posts: 671
Joined: 2003-01-08 20:10
Location: Berlin

Re: Komplizierte Schleife in PHP realisierbar?

Post by [tom] » 2005-04-16 09:34

1. Würd ich das erstmal umsortieren.
2. Scheint mir Dein Beispiel nicht vollständig zu sein.

Bei mir würde das dann so aussehen (mit $kategorie = 0 - 2 und $item = 0 - 1):

Code: Select all

$ergebnis[0] = $array[0][0] + $array[1][0] + $array[2][0];
$ergebnis[1] = $array[0][0] + $array[1][0] + $array[2][1];
$ergebnis[2] = $array[0][0] + $array[1][1] + $array[2][0];
$ergebnis[3] = $array[0][0] + $array[1][1] + $array[2][1];

$ergebnis[4] = $array[0][1] + $array[1][0] + $array[2][0];
$ergebnis[5] = $array[0][1] + $array[1][0] + $array[2][1];
$ergebnis[6] = $array[0][1] + $array[1][1] + $array[2][0];
$ergebnis[7] = $array[0][1] + $array[1][1] + $array[2][1];
Dann erkennt man auch den Schleifenindex besser. Bevor es weitergeht: Meintest Du das so?


[TOM]

outofbound
Posts: 470
Joined: 2002-05-14 13:02
Location: Karlsruhe City

Re: Komplizierte Schleife in PHP realisierbar?

Post by outofbound » 2005-04-16 13:17

var_dump ($mainarray);

foreach ($array as $mainarray=>$unterarrays) {
var_dump($array);
}


Viel Spass ;)


Gruss,

Out

materia
Posts: 21
Joined: 2005-03-15 15:06

Re: Komplizierte Schleife in PHP realisierbar?

Post by materia » 2005-04-17 00:04

[TOM] wrote:1. Würd ich das erstmal umsortieren.
2. Scheint mir Dein Beispiel nicht vollständig zu sein.

...

Dann erkennt man auch den Schleifenindex besser. Bevor es weitergeht: Meintest Du das so?

[TOM]
So meinte ich das, ja war ja auch noch früh am Morgen. :)
Umsortieren ist kein Problem. Ich habe eigentlich alle benötigten Daten in einer Tabelle stehen in der auch die Kategorie steht. Ich dachte mir ich kann das mit 2-3 Schleifen in einem 2D-Array leicht realisieren aber ich kann es natürlich auch auf eine andere Weise einlesen.

Verarbeiten möchte ich die Daten aber im Speicher, da bei 200 Items schon ein paar mio. Kombinationen bei rauskommen werden - Welche aber erst ab einem gewissen Ergebniswert endgültig ausgewertet werden. Aber das ist das kleinere Problem.

Mit dem Vorschlag von Tom konnte ich zunächst nichts anfangen. Hast du noch eine Idee?

outofbound
Posts: 470
Joined: 2002-05-14 13:02
Location: Karlsruhe City

Re: Komplizierte Schleife in PHP realisierbar?

Post by outofbound » 2005-04-17 00:19

materia:

vielleicht klingt es doof, aber vielleicht kommt amn einfacher auf einen grünen Zweig wenn du folgende Fragen beantwortest:

Woher kommen die Daten?
In welchem Format liegen die Daten ursprünglich vor?
Wie sollen die Daten am Ende aussehen?

Oder auch:

Was hast du eigentlich vor? (Vielleicht geht es auf einem anderen Weg viel einfacher?)

Hier hilft z.B. schonmal: Was sind Kategorien, was sind Items? Was soll das Array aus beiden darstellen?

Und um zum foreach zurückzukommen: Dieses Konstrukt ist ideal, um 2D- Array
zu verarbeiten, wenn du nämlich eine Kombination aus "Key" und "Wert" hast. Das
macht additionen von vielen Elementen eines beliebig grossen Arrays sehr einfach, und
im Endeffekt scheint es das zu sein, was du haben willst. ;)


Gruss,

Out

PS: Die Daten kommen nicht aus einem RDBMS, oder? Denn dann gäbe es da group by und compute sum() Konstrukte für ;)

[edit]
Bitte nimm dir eine halbe Stunde Zeit, alle angefallenen Frage exakt zu beantworten. Das wird uns bei der Lösung deines Problems IMMENS weiterhelfen.
[/edit]

materia
Posts: 21
Joined: 2005-03-15 15:06

Re: Komplizierte Schleife in PHP realisierbar?

Post by materia » 2005-04-17 00:39

Die Daten kommen aus einem Export und sehen in etwa so aus:

Code: Select all

barbed leather tunic crafted by Jonny Worker exceptional stamina regeneration 3 lower mana cost 4% lower reagent cost 12% physical resist 5% fire resist 8% cold resist 6% poison resist 7% energy resist 7% strength requirement 25 durability 40 / 40, Preis: --

barbed leather tunic crafted by Jonny Worker exceptional self repair 2 mana increase 6 reflect physical damage 11% lower reagent cost 16% physical resist 5% fire resist 6% cold resist 6% poison resist 7% energy resist 23% strength requirement 25 durability 37 / 37, Preis: --

barbed leather tunic crafted by Jonny Worker exceptional hit point increase 5 mana increase 6 night sight lower reagent cost 13% physical resist 6% fire resist 5% cold resist 6% poison resist 7% energy resist 9% strength requirement 25 durability 40 / 40, Preis: --
Ein Script von mir verarbeitet die Daten schon und legt sie in folgende Tabelle:

Code: Select all

-- 
-- Tabellenstruktur für Tabelle `ac_parts`
-- 
CREATE TABLE `ac_parts` (
  `part_id` int(11) NOT NULL auto_increment,
  `part_user_id` int(11) NOT NULL default '0',
  `part_type_id` int(11) NOT NULL default '0',
  `part_name` text NOT NULL,
  `part_crafter` text NOT NULL,
  `part_physical` int(11) NOT NULL default '0',
  `part_fire` int(11) NOT NULL default '0',
  `part_cold` int(11) NOT NULL default '0',
  `part_poison` int(11) NOT NULL default '0',
  `part_energy` int(11) NOT NULL default '0',
  `part_mr` int(11) NOT NULL default '0',
  `part_hpr` int(11) NOT NULL default '0',
  `part_sr` int(11) NOT NULL default '0',
  `part_lmc` int(11) NOT NULL default '0',
  `part_lrc` int(11) NOT NULL default '0',
  `part_sdi` int(11) NOT NULL default '0',
  `part_reflect` int(11) NOT NULL default '0',
  `part_sb` int(11) NOT NULL default '0',
  `part_db` int(11) NOT NULL default '0',
  `part_ib` int(11) NOT NULL default '0',
  `part_hpi` int(11) NOT NULL default '0',
  `part_si` int(11) NOT NULL default '0',
  `part_mi` int(11) NOT NULL default '0',
  `part_luck` int(11) NOT NULL default '0',
  `part_ns` int(11) NOT NULL default '0',
  PRIMARY KEY  (`part_id`)
) TYPE=MyISAM AUTO_INCREMENT=263 ;
Wobei part_type_id die ID der Kategorie enthält die wie folgt aufgebaut ist:

Code: Select all

type_id 	type_name 	
1	Head Wear	
2	Neck	
3	Arms	
4	Gloves	
5	Legs	
6	Chest Pieces	
7	Rings	
8	Bracelets	
9	Shields	
10	Robes	
11	Cloaks	
12	Weapons
Wenn man z.B. jeweils 20 Items oder auch Parts der Kategorie 4, 5 und 6 in ac_parts drin hat welche ich ja auch im Speicher habe zur Laufzeit soll die Schleife jede mögliche sinnvolle Kombination (jeweils ein mal Gloves, Legs und Chest Pieces) durchgehen und von jedem Part die Werte `part_physical`, `part_fire`, `part_cold`, etc. addieren. Das Ergebnis wird dann in einem Array gespeichert (z.B. $result_physical[$n]) wenn es diverse Mindestanforderungen erreicht.

Hoffe das war verständlich. :)

outofbound
Posts: 470
Joined: 2002-05-14 13:02
Location: Karlsruhe City

Re: Komplizierte Schleife in PHP realisierbar?

Post by outofbound » 2005-04-17 00:44

Ah, Ultima Online... ;)

Kurzum: Was willst du machen, Armor- Kombis zusammenbauen?

Gruss,

Out

materia
Posts: 21
Joined: 2005-03-15 15:06

Re: Komplizierte Schleife in PHP realisierbar?

Post by materia » 2005-04-17 00:52

Aye, es gab da mal so nen Armor Part Calculator der alle möglichen Kombinationen ausrechnet und dann die besten Kombinationen anzeigt. Progrämmchen nutzt aber nicht jeder so gerne vor allem wenn man nicht weiss wo sie her kommen und deswegen wollte ich das ganze mal für die Ã?ffentlichkeit als PHP-Version rausbringen. Ausserdem sind die Sortierfunktionen des Programms mieserabel und die AoS-Attribute werden garnicht erst beachtet...

Es ist eigentlich schon alles fertig. Mir fehlt nur noch die Routine welche die Kombis alle einmal durchgeht und dann die guten Ergebnisse in eine Tabelle schreibt. Dort kann man dann nach belieben sortieren und sich endgültig seine Rüstung aussuchen. Wenn du möchtest kannst du das Teil auch mal testen, was fertig ist, ist auch schon online und benutzbar.

Gruss,
mat

materia
Posts: 21
Joined: 2005-03-15 15:06

Re: Komplizierte Schleife in PHP realisierbar?

Post by materia » 2005-04-18 00:28

Ich hab vom Autor des Programms welches ich versuche in PHP zu übersetzen nun einen Auszug des Quellcodes bekommen. Hier eine von cpp nach PHP übersetzte Variante wie ich es gemacht hab, was auch soweit funktioniert.

Bei der Berechnung kann ich ohne Probleme mein Array verwenden mit "$iI" für die Kategorie und "$iCur[$iI]-1" für das jeweilige Item in der Kategorie.

Code: Select all

unset($iCur[1]);
do {
  if($num_calc_parts[1]) $iCur[1]++;

  unset($iCur[2]);
  do {
    if($num_calc_parts[2]) $iCur[2]++;

    unset($iCur[3]);
    do {
      if($num_calc_parts[3]) $iCur[3]++;

      unset($iCur[4]);
      do {
        if($num_calc_parts[4]) $iCur[4]++;

        unset($iCur[5]);
        do {
          if($num_calc_parts[5]) $iCur[5]++;

          unset($iCur[6]);
          do {
            if($num_calc_parts[6]) $iCur[6]++;

            unset($iCur[7]);
            do {
              if($num_calc_parts[7]) $iCur[7]++;

              unset($iCur[8]);
              do {
                if($num_calc_parts[8]) $iCur[8]++;

                unset($iCur[9]);
                do {
                  if($num_calc_parts[9]) $iCur[9]++;

                  unset($iCur[10]);
                  do {
                    if($num_calc_parts[10]) $iCur[10]++;

                    unset($iCur[11]);
                    do {
                      if($num_calc_parts[11]) $iCur[11]++;

                      unset($iCur[12]);
                      do {
                        if($num_calc_parts[12]) $iCur[12]++;
                        $iTotalArmors++;
                        $iCurrentArmor++;

                        for($iI=1; $iI<13; $iI++) {
                          if($part_id[$iI][$iCur[$iI]-1]) {
// ...
// Berechnung
// ...
                          }
                        }
// ...
// Weitere Berechnung und Auswertung
// ...
                      } while($iCur[12]<$num_calc_parts[12]);
                    } while($iCur[11]<$num_calc_parts[11]);
                  } while($iCur[10]<$num_calc_parts[10]);
                } while($iCur[9]<$num_calc_parts[9]);
              } while($iCur[8]<$num_calc_parts[8]);
            } while($iCur[7]<$num_calc_parts[7]);
          } while($iCur[6]<$num_calc_parts[6]);
        } while($iCur[5]<$num_calc_parts[5]);
      } while($iCur[4]<$num_calc_parts[4]);
    } while($iCur[3]<$num_calc_parts[3]);
  } while($iCur[2]<$num_calc_parts[2]);
} while($iCur[1]<$num_calc_parts[1]);