Das ist jetzt PHP, aber wer C und C++ kann, wird sicherlich auch das
Script verstehen.
Es gibt verschiedene Rohstoffe und Vorgaben (Menge, Inhaltstoffe). Ziel
ist es das günstigste
Mischungsverhälntis zu finden. Im Grunde ganz einfach. Nur ineinander
geschachtelte for Schleifen,
die alle möglichen Mischungsverhälntisse in Prozent berechnen.
Das Problem ist die Rechenzeit.
1
3 Rohstoffe Loops: 5.151 Seconds: 0,012 sec.
2
4 Rohstoffe Loops: 176.851 Seconds: 0,420 sec.
3
5 Rohstoffe Loops: 4.598.126 Seconds: 14,165 sec.
4
...
Ideal wäre es, wenn man 30 Rohstoffe mit einer 1% Genauigkeit
durchrechnen könnte.
Das man jemals da hinkommt, glaube ich nicht, aber man kann's ja mal
versuchen, wie weit man mit
richtig Rechenpower kommt. Die Schleifen dürfte man eigentlich gut auf
mehrere Prozessoren verteilen
können.
Er hier:
http://www.rechenkraft.net/forum/viewtopic.php?f=83&t=12405&start=12
dürft schon deutlich schneller sein als die 2,8 Ghz (Single-Core) vom
PHP Server. Zwei bis Vier
Board's dürften aber für den ersten Test erstmal reichen. Dann kann
abschätzen wieviele Board's
Sinn machen würden.
Gibt es jemand der helfen könnte, dieses kleine Script auf so einem
Cluster laufen zu lassen?
Ist kein Hobby-Projekt, würde natürlich auch bezahlt werden.
Viele Grüße
Roman
Exponentielle Komplexität mit linearer Skalierung erschlagen ;)
Das bekommen schon die richtigen HPC'ler nicht hin.
Lös' doch einfach das unterliegende DGL mit entsprechend optimierter
Software, anstatt das selber machen zu wollen …
Hi Roman,
PHP ist schonmal blöd. Habe das trotzdem mal auf 5.6 auf meinem i7-4770k
laufen lassen: 2 Sekunden.
Mit PHP7 ist es noch eine Sekunde.
Mit einer "vernünftigen" Programmiersprache, sollte das ganze noch
erheblich schneller gehen; auf einem Kern.
Kannst du mal aufschlüsseln was das Ziel des Programmes ist?
Man mixt 0-6 Inhaltstoffe rein, welche prioritisiert werden,
es ist aber egal welche Zusammensetzung, es wird die Summe des
Gewicht/Volumen begrenzt.
@Hannes W.
Je mehr Rechenpower desto mehr Komponenten sind möglich. Desto besser.
Rein softwareseitig, soll aus vielen verschiedenen Rohstoffen die
günstigste Mischung gefunden werden, die den Produktanforderungen noch
entspricht.
Außer Brute-Force (s.o.) gibt es keine Lösung. Bei Brute-Force haben wir
schon sehr viele Filter im Einsatz die Schleifen einsparen, und auf
X-Wegen abkürzen, aber auch das hat logisch, und von der Bedienung
grenzen...
@Soeren
Ist alles bekannt. Die Zeiten stammen von einem Xamp System das maximal
mit 10% unter Windows 10 laufen kann. Der LiveServer mit PHP7 ist
nochmal deutlich schneller. Wenn wir auf C oder C++ umsteigen (eigene
PHP Module), etwa 5-8 schneller. Relevant weiter hilft uns das nicht...
aber 1.000x
schneller ggf. schon:
2,8Ghz mit PHP7 vs. 640 Cores (40x Parallela) a 800Mhz mit C
ganz grob 640 x 0.8 * 5(für C) / 2.8 = 914x
Die kleinen Boards können auch gut zwei Tage durchrechnen.
An dem Projekt arbeite ich schon seit Monaten -
Wir brauchen einen Supercomputer :)
@Pic Tech
Auf eine Produktgruppe bezogen:
Es gibt aktuell auf Lager 40 verschiedene Rohsstofftypen mit 5-12
Inhaltsstoffen (einer davon ist Nutzinhalt), einer Menge und natürlich
einem Preis.
Die Kunden bestellen immer einen Mix mit unterschiedlichen
Spezifikationen (Inhaltsstoff 1. min 35% und max 37%, Inhaltsstoff 4 max
0.02% usw.) und natürlich die Menge.
Je günstiger man den Mix herstellen kann, desto mehr Geld verdient die
Firma.
Kann man dafür nicht existierende Tools verwenden, die schon allerlei
Optimierungen eingebaut haben?
Optimierungsprobleme treten ja nicht gerade selten auf.
Faktor 5-8 in C kannst du mit mehreren Threads auch noch verfielfachen.
av@av-1005HA:~/test/tmp/cnc$ php5 t1.php
Loops: 4.598.126 <br>
Hits: 400.800 <br>
Seconds: 10,360 sec.
Optimierung der Variablen , kein hash lookup, oder einer weniger
$bestand[0]['inhaltsstoff_1'] = 6.95; => $bestand[0]=6.95;
av@av-1005HA:~/test/tmp/cnc$ php5 t1.php
Loops: 4.598.126 <br>
Hits: 400.800 <br>
Seconds: 8,434 sec.
Dasselbe mit tcc compiliert,
av@av-1005HA:~/test/tmp/cnc$ ./a.out
Loops: 4598126
Hits: 400800
Seconds: 0.249174 sec
sowie mit gcc
av@av-1005HA:~/test/tmp/cnc$ ./a.out
Loops: 4598126
Hits: 400754
Seconds: 0.118603 sec
Trotzdem würde ich da eher eine rechnerische Lösung vorziehen.
Muss es denn pnp sein ?
Das sieht wie ein typisches Problem der linearen Optimierung (linear
programming) aus.
Das php programm ist das "Diet Problem", als einfuehrendes Beispiel in
das
Gebiet.
Bewaehrter Algorithmus ist der Simplex Algorithmus.
Solver loesen Probleme mit Tausenden von Variablen problemlos.
Falls das Problem doch nicht so gut strukturiert ist lohnt sich
ein Blick auf "Constraint Programming".
einen Beowulf-Cluster fürs Raytracing hatte ich mal auf einem
Debian-Server mit 4 Nodes (alte Laptops) aufgestellt
die Clustersoftware war Kestrel-HPC
http://kestrelhpc.sourceforge.net/ (Vers. 2.0 damals verwendet, wird
wohl leider nicht mehr gepflegt)
Programmiersprache war C++ mit dem Open-MPI-Zusatz mit der
Code::Blocks-IDE
das ganze lief nach einiger Mühe mit PXE-Boot
und es lief ganze drei Tage, bis die (nicht gesicherte)
Server-Hauptfestplatte sich verabschiedet hat (die einzige von meinen 50
Platten die nicht hätte kaputt gehen dürfen..., Murphy halt)
sollte auch heute noch mit den alten Debian-Versionen (6.0 war es glaub
ich) nochmal aufzubauen sein, Kestrel usw. kann man ja noch runterladen
Code nach C++ portieren, OpenMPI reinfrickeln und ab damit
in Sachen Performance aber lief meiner auf Maulwurf-Level, hätte
rechnerisch 1.3GFlops haben sollen und hatte 300MFlops (ja, ist schon
etwas länger her)
Pic Tech - Nein, PHP auf gar keinen Fall :) Das haben wir ja schon. Auf
dem Linux LiveServer braucht das Script von oben, mit PHP7 und 2,8GHz
Loops: 4.598.126
Hits: 400.800
Seconds: 1,887 sec.
@Josef C. - "Bewaehrter Algorithmus ist der Simplex Algorithmus."
Ich kann mir im Moment nicht wirklich vorstellen, das es eine
intelligente Lösung gibt, anstelle von Brute-Force. Denn ich habe 30
Komponenten mit 8-15 Analysewerten mit eigenen Spezifikationen, einem
Preis und einer maximal mischbaren Menge. Da gibt es keinen Roten Faden
dem man folgen kann. Die einen Werte werden richtiger, die anderen 6
falscher... was dann? Ich bin allerdings auch kein Mathematiker.
@Mike B. - Puh, kenne mich da garnicht aus. Gibt ja schon einige die
solche Cluster gebaut haben. Die Kunst wird es wohl sein die ganzen
Schleifen sinnvoll auf die Kerne zu verteilen und die Ergebnisse in zwei
Tagen wieder abzuholen.
Alternativ kannst du in deinem PHP Programm eine Zielfunktion samt
Nebenbedingungen für deinen Zaubertrank generieren:
Die Zielfunktion ist in deinem Fall die Kostenfunktion, die minimiert
werden soll.
Die Nebenbedingungen sind die Anteile der Zutaten und sonstige
Beschränkungen und Abhängigkeiten.
Diese Gleichungen gibst du dann in einem Standardformat (z.B. CPLEX) aus
und jagst sie durch einen LP Solver.
Das erspart dir zumindest die Implementierung des Simplex Algorithmus.
Roman S. schrieb:> Pic Tech - Nein, PHP auf gar keinen Fall :) Das haben wir ja schon. Auf> dem Linux LiveServer braucht das Script von oben, mit PHP7 und 2,8GHz>> Loops: 4.598.126> Hits: 400.800> Seconds: 1,887 sec.>> @Josef C. - "Bewaehrter Algorithmus ist der Simplex Algorithmus."> Ich kann mir im Moment nicht wirklich vorstellen, das es eine> intelligente Lösung gibt, anstelle von Brute-Force. Denn ich habe 30> Komponenten mit 8-15 Analysewerten mit eigenen Spezifikationen, einem> Preis und einer maximal mischbaren Menge. Da gibt es keinen Roten Faden> dem man folgen kann. Die einen Werte werden richtiger, die anderen 6> falscher... was dann? Ich bin allerdings auch kein Mathematiker.>
Um das zu klaeren solltest du dein Problem mal richtig formulieren.
Bis jetzt sieht es nach einem
https://de.wikipedia.org/wiki/Lineare_Optimierung#Mischungsprobleme aus.
Es sollte geklaert werden, ob das Problem linear ist. Also z.B.
Inhaltsstoff = Menge * Faktor
und keine Potenz oder Wurzel oder sowas in den Variablen auftritt.
Dann ob die Loesung eine ganze Zahl sein muss oder ob auch Bruchzahlen
erlaubt sind. Z.B. von Material1 2.345kg etc.
Bei lebenden Tieren sind normal nur ganze Zahlen erlaubt. Ganzzahlige
Probleme sind viel schwieriger zu loesen.
Ja und den Algorithmus musst du nicht programmieren. Es gibt genuegend
Solver (glpk, lpsolve, cplex ...).
Da durch solche Optimierungen viel Geld verdient werden kann, wurde
schon
eine Menge Hirnschmalz investiert.
Roman S. schrieb:> @Mike B. - Puh, kenne mich da garnicht aus. Gibt ja schon einige die> solche Cluster gebaut haben. Die Kunst wird es wohl sein die ganzen> Schleifen sinnvoll auf die Kerne zu verteilen und die Ergebnisse in zwei> Tagen wieder abzuholen.
das macht OpenMPI automatisch
einfach die #pragma-lauseln an die richtige Stelle setzen
nicht effizient aber simple, fürs erste
Gesucht wird die günstigste Mischung mit 2% Genauigkeit.
Menge > 200t, und Eisenanteil > 60%.
Neben Eisen "Iron Share" gibt es noch weitere solcher
Bedingungen die bei ein gültigen Mischung erfüllt sein müssen.
Ich denke was aus dem Rahmen fällt ist die theoretisch mischbare
Menge mit dem Mischungsverhältnis. Da muß man erst kleinste Menge
finden und diese dann hochrechnen. Siehe Beispiel. Sonst müßten alle
Bedingungen 'Linear' wenn ich das richtig verstanden habe.
Wenn man ohne Brute-Force durchkommen könnte, wäre natürlich super.
Ansonsten habe ich noch das hier gefunden
http://www.nvidia.de/object/cuda-parallel-computing-de.html
(eine nvidia titan x hat 7 teraflops ... )
$> lp_solve mix1.lp
Value of objective function: 1.05559e+07
Actual values of the variables:
x0 0
x1 25460
x2 34020
x3 4046.6
x4 136473
Fuer http://lpsolve.sourceforge.net/ gibt es auch eine php
Schnittstelle.
Oder zum ausprobieren auch http://www.phpsimplex.com/en/help.htm.
P.S.:
Beim Ergebnis siehst du das die Summe nur 199999.6 ist. Die Genauigkeit
laesst sich konfigurieren.
@Josef
Ich bin beindruckt. Das kannte ich so noch nicht.
Diese Bedingung vesteht ich allerdings nicht:
-0.425 x0 + 0.086 x3 - 0.00255 x4 >= 0;
Ich denke mal das gibt den Eisenanteil wieder (< 60%).
Gegeben war:
$stock[0]['iron'] = 17.5;
$stock[1]['iron'] = 60;
$stock[2]['iron'] = 60;
$stock[3]['iron'] = 68.6;
$stock[4]['iron'] = 59.745;
x1 und x2 fällt weg. Ab wie kommst Du auf diese Bedingung?
Würde das gern mal mit 30 Komponenten und allen Bedingungen
ausprobieren. Danke!
Erstens wuerde ich die Mathematik anschauen, und nicht auf maximale
Genuaigkeit, sondern auf maximale Geschwindigkeit trimmen. Besser als
0.1% muss man keinen Inhaltsstoff einwiegen koennen.
Zweitens wuerde ich versuchen auf Hyperthreading, dann allenfalls auf
eine GPU zu transportieren versuchen, weshalb geld fuer nichts ausgeben.
und dann versuchen floatingpoint durch integer zu ersetzen versuchen.
@PicTec
Habe im Moment nur ein Beispiel mit 15 Rohstoffen. Und da geht schon
mein Rechner in die Knie. Mit "$p = 1; // Precision" also 1% Genauigkeit
sollte auch C am Ende sein. $p kann man Schrittweise runterschrauben.
10, 5, 4, 2, 1 (muß gerade durch 100 teilbar sein).
Mit 10% sind es mit 15 Rohstoffen schon 1.961.256 Loops ...
Bei 30 Rohstoffen mit 1% dürfte es in Richtung while(true){} gehen :)
Zumindest bei Brute-Force.
Ich würde evt empfehlen ... wenn es nachher zum parallel prozessing
kommt.. auf ada umzusteigen.
Hab mal gehört die Sprache ist oder war predestiniert für parallel
processing.
Sonst interessant zu lesen :)
Zur Aufgabenstellung. Sie ist extrem unvollstaendig. Muss man nun N
Einheitsvolumen, resp N Gewichtseinheiten, moeglichst billig fuellen?
Reicht nicht, es muss nochmals ein paar Kriterien geben. Sonst pumpt man
Fleisch mit Wassser auf, macht Pulver feucht, usw. Dh man wertet Abfall
zum Qualitaetsprodukt auf.
Also nochmals.
@Pic Tech
Zu den Ergebnissen kann ich nur etwas zum Beispiel mit 5 Komponenten vom
05.04.2016 23:35 sagen. (15 Komponenten ist zu viel für PHP)
Hier war mit 4% das beste Ergebnis:
m1 = 0
m2 = 25460 kg
m3 = 33947 kg
m4 = 8487 kg
m5 = 144273 kg
Total Iron Share = 60.17%
Max.Quantity = 212167kg
Price = 53.84
Josef C. war mit LPSolver noch besser (06.04.2016 09:14)
x0 0
x1 25460
x2 34020
x3 4046.6
x4 136473
ergibt:
Total Iron Share = 59.999%
Max.Quantity = 199999kg
Price = 52.78
Weiß jemand wie er auf die Bedingung
-0.425 x0 + 0.086 x3 - 0.00255 x4 >= 0;
gekommen ist? (sorry ... alles etwas Neuland. Danke!)
Roman S. schrieb:> Weiß jemand wie er auf die Bedingung>> -0.425 x0 + 0.086 x3 - 0.00255 x4 >= 0;>> gekommen ist?
Im Code sind die beiden Kommentare:
Josef C. schrieb:> /* 0.175*x0 + 0.60*x1 + 0.60*x2 + 0.686*x3 + 0.59745*x4 >= (x0 + x1 + x2> + x3 + x4)*0.6 */> /* 0.175 x0 + 0.60 x1 + 0.60 x2 + 0.686 x3 + 0.59745 x4 >= 120000; */
In der ersten Gleichung wird links der Inhaltsstoff fuer jedes x
berechnet und summiert. Rechts steht Gesamtmenge * 0.6. Also was
mindestens drinnen sein muss.
Dann wird nur noch umgeformt, alle Variablen auf die linke Seite.
Die zweite Gleichung hat rechts nur absolute Werte 200000*0.6 = 120000,
was nicht immer korrekt ist.
Das lp-format Format fuer den Solver ist etwas einfach gestrickt.
Es gibt bessere Formate.
Hier noch die Loesung fuer 15 Variablen:
$> lp_solve mix2.lp
Value of objective function: 9.03564e+06
Actual values of the variables:
x0 0
x1 25460
x2 34020
x3 2586
x4 79915
x5 0
x6 25460
x7 0
x8 0
x9 0
x10 0
x11 25260
x12 0
x13 0
x14 7299
lp_solve ist kein besonders guter und kein besonders schneller Solver.
Aber damit wird er spielend fertig.
Solche Probleme wurden in den 60ern mit Rechnern in Schrankgroesse
geloest.
Z.B. ist das MPS Eingabe Format noch fuer Lochkarten entwickelt worden.
Aber heutezutage waren das bessere Taschenrechner.
Gruss
wenn ich die letzte Aufrundungsstufe wegmache, bekomme ich dieses
Ergebniss, voriges siehe weiter oben:
m: [0] 0.000% [1] 12.730% [2] 17.010% [3] 0.000% [4] 70.239%
t: [0] 0.000 [1] 25.460 [2] 34.020 [3] 0.000 [4] 140.478
price: 52.189473 -- iron: 59.808291 % -- sum: 199.958000
oder aber:
m: [0] 0.000% [1] 12.730% [2] 17.010% [3] 0.000% [4] 70.539%
t: [0] 0.000 [1] 25.460 [2] 34.020 [3] 0.000 [4] 141.078
price: 52.371543 -- iron: 59.987526 % -- sum: 200.558000
Diese -.425 hatte ich auch mal, denke es ist ein Fehler in der Formel,
wenn
man diese zu vereinfacht, auch wenn das Resultat stimmt.
Denkst du wirklich, dass man bei ueber 100 Tonnen mit Genauigkeit von
100
gramm rechnen sollte oder besser, ich habe die SW auf 1kg Genauigkeit
limitiert, sowie wenn ein Wert unter 2kg rauskommt, wird dieser auf 0
gesetzt.
Hallo,
wäre es vielleicht auch möglich mit lpsolver oder einem anderen Programm
für die lineare Optimierung mehrere Produktionen gleichzeitig "in
Abhängigkeit zueinander" zu berechnen?
z.B.
- 200t mit Iron Share > 60%
- 50t mit Iron Share > 45%
nach dem Schema:
Da alle Produktionen auf den gleichen Bestand zurückgreifen, denke ich
spielt auch Reihenfolge in der ich einzelne Produktionen kalkulieren
später eine Rolle.
Dann verbrauche ich vielleicht in der ersten Produktion einen Rohstoff,
denn ich in der zweiten Produktion dringend benötige, um nicht einen
viel teureren Rostoff verwenden zu müssen.
(Das Beispiel oben ist vereinfach. Bei viel mehr Rohstoffen, Elementen
und vielen von Produktion zu Produktion abweichenden Bedingungen wird
das Problem deutlicher)
Oder geht das nur (wieder) mit Brute Force ... alle möglichen
Reihenfolgen durchrechnen, bei drei Produktionen (1,2,3 und 2,3,1 und
3,2,1 und 1,3,2 ... ) Je mehr Produktionen anstehen würden, desto
schlimmer.
Danke & Viele Grüße
Hi,
normalerweise gibt es nur eine Zielfunktion.
Manchmal kann man aber mehrere Ziele in einer Funktion kombinieren.
Bei deinem Problem scheint das zu gehen.
Roman S. schrieb:
Problem A:
> - 200t mit Iron Share > 60%
Problem B:
> - 50t mit Iron Share > 45%
Die letzten beiden Bedingungen fuer die Mischung hab ich jetzt nicht
nachgeprueft.
Aber es ist nur noch eine Zielfunktion und die Constraints wurden
angepasst, wo noetig.
Literatur:
- irgendein Lehrbuch ueber Operations Research
- Model Building in Mathematical Programming von Paul Williams
- Gemischt-ganzzahlige Optimierung von J. Kallrath
Das Thema kann schnell theorielastig werden. Deshalb sollte man sich
die Buecher mal vorher anschauen, bevor man sie kauft.
Roman S. schrieb:> Oder geht das nur (wieder) mit Brute Force ...
Es gibt viele Optimierungsverfahren und intelligente Suchverfahren...