Antwort
 
LinkBack Themen-Optionen Thema durchsuchen
Alt 10.05.2009, 14:32 Nach oben    #1
Martin Schröder
 
Benutzerbild von Orolhawion
 
Registriert seit: 15.12.2004
Ort: Berlin
Beiträge: 121
Standard prozedural gelöstes Problem parallelisieren

Hallo zusammen,

ich sitze gerade über einer Aufgabe für die Uni und komme gerade nicht so recht weiter.

es ist folgernder Algorithmus gegeben:
Code:
int a[10] = { -1, 5, -2, 0, 1, 4, 6, -4, 3, -6 };
int max_sum=0;
int cur_sum=0;
for( i=0; i<10; ++i ) {
      cur_sum += a[i];
      if( cur_sum < 0 ) cur_sum=0;
      if( cur_sum > max_sum ) max_sum = cur_sum;
}
gesucht ist das ergebnis für max_sum. mit diesen zahlen bekomme ich das ergebnis 14, (wenn ich mich nicht verrechnet hab)

das problem soll parallelisiert werden, also auf mehrere rechner verteilt werden und dazu soll ich mir einen passenden algorithmus überlegen der das problem an sich löst, muss nicht unbedingt dieser algorithmus sein.

wie man leicht feststellen kann, sind reihenfolge vertauschen und irgendwo aufsplitten nicht sinnvoll, da das ergebnis für max_sum damit verfälscht würde.

daher habe ich mir folgendes überlegt: gesucht ist quasi eine liste, die für max_sum das selbe ergebnis liefert, wie meine ausgangsliste.

1. ich kann alle aufeinanderfolgenden zahlen mit gleichem vorzeichen addieren, ohne das ergebnis zu verfälschen. dieser schritt kann also parallelisiert werden. danach sammle ich die ergebnisse der einzelnen nodes ein und bekomme folgende liste:
Code:
int b[7] = { -1, 5, -2, 11, -4, 3, -6 };
// ergebnis immernoch 14
wenn man sich die liste genauer ansieht fällt auf, dass sie alterniert (bzgl. des vorzeichens) weiterhin fällt auf, dass ich führende und schließende zahlen <= 0 von der listen entfernen kann, weil sie das ergebnis nicht für max_sum beeinflussen -> wieder gekürzt, wenn auch nicht parallel.

dann erhalte ich folgende liste:
Code:
int c[5] = { 5, -2, 11, -4, 3};
// ergebnis immernoch 14
nun kann ich unter bestimmten voraussetzungen pärchen bilden.
ich nehme die 5 als erstes und erhalte als temporäre max_sum=5. dann stelle ich fest, dass die -2 und die 11 addiert 9 ergeben und die -4 und die 3 zusammen -1. daraus erhalte ich folgende liste:
Code:
int d[3] = { 5, 9, -1};
// ergebnis immernoch 14
die -1 fällt wieder weg, weil sie am ende steht:
Code:
int e[2] = { 5, 9 };
// ergebnis immernoch 14
und letztendlich kommt wieder 14 raus.

in c darf ich -2 und 11 aber nur addieren, weil |-2| < |max_sum|. sonst würde das nicht funktionieren.

zusammenfassend kann ich also sagen, dass ich weiß wie man nicht-alternierende listen parallelisiert vereinfachen kann, und meine frage an euch lautet nun, wie kann ich die alternierende liste (also b) parallelisieren? und geht das überhaupt? da hakts gerade irgendwie..
__________________
"Wer nicht mit der Zeit geht, wird mit der Zeit gehen."
Game over, Junge! ;)
ENERGIE!
___________________________
Mein Blog
Mein OpenBC
Orolhawion ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 10.05.2009, 17:20 Nach oben    #2
Jonas
 
Benutzerbild von Artemis
 
Registriert seit: 03.06.2006
Beiträge: 331
Standard

Zitat:
Zitat von Orolhawion Beitrag anzeigen
dann erhalte ich folgende liste:
Code:
int c[5] = { 5, -2, 11, -4, 3};
// ergebnis immernoch 14
nun kann ich unter bestimmten voraussetzungen pärchen bilden.
ich nehme die 5 als erstes und erhalte als temporäre max_sum=5. dann stelle ich fest, dass die -2 und die 11 addiert 9 ergeben und die -4 und die 3 zusammen -1. daraus erhalte ich folgende liste:
Code:
int d[3] = { 5, 9, -1};
// ergebnis immernoch 14
Dieser Schritt geht aber nur, wenn die negative Zahl kleiner ist, als das Ergebnis von vorher - hierbei ginge es nicht:

Code:
int c[5] = { 5, -6, 11, -4, 3};
__________________
Applikations-Programmierung:
BlitzMax, BlitzPlus

Webentwicklung:
PHP, (X)HTML, CSS, JavaScript, MySQL


Artemis ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 10.05.2009, 22:56 Nach oben    #3
Martin Schröder
 
