2016-04-10 4 views
0

Ich versuche, ein Array in n gleiche Teile durch Berechnung der Start- und Ende-Indizes zu teilen. Die Adresse der Start- und Endelemente wird an eine Funktion übergeben, die diese Arrays sortiert. Zum Beispiel, wenn ArraySize = 1000, und n = 2, sind die Indizes 0, 499, 999. Bis jetzt habe ich den folgenden Code, aber für ungerade n, es teilt es in mehr als n Arrays. Eine andere Möglichkeit, dies zu tun, ist, n mal durch die Schleife zu laufen, aber ich bin mir nicht sicher, wo ich anfangen soll.Geteiltes C-Array in n gleiche Teile

int chunkSize = arraySize/numThreads; 
    for (int start = 0; start < arraySize; start += chunkSize) { 
     int end = start + chunkSize - 1; 
     if (end > arraySize - 1) { 
      end = arraySize - 1; 
     } 

     InsertionSort(&array[start], end - start + 1); 
    } 

EDIT: Hier ist etwas, das ich mit aufkommen. Es scheint zu funktionieren, aber ich muss etwas gründlicher testen. Ich habe es mehrmals herausgesucht und es von Hand verfolgt. Hoffentlich gibt es keine Randfälle, die scheitern werden. Ich beschränke bereits n> = arraySize.

int chunkSize = arraySize/numThreads; 
for (int i = 0; i < numThreads; i++) { 
    int start = i * chunkSize; 
    int end = start + chunkSize - 1; 
    if (i == numThreads - 1) { 
     end = arraySize - 1; 
    } 

    for (int i = start; i <= end; i++) { 
     printf("%d ", array[i]); 
    } 
     printf("\n"); 
} 
+3

"arraySize = 2, und n = 2, die Indizes werden 0, 499, 999" werfen mehr Licht auf diese Pkease – nullpointer

+0

Sie können + 1 zu "Ende" in jeder Zeile im Körper der Schleife hinzufügen, und dann subtrahiere 1 vom 'Ende' im 'InsertionSort'-Aufruf. 'end = start + chunkSize'; 'end> arraySize'; 'end = arraySize'; 'InsertionSort (& array [start], end)'. Dadurch verlieren Sie eine ganze Reihe von - 1 und + 1 Rauschen. – Kaz

+0

Sorry fixed arrayGröße, um 1000 zu sein. – Shan

Antwort

1

Sie benötigen eine Blockgröße zu berechnen, so dass es „aufzurunden“ ist, nicht nach unten. Man könnte es % Operator und eine komplexere Formel, tut verwenden, aber nur mit einfachen if ist wahrscheinlich einfacher zu verstehen:

int chunkSize = arraySize/numThreads; 
if (chunkSize * numThreads < arraySize) { 
    // In case arraySize is not exactly divisible by numThreads, 
    // we now end up with one extra smaller chunk at the end. 
    // Fix this by increseing chunkSize by one byte, 
    // so we'll end up with numThread chunks and smaller last chunk. 
    ++chunkSize; 
} 
+0

Kannst du mir bitte meine bearbeitete Lösung ansehen? Scheint zu arbeiten. – Shan

+0

@Shan Ja, das funktioniert auch. Dann enden Sie mit kleineren anderen Brocken und größeren letzten Brocken, die bis zu doppelt so groß wie andere Brocken sein können. Ich denke, es ist ein bisschen besser, wenn man einen kleineren letzten Brocken hat, weil dann die Arbeit mehr gleichmäßig zwischen den Threads aufgeteilt wird, zum Beispiel für Array-Größe 8 und 3 Threads: Brocken 3,3,2 ist besser als 2,2,4. Wenn Ihre Array-Größe jedoch größer ist, ist der Unterschied irrelevant. – hyde

+0

'int chunkSize = rund (float (arraySize)/numThreads);' Das scheint es auch zu beheben – Shan

0

Ich hoffe, dass dies dazu beitragen würde:

int chunkSize = arraySize/numThreads; 
    for (int i = 0; i < numThreads-1; i++) { 
     start = i* chunkSize; 
     end = start + chunkSize - 1; 
     InsertionSort(&array[start], end + 1); 
    } 
    //Last chunk with all the remaining content 
    start = end + 1; 
    end = arraySize - 1; 
    InsertionSort(&array[start], end + 1); 
+0

Ich habe in meinem Schnitt eine ähnliche Lösung gefunden. Es scheint zu funktionieren. Da ist dein ist mir so ähnlich. Ich werde deine Antwort akzeptieren, wenn ich bestätigen kann, dass meine idiotensicher ist. – Shan

+0

@ Shan: scheint identisch in Lösung (Y) – nullpointer

2

die minimale Blockgröße berechnet mit die abgeschnittene Teilung. Dann berechne den Rest. Diesen Rest verteilt, indem 1 bis einige chunks Zugabe:

Pseudo-Code:

chunk_size = array_size/N 
bonus = array_size - chunk_size * N // i.e. remainder 

for (start = 0, end = chunk_size; 
    start < array_size; 
    start = end, end = start + chunk_size) 
{ 
    if (bonus) { 
    end++; 
    bonus--; 
    } 

    /* do something with array slice over [start, end) interval */ 
} 

Zum Beispiel, wenn ARRAY_SIZE 11 und N == 4, 11/N ergibt 2. Der Rest ("Bonus") ist 3: 11 - 2*3. Also die ersten drei Iterationen der Schleife wird 1 zu der Größe hinzufügen: 3 3 3. Der Bonus trifft dann Null und die letzte Chunk-Größe wird nur 2.

Was wir hier tun, ist nichts mehr als die Verteilung eines Fehlers Begriff in einer diskreten Quantisierung, auf eine Weise, die irgendwie zufriedenstellend ist. Dies passiert genau dann, wenn ein Liniensegment auf einer Rasteranzeige mit dem Bresenham-Algorithmus gezeichnet wird oder wenn ein Bild mit Floyd-Steinberg-Dithering auf eine kleinere Anzahl von Farben reduziert wird, und so weiter.

Verwandte Themen