Hintergrund
Zum Zeitpunkt des Schreibens dieses Dokuments ist das P vs NP-Problem noch ungelöst, aber Sie haben vielleicht von Norbert Blums neuem Aufsatz gehört , der den Beweis erbringt, dass P! = NP ist, was bereits als fehlerhaft vermutet wird (aber wir werden sehen).
Das in diesem Artikel diskutierte Problem ist das Cliquenproblem . Zumindest habe ich das in einem Zeitungsartikel gelesen, also korrigieren Sie mich, wenn ich falsch liege, aber auf jeden Fall möchten Sie, dass Sie ein Programm schreiben, das die folgende Variante löst:
Die Aufgabe
Angenommen, wir haben eine große Schule mit vielen Schülern. Jeder dieser Schüler hat einige Freunde an dieser Schule. Eine Clique von Studenten ist eine Gruppe , die nur aus Studenten besteht , die Freunde mit sind jedes andere Mitglied .
Ihr Programm erhält befreundete Schülerpaare als Input. Aus diesen Informationen muss das Programm die Größe der größten Clique ermitteln . Die Schüler werden durch ganzzahlige IDs identifiziert .
Wenn Sie mathematische Begriffe bevorzugen, bedeutet dies, dass Sie die Kanten eines ungerichteten Graphen erhalten, der durch jeweils zwei Knoten gekennzeichnet ist.
Eingang
Ihre Eingabe ist eine nicht leere Liste positiver ganzzahliger Paare, z [[1,2],[2,5],[1,5]]
. Sie können diese Eingabe in jeder sinnvollen Form vornehmen, z. B. als Array von Arrays, als Textzeilen mit jeweils zwei Zahlen usw.
Ausgabe
Die erwartete Ausgabe ist eine einzelne Zahl n >= 2
: die Größe der größten Clique. Mit dem Beispiel Eingang oben, wäre das Ergebnis 3
, da alle Schüler ( 1
, 2
und 5
) miteinander befreundet sind.
Testfälle
[[1,2]]
=> 2
[[1,2],[3,1],[3,4]]
=> 2
[[1,2],[2,5],[1,5]]
=> 3
[[2,5],[2,3],[4,17],[1,3],[7,13],[5,3],[4,3],[4,1],[1,5],[5,4]]
=> 4 (the largest clique is [1,3,4,5])
[[15,1073],[23,764],[23,1073],[12,47],[47,15],[1073,764]]
=> 3 (the largest clique is [23,764,1073])
[[1296,316],[1650,316],[1296,1650],[1296,52],[1650,711],[711,316],[1650,52],
[52,711],[1296,711],[52,316],[52,1565],[1565,1296],[1565,316],[1650,1565],
[1296,138],[1565,138],[1565,711],[138,1650],[711,138],[138,144],[144,1860],
[1296,1860],[1860,52],[711,1639]]
=> 6 (the largest clique is [52,316,711,1296,1565,1650])
Sie können diese (blöde) Referenzimplementierung verwenden (zusätzliche Ausgabe mit -d
Flag ausgeben ), um die Ergebnisse anderer Testfälle zu überprüfen.
Die Regeln
- Ihr Programm benötigt kein definiertes Ergebnis bei ungültiger Eingabe. Sie können also davon ausgehen, dass:
- Sie erhalten immer mindestens ein Paar IDs
- Jedes Paar besteht aus zwei verschiedenen IDs
- kein Paar erscheint zweimal (das Vertauschen der Stellen der IDs wäre immer noch dasselbe Paar)
- Ihr Algorithmus darf keine Obergrenze für die Eingabegröße festlegen. Rein technische Einschränkungen und Einschränkungen, die durch Ihre Sprache / Umgebung (wie Stapelgröße, Rechenzeit usw.) festgelegt werden, sind natürlich unvermeidlich.
- Standardlücken sind verboten.
- Das ist Code-Golf , also gewinnt der kürzeste Code, gemessen in Bytes.
- Wenn Ihr Algorithmus eine polynomielle Zeitkomplexität aufweist, erzielen Sie
-1
unabhängig von Ihrer Codegröße sofort eine Punktzahl. In diesem Fall möchten Sie Ihre Lösung möglicherweise an einer anderen Stelle einreichen. ;)
quelle
-1
ist das wohlverdient ;)Antworten:
Jelly ,
15 1816 Bytes+3 Bytes, um Fehler in meiner Methode zu beheben.
-2 Bytes dank Meilen ( n × (n-1) ÷ 2 = nC2 )
Ein monadischer Link, der die Liste der Freundschaften (Kanten) aufnimmt und eine Ganzzahl zurückgibt.
Probieren Sie es online!bildet die Potenz der Kanten im Speicher und ist daher sowohl räumlich als auch zeitlich ineffizient (yep, das sind O (2 n ) Leute)!
Wie?
quelle
Mathematica, 34 Bytes
Grundsätzlich erledigt FindClique die Aufgabe und "findet eine größte Clique in der Grafik g."
Alles andere wandelt die Eingabeliste in eine Grafik um
Eingang
Ausgabe
Eingang
Ausgabe
Danke @Kelly Lowder für -10 Bytes
quelle
Tr[1^#&@@FindClique[#<->#2&@@@#]]&
FindClique
ಠ ___ ಠGelee , 20 Bytes
Probieren Sie es online!
Das verdient natürlich nicht die Million: p
Dies hätte Pyth geschlagen, wenn nicht
µ(...)µ
und 2-ByteÐf
.quelle
J , 36 Bytes
Probieren Sie es online!
Läuft in Zeit O (2 n ), wobei n die Anzahl der Paare ist.
Eine schnellere Lösung für 65 Bytes ist
Probieren Sie es online!
Erläuterung
quelle
Pyth, 19 Bytes
Probieren Sie es hier aus.
quelle
Python 2 , 180 Bytes
Probieren Sie es online!
-2 dank shooqie .
-1 Danke an Herrn Xcoder .
-3 dank rekursiv .
quelle
len
einer Variablen(x not in y)
bedeutet0**(x in y)
.0**
mit-~-
.Pyth, 28 Bytes
Probieren Sie es online aus
Erläuterung
quelle
Python 3 ,
162159 BytesProbieren Sie es online!
Die Funktion c nimmt Eckpunkte in Form einer Menge
sortierterTupel ({(x, y), ...}, wobei x kleiner als y ist).Eine Funktion mit dem Namen "entry" befindet sich im TIO-Header, um Daten im Format "Liste unsortierter Listen" zu testen. Wenn clique, wird length zurückgegeben. Wenn nicht clique, wird die maximale Cliquegröße der Scheitelpunkte abzüglich eines Scheitelpunkts für jeden Scheitelpunkt in den Scheitelpunkten zurückgegeben. Zeitüberschreitung beim letzten Testfall in TIOUpdate: "oder (z, y) in x" Teil hinzugefügt, um die Abhängigkeit von der Sortierbarkeit zu beseitigen "f = lambda x: {i für s in x für i in s}" anstelle von itertools.chain in set.
-Minus 3 Bytes dank @ Jonathan Allen
quelle
c
, also können Sie entfernenc=
(Sie müsstenc=\
am Ende des Headerslambda
einfügen und das am oberens
und ersetzens(...)
mit{*...}
ermöglicht die Entfernung von einigen Räumen zu.05AB1E , 19 Bytes
Probieren Sie es online!
quelle
Gelee , 28 Bytes
Probieren Sie es online!
Schnellere Lösung, mit der der letzte Testfall in Sekundenschnelle mit TIO gelöst werden kann.
quelle
n
nur in den Basen auftauchen dürfen , um eine Million wert zu sein :)Java + Guava 23.0, 35 + 294 = 329 Bytes
Dieser Algorithmus zeichnet nicht grafisch, sondern generiert alle Kombinationen von Paaren einer bestimmten Größe. Ich füttere alle Paarkombinationen zu einem Multiset und überprüfe, ob sie alle die erwartete Größe haben (die Anzahl der eindeutigen Einträge - 1). Wenn ja, habe ich eine Clique gefunden und suche eine größere.
Aus der Guava-Bibliothek verwende ich die neue
combinations
Methode und den Tool-Collection-TypMultiset
.Ungolfed
quelle
x
ist Polynom " <- sind Sie sicher? Ich denke , das ist die angewandte Methode . Der Rückgabewert ist einAbstractSet
mit einem Iterator, und die folgendefor
Schleife wird diesen Iteratorx!
mal aufrufen, wenn ich mich nicht irre ...x < n
(mitn
der vollständigen Größe der Eingabemenge), ist es immern!/(x!(n-x)!)
noch kein Polynom :)combinations
Methode bekommen kann, dieX^n
(durchaus möglich) ist , wenn ich sie erstelle? In der Zwischenzeit entferne ich meinen Anspruch von "-1".Python 2 , 102 Bytes
Probieren Sie es online!
quelle
6502 Maschinencode (C64),
774703 Bytes(Ich gerade hatte , dies zu tun, mein C64 kann alles ... hehe)
Hexdump:
Online-Demo
Verwendung: Beginnen Sie mit
sys49152
, und geben Sie dann die Paare einzeln pro Zeile ein, wie zBacksapce ist nicht bei der Eingabe behandelt (aber wenn Sie verwenden
vice
, kopieren einfach Ihre Eingabe in den Emulator). Geben Sie eine leere Zeile ein, um die Berechnung zu starten.Dies ist zu groß, um hier eine erklärende Auflistung der Demontage zu veröffentlichen, Sie können jedoch die Assembly-Quelle im Stil von ca65 durchsuchen . Der Algorithmus ist sehr ineffizient, er generiert jede mögliche Permutation der Knoten und bildet mit jedem von diesen gierig eine Clique, indem er alle Kanten überprüft. Dies ermöglicht einen Raumwirkungsgrad von O (n) (wichtig auf einer Maschine mit diesem kleinen RAM), hat aber eine schreckliche Laufzeiteffizienz (*) . Die theoretischen Grenzen liegen bei bis zu 256 Knoten und bis zu 8192 Kanten.
Es gibt eine größere Version (
883805 Byte) mit besseren Funktionen:Online-Demo
Quelle durchsuchen
(*) Der letzte Testfall dauert zwischen 12 und 20 Stunden (ich habe geschlafen, als er endlich fertig war). Die anderen Testfälle enden schlimmstenfalls innerhalb weniger Minuten.
quelle