Benutzerbild von Orolhawion
 
Registriert seit: 15.12.2004
Ort: Berlin
Beiträge: 121
Standard

Zitat:
Zitat von Artemis Beitrag anzeigen
Dieser Schritt geht aber nur, wenn die negative Zahl kleiner ist, als das Ergebnis von vorher - hierbei ginge es nicht:

Code:
int c[5] = { 5, -6, 11, -4, 3};
Zitat:
Zitat von Orolhawion Beitrag anzeigen
in c darf ich -2 und 11 aber nur addieren, weil |-2| < |max_sum|. sonst würde das nicht funktionieren.
das sagte ich bereits..
__________________
"Wer nicht mit der Zeit geht, wird mit der Zeit gehen."
Game over, Junge! ;)
ENERGIE!
___________________________
Mein Blog
Mein OpenBC
Orolhawion ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 11.05.2009, 08:17 Nach oben    #4
Lutz Mahlstedt
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 827
Standard

Ich habe das zwar jetzt nur überflogen und verstehe auch leider nichts von Parallelisierung, aber hast du einen Fehler im Code oder rechne ICH falsch?

Code:
int a[10] = { -1, 5, -2, 0, 1, 4, 6, -4, 3, -6 };
int max_sum=0;
int cur_sum=0;
for( i=0; i<10; ++i ) {
      cur_sum += a[i];
      if( cur_sum < 0 ) cur_sum=0;
      if( cur_sum > max_sum ) max_sum = cur_sum;
}
Ich komme auf ein Ergebnis von 7, nicht 14! Oder ist das "+=" nicht korrekt? Denn dann wäre die Reihenfolge meiner Meinung nach folgende:

-1 -> cur_sum < 0 -> 0
5 -> 0+5 -> 5
-2 -> 5+(-2) -> 3
0 -> 3+0 -> 3
1 -> 3+1 -> 4
4 -> 4+4 -> 8
6 -> 8+6 -> 14
-4 -> 14+(-4) -> 10
3 -> 10+3 -> 13
-6 -> 13+(-6) -> 7

Die Regel, dass bei negativen Zahlen in cur_sum dieses auf 0 gesetzt wird erfolgt ja nur ein Mal am Anfang!? Von daher verstehe ich gerade nicht, wie du auf 14 kommst!?
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 11.05.2009, 08:26 Nach oben    #5
Martin Schröder
 
Benutzerbild von Orolhawion
 
Registriert seit: 15.12.2004
Ort: Berlin
Beiträge: 121
Standard

Zitat:
Zitat von MrNiceGuy Beitrag anzeigen
Ich habe das zwar jetzt nur überflogen und verstehe auch leider nichts von Parallelisierung, aber hast du einen Fehler im Code oder rechne ICH falsch?
nicht wirklich, du betrachtest nur nicht max_sum sondern cur_sum.

Zitat:
Zitat von MrNiceGuy Beitrag anzeigen
Ich komme auf ein Ergebnis von 7, nicht 14! Oder ist das "+=" nicht korrekt? Denn dann wäre die Reihenfolge meiner Meinung nach folgende:

-1 -> cur_sum < 0 -> 0
5 -> 0+5 -> 5
-2 -> 5+(-2) -> 3
0 -> 3+0 -> 3
1 -> 3+1 -> 4
4 -> 4+4 -> 8
6 -> 8+6 -> 14
-4 -> 14+(-4) -> 10
3 -> 10+3 -> 13
-6 -> 13+(-6) -> 7

Die Regel, dass bei negativen Zahlen in cur_sum dieses auf 0 gesetzt wird erfolgt ja nur ein Mal am Anfang!? Von daher verstehe ich gerade nicht, wie du auf 14 kommst!?
nochmal genau den code ansehen. max_sum wird nie verringert, daher bleibt es bei 14.
es ist C-Code. x += y; ist gleichbedeutend mit x = x+y;
__________________
"Wer nicht mit der Zeit geht, wird mit der Zeit gehen."
Game over, Junge! ;)
ENERGIE!
___________________________
Mein Blog
Mein OpenBC
Orolhawion ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 11.05.2009, 09:55 Nach oben    #6
Lutz Mahlstedt
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 827
Standard

Ups, alles klar, dann stimmt das natürlich doch, ich hatte nur auf cur_sum geachtet

EDIT: Was += bedeutet war mir schon klar, ich habe nur nicht beachtet, dass er explizit von max_sum sprach...
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 11.05.2009, 12:55 Nach oben    #7
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 396
Standard

Mal von der Sache her macht das Parallelisieren in diesem Fall keinerlei Sinn, da sich die Performance nicht steigert. Aber wie dem auch sei.



Ein anderer Ansatz wäre, nicht den Algorithmus selbst zu verwenden um zu parallelisieren, sondern Teilaufgaben daraus. Beispielsweise das Zusammenfassen von zwei aufeinander folgende positive Zahlen. Jeder Node beginnt bei Position X und schaut, ob dort aufeinander folgende positive Zahlen sichtbar sind. Als Ergebnis kommt dann zurück: Ja/Nein (ggf. auch die Summer der beiden zusammengefassten Zahlen)

Sprich: Das was du oben beschrieben hast, die Teilschritte um die Liste zu verkürzen, die kannst du durch deine Nodes vorberechnen lassen. Wenn sich nichts zusammenfassen lässt, sind deine Nodes überflüssig. Wenn sich aber was zusammenfassen lässt, kann dein Node das tun in der Hoffnung, dass der Master mit seinem Algorithmus noch nicht so weit ist.
Sprich: Die Nodes erleichtern dem Master damit die Arbeit, denn je größer die Liste ist, desto eher werden die Nodes dieselbige verkürzen.



Zweite Alternative: Du lässt jeden Node an einer neuen Position auf Verdacht losrechnen. Beispiel:
Node 0 beginnt bei Index 0.
Node 1 beginnt bei Index 1
Node 2 beginnt bei Index 2 usw.
Sobald deine Nodes bei folgender Konstellation ankommen:
Code:
if( cur_sum < 0 ) cur_sum=0;
(btw. ich würde dies auf <= 0 ändern. Sieht im ersten Moment sinnlos aus aber wenn du diese Bedingung als Abbruchbedingung für einen Node definierst, macht das wieder Sinn)
brechen sie ihre Arbeit ab und haben ein Teilergebnis. Gleichzeitig weißt du, dass du ab dem nächsten Index wieder ein neues Teilergebnis brauchst.
Also etwa so:
10 Array-Elemente -> 10 Nodes -> 10 Teilergebnisse
Der erste Node rechnet die erste Zahl, bricht ab. Teilergebnis 0.
Der zweite Node rechnet die zweite Zahl bis zum Ende. Teilergebnis 14.
Alle übrigen Nodes rechnen zwar, werden aber ignoriert, da der zweite bereits bis zum Ende rechnete.

Das kannst du noch feintunen, dass der zweite Node Teilergebnisse der übrigen Nodes auch berücksichtigt, um selbst nicht zu viel rechnen zu müssen. Das ist aber ein Timing-Problem und erst bei hunderttausenden von Zahlenreihen sinnvoll.

Würde der zweite Node irgendwann bei der 5. Zahl oder so abbrechen (weils negativ oder 0 wird) wüsstest du, wieviele Nodes nicht berücksichtigt werden müssen. Und du hast dann sofort einen weiteren Node, der ab dieser fünften Zahl loslegt und dir die neuen Teilergebnisse liefert.
__________________
Open Sourcing the Online Gaming Universe (bald wieder)
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
Das Game Developer Consultant Team öffnet langsam seine Pforten
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 11.05.2009, 14:39 Nach oben    #8
Martin Schröder
 
Benutzerbild von Orolhawion
 
Registriert seit: 15.12.2004
Ort: Berlin
Beiträge: 121
Standard

Zitat:
Zitat von mepeisen Beitrag anzeigen
Mal von der Sache her macht das Parallelisieren in diesem Fall keinerlei Sinn, da sich die Performance nicht steigert. Aber wie dem auch sei.
naja, das ist wohl abhängig von dem was pro iteration so passiert, bei simplem addieren, wie in diesem fall, hast du natürlich recht.

danke für deine antworten.

ich habe noch ein wenig recherchiert und es handelt sich offenbar um Kadane's Algorithmus Dazu gibt es ein ellenlanges paper von der uni cantebury. das was in diesem paper steht sieht vielversprechend aus, ich setze mich da mal ran. :)
__________________
"Wer nicht mit der Zeit geht, wird mit der Zeit gehen."
Game over, Junge! ;)
ENERGIE!
___________________________
Mein Blog
Mein OpenBC
Orolhawion ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 11.05.2009, 17:09 Nach oben    #9
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 396
Standard

Jetzt wo dus verlinkt hast. Dem gleichen Problem liegt ein Div zugrunde.
*sich-selbst-an-die-Stirn-fasst*

Nun weiß ich auch, warum du so einen komischen Algorithmus hast :)
__________________
Open Sourcing the Online Gaming Universe (bald wieder)
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
Das Game Developer Consultant Team öffnet langsam seine Pforten
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
qooxdoo in Eclipse einbinden don_pazo Eclipse 0 08.01.2009 10:41
Problem mit Image-blobs und fpdf centauro PHP-Programmierung 1 19.10.2008 12:26
Problem mit LaTex (Facharbeit) mouCe Sonstige Programmiersprachen 6 04.12.2006 00:13
Problem mit Cookie und Reloads... Bookworm PHP-Programmierung 10 13.04.2006 12:09
OSX + Eclipse 3.1 Problem bacarni Eclipse 3 29.07.2005 21:19


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:22 Uhr.


Powered by vBulletin® Version 3.8.4 (Deutsch)
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0

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