Beweis der Richtigkeit des Algorithmus, um zu bestimmen, ob die Elemente eines Arrays gleich oft wiederholt werden

7

Ich entschuldige mich für den langen Titel, aber ich wusste wirklich nicht, wie ich ihn anders schreiben sollte, ohne Informationen über den Inhalt zu haben.

Ich hatte vor kurzem eine Universitätsprüfung über parallele Algorithmen. In einer Übung wurde ich gebeten, einen Algorithmus zu schreiben, um festzustellen, ob die Elemente eines Arrays, nennen wir es A, gleich oft wiederholt wurden.

Zum Beispiel:

1) A = 1 8 8 1 8 1 1 8: Die Antwort lautet ja, jede Zahl wird zweimal wiederholt.

2) A = 7 8 8 5 5 4 7 8: Die Antwort lautet nein.

Ich musste den Algorithmus für ein bestimmtes Modell des parallelen Rechnens schreiben, einen PRAM: Das Modell erforderte einige Techniken, um Lese- / Schreibkonflikte und andere Probleme zu vermeiden, aber dies ist nicht relevant. Am Ende hatte ich ein neues Array, nennen wir es B, das ich wie folgt definieren kann:Given the array A, B[i] contains the number of repetitions of the element A[i] within A.

Zum Beispiel:

1) A = 1 8 8 1 8 1 1 8

B = 4 4 4 4 4 4 4 4

2)A = 7 8 8 5 5 4 7 8

B = 2 3 3 2 2 1 2 3

Wie Sie vielleicht denken und erwarten, müssen Sie nur noch prüfen, ob jedes Element des Banderen gleich ist, aber es stellt sich heraus, dass ich Masochist bin und der Druck der Prüfung (und ich hatte ein bisschen Zeit) Temperatur) führte mich zu einem anderen Weg. Darüber hinaus ist der Vergleich von Elementen eines Arrays mit diesem Rechenmodell nicht unmittelbar.

Um zu überprüfen, ob alle Elemente von gleich Bsind, habe ich alle summiert und das Ergebnis durch die Anzahl der Elemente von geteilt B: Wenn das Ergebnis einem Element von B (zum Beispiel dem ersten B[0]) entspricht, wird der Algorithmus zurückgegeben true( falsesonst).

Nehmen Sie das obige Beispiel:

1) sum = 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 = 32-> 32 / 8 = 4 = B[0]-> Ja.

2) sum = 2 + 3 + 3 + 2 + 2 + 1 + 2 + 3 = 18-> 18 / 8 ≠ 2 = B[0]-> Nr.

Ich weiß, dass es absurd ist, aber darauf bin ich gekommen.

Ich habe diesen Ansatz mit vielen verschiedenen Kombinationen von Arrays / Zahlen überprüft, und es scheint zu funktionieren. Es fällt mir schwer, einen (mathematischen) Beweis dafür zu finden, dass der Algorithmus korrekt ist. Neben dem Ergebnis der Prüfung, das ich noch nicht kenne, bin ich sehr daran interessiert zu wissen, ob es einen mathematischen Beweis / eine mathematische Erklärung gibt, die besagt, dass dieser Ansatz korrekt ist oder nicht, und deshalb brauche ich eine Hilfe.

Ich hoffe, ich habe die Frage auf der richtigen StackExchange-Site veröffentlicht. Wenn nicht, leiten Sie mich bitte auf die richtige Seite weiter.

Vielen Dank im Voraus.

Alessandro
quelle
2
Wie wäre es mit (3 + 2 + 4) / 3 = 3?
Yuval Filmus
@ YuvalFilmus Ich verstehe nicht, was du meinst. Ich denke du hast meine Frage irgendwie falsch verstanden.
Alessandro

Antworten:

11

Nein, Ihr Algorithmus funktioniert nicht. Überlegen Sie, ob das Array A ist

A = [1 1 1 1 1 2 2 3 3 3 3 3 3].

Dann wird das Array B sein

B = [5 5 5 5 5 2 2 6 6 6 6 6 6].

Die Summe von B ist 65 und die Länge von B ist 13. Nach der Division erhalten wir die Zahl 5. Dies entspricht dem ersten Element von B, sodass Ihr Algorithmus "Ja" ausgibt. Trotzdem sind nicht alle Elemente von B gleich und die richtige Antwort lautet "Nein". Ihr Algorithmus gibt also in diesem Fall die falsche Ausgabe aus.

Trotzdem netter Versuch! Herauszufinden, wie man B baut, war wahrscheinlich der schwierigste Teil dieses Problems.


Wie ich das gefunden habe: Ich konnte kein Gegenbeispiel mit zwei unterschiedlichen Zahlen finden, also habe ich es als nächstes mit drei unterschiedlichen Zahlen versucht. Lassenu,v,wGeben Sie an, wie oft jede dieser Zahlen erscheint. Dann hat das Array eine Längeu+v+wund B enthalten den Wert u wiederholt u mal der Wert v wiederholt v Zeiten und w wiederholt w mal, also ist die Summe der Elemente von B u2+v2+w2. Wir können ein Gegenbeispiel finden, wenn wir eine Lösung über die positiven ganzen Zahlen der diophantinischen Gleichung finden können

u2+v2+w2u+v+w=u

so dass vu oder wu. Dies entspricht

u2+v2+w2=u(u+v+w),

wo u,v,w sind positive ganze Zahlen und entweder vu oder wu. Ich habe dann ein paar kleine Werte von ausgewähltuund versuchte, diese diophantinische Gleichung mit Wolfram Alpha zu lösen. Die erste Lösung, über die ich gestolpert bin, waru=5, v=2, w=6, aber es gibt auch viele andere. Rückblickend hätte ich es wohl weiter vereinfachen können

v2+w2=uv+uw

aber ich bemerkte es nicht und es stellte sich heraus, dass es keine Rolle spielte.

DW
quelle
Vielen Dank für die Erklärung! Ich habe alles verstanden. (Traurig :()
Alessandro
5

[2,2,5,5,5,5,5,6,6,6,6,6,6] ist ein Gegenbeispiel.

Wie ich das gefunden habe: (Der letzte Schritt war ein Python-Skript.) Damit nicht alle gleich sind, müssen mindestens zwei unterschiedliche Zahlen angezeigt werden. Die Durchschnittswerte liegen jedoch streng zwischen dem Minimum und dem Maximum. Um Ihr Kriterium zu erfüllen, müssen mindestens drei verschiedene Zahlen vorhanden sein. Ich dachte einfach, es sollte ein Gegenbeispiel mit nur drei verschiedenen Zahlen geben. Aus dem Grund, dass ich vor zwei Sätzen mit nur drei verschiedenen Zahlen angegeben habe, muss man nur prüfen, ob der Durchschnitt die mittlere Zahl ist oder nicht. Mit dieser Beobachtung schrieb ich ein Python-Skript, um Dreifache in Bezug auf die lexikografische Reihenfolge von [Summe, größte, mittlere, kleinste] zu versuchen, und das Array, das ich gab, entspricht dem kleinsten Gegenbeispiel, das das Skript gefunden hat.


quelle
Nett! Das sieht richtig und hilfreich aus. Ich mag die Erklärung, wie Sie es gefunden haben; das scheint wirklich hilfreich zu sein. Ich hoffe, dass die Löschung nur vorübergehend ist - wenn Sie sich dafür entscheiden, sie wiederherzustellen, würde ich sie gerne positiv bewerten.
DW
(Ich lösche mich hatte , weil es nichts zu Ihnen hinzufügen schien.)