Ihre Mission ist es, einen Algorithmus (Programm oder Funktion) zu entwickeln, der das Verpacken von Obst von einem Förderband in Säcke, die an Einzelhändler versandt werden sollen, optimiert und für die meisten Säcke optimiert.
Jeder Beutel muss mindestens eine bestimmte Menge wiegen, aber jeder Überschuss geht als Gewinn verloren, da dieses Gewicht zum Befüllen eines anderen Beutels verwendet werden könnte. Ihre Verpackungsmaschine hat immer eine Vorausschau nach n
Früchten aus der Warteschlange und kann diese n
Früchte möglicherweise nur der (einzelnen) Tasche hinzufügen , die gerade verarbeitet wird. Es kann nicht über die n
ersten Elemente in der Warteschlange hinaussehen. Das Programm weiß immer genau, wie viel Gewicht sich bereits in der Tasche befindet.
Ein anderer Weg, dies zu visualisieren, ist ein Förderband mit einer Ladefläche n
am Ende, von dem eine Frucht entnommen werden muss, bevor eine neue Frucht ankommt. Eventuell übrig gebliebene Früchte und ein nicht voller Beutel am Ende werden verworfen.
Eingänge
- Liste / Anordnung der Fruchtgewichte in der Warteschlange (positive ganze Zahlen)
- Mindestgesamtgewicht für Beutel (positive ganze Zahl)
- Lookahead
n
(positive ganze Zahl)
Ausgabe
Ihr Algorithmus sollte für alle Beutel die Gewichte der Früchte in ihnen zurückgeben, mit welchen Mitteln auch immer dies für Sie und Ihre Sprache zweckmäßig ist, sei es der Standardwert oder ein Rückgabewert oder etwas anderes. Sie sollten in der Lage sein, das Programm auszuführen und Ihre Punktzahl in einer Minute auf Ihrem Computer zu berechnen.
Beispiel
Total weight 1000, lookahead of 3 and fruit queue:
[171,163,172,196,156,175,162,176,155,182,189,142,161,160,152,162,174,172,191,185]
One possible output (indented to show how the lookahead affects the bagging):
[171,163,172, 156,175, 176]
[162, 155,182,189, 161,160]
[152,162,174,172,191,185]
Wertung
Ihr Algorithmus wird in sechs Läufen mit einer Charge von 10000 Orangen, die ich für Sie vorbereitet habe, auf Lookaheads von 2 bis 7 einschließlich an beiden Enden getestet . Sie sind in Säcke mit einem Gewicht von mindestens 1000 Stück zu verpacken. Die Orangen werden normalerweise mit einem Durchschnittsgewicht von 170 und einer Standardabweichung von 13 verteilt, wenn dies hilfreich ist.
Ihre Punktzahl ist die Summe der Taschen aus den sechs Läufen. Die höchste Punktzahl gewinnt. Standardlücken sind nicht zulässig.
Einfache Beispielimplementierung und Test-Suite-Boilerplate in Haskell
Antworten:
Python 3,
99649981 TaschenDie Idee dieser Lösung ähnelt der von Jonathan, JayCe und fortraan, jedoch mit einer Bewertungsfunktion =)
Diese Lösung fügt die besten Teilmengen des Lookahead-Bereichs gemäß dem an
score
.score
Liefert eine Reihenfolge über die Teilmengen nach folgendem Schema:expected_mean
versucht vorherzusagen, wie der Rest der Werte aussehen soll (vorausgesetzt, ihre Auswahl ist optimal).UPD :
Hier ist eine weitere Beobachtung: Sie können alle Orangen aus der besten Teilmenge in den Beutel legen, ohne die Leistung des Algorithmus zu beeinträchtigen. Wenn Sie einen Teil davon verschieben, können Sie den Rest danach verschieben, und der Rest sollte immer noch die beste Option sein (ohne neue Orangen), wenn die Wertung stimmt. Darüber hinaus besteht auf diese Weise die Möglichkeit, die Menge der Kandidaten, die in den Beutel gegeben werden sollen, dynamisch zu verbessern, indem vor dem Befüllen des Beutels mehr Orangen zu sehen sind. Und Sie möchten so viele Informationen wie möglich haben. Es macht also keinen Sinn, mehr als eine Orange gleichzeitig in die Tasche zu legen.
Versuch es!
quelle
powerset
Funktion in diesem Fall überflüssig, weil eslen(list_)
sowieso gleich ist?)expected_mean(w)
, die als gute Ergebnisse gibt:return (w+2) / max(1, round((w+2) / mean))
Python 3 , 9796 Taschen
Aufbauend auf Jonathans Antwort:
Dies basiert auf Powerset aus dem Kochbuch von itertool. Findet zuerst die optimale Teilmenge des Puffers basierend auf der Minimierung der Differenz zum Zielgewicht für alle Teilmengen und wählt dann ein Element aus dieser Teilmenge basierend auf demselben Kriterium aus. Wenn keine optimale Teilmenge aus dem gesamten Puffer auswählt.
quelle
C ++ 17, 9961.58 (Durchschnitt über einige zufällige Samen)
(Scrollen Sie zur Erklärung nach unten, wenn Sie C ++ nicht kennen.)
(wenn
<
im Grunde genommen verwendet wird, versucht der Algorithmus die Anzahl der Taschen zu minimieren )Inspiriert von dieser Antwort .
TIO-Link für 250 Wiederholungen: Probieren Sie es online!
Definiert eine Funktion (eigentlich sieht sie nur aus wie eine Funktion, es ist eine Struktur)
pick_orange
, die unter Berücksichtigungvector<int> weights
des Gewichts der Orangen undint remain
des verbleibenden Gewichts des Beutels den Index der Orange zurückgibt, die gepflückt werden soll.Algorithmus:
500
Wiederholungszeiten{
erzeugen zufällige (fake) Orangen (Normalverteilung mit Mittelwert 170 und stddev 13) , bis es gibt
N_NEW_ORANGES=7
Orangenjede Teilmenge Summe , dessen Pick am kleinsten ist und nicht kleiner als
remain
(die Funktionbacktrack
ist , dass)in dieser Teilmenge als alle Orangen markiert gut
}
Der Durchschnitt der Häufigkeit, mit der eine Orange als gut der (echten) Orangen mit gleichem Gewicht bewertet wird,
ergibt die beste Orange
Das Programm enthält 3 fest codierte Konstanten, die nicht aus dem Problem abgeleitet werden können:
N_NEW_ORANGES
(die Vorhersagelänge). Wenn Sie dies erhöhen, wird das Programm exponentiell länger ausgeführt (da der Backtrack).quelle
invalid use of template-name ‘std::normal_distribution’
. Keine Probleme mit gcc 7.1.0.Python 2 , 9756 Taschen
Lassen Sie uns die Orange ins Rollen bringen ...
Probieren Sie es online!
Pflückt die Früchte immer aus dem Puffer, wodurch die absolute Differenz zwischen dem neuen Gewicht und dem Zielgewicht minimiert wird.
quelle
Python 3, 9806 Taschen
Aufbauend auf den Antworten von Jonathan und JayCe:
Probieren Sie es online!
Wie es funktioniert
Angenommen, die Tüte enthält 900 Einheiten und es stehen 2 Früchte zur Verfügung: eine Frucht mit 99 Einheiten und eine Frucht mit 101 Einheiten. Befindet sich die Frucht mit 99 Einheiten näher am Anfang der Lookahead-Liste,
min
wird sie anstelle von 101 ausgewählt. In diesem Fall benötigen wir jetzt eine weitere Frucht, um die verbleibende benötigte Einheit zu erfüllen. Ich habe das Programm geändert, um in diesen Fällen die höherwertigen Früchte zu bevorzugen.Dies geschieht, indem die Lookahead-Liste vor dem Powersetting sortiert und dann umgekehrt wird.
quelle
PHP, 9975 Beutel
am längsten von allen Einsendungen, sollte aber lesbar sein
Versuch es
quelle
Python 3,
98559928994799569964 TaschenBasiert auf Jonathan Allans Startercode, ist aber ungolfed, um lesbar zu sein.
Idee: Seit 1000/170 = 5.88 versuchen wir, Früchte in der Nähe von 1000/6 auszuwählen (ich habe mit den magischen Konstanten herumgespielt). Wenn die letzte Frucht in der Tüte den Abfall minimieren kann, verwenden wir stattdessen diese.
Diese Lösung enthält Beutelsummenziele für jede hinzugefügte Frucht. Ich werde wahrscheinlich hier aufhören. Ich habe Nelder-Mead verwendet, um mein
targets
Array zu finden :9956 Taschen
Das 9947 bags- Programm ist besonders einfach:
quelle
targets
? Training auf zufälligen Daten?Rubin , 9967 Beutel
Probieren Sie es online!
Wenn Sie genug Gewicht haben, um den Beutel zu füllen, suchen Sie die leichteste Teilmenge, die den Beutel füllen kann, und verwenden Sie die hellste Orange dieser Teilmenge. Andernfalls bringen Sie das verbleibende Gewicht so nahe wie möglich an ein Vielfaches von 170.
quelle
Schläger / Schema, 9880 Taschen
Um zu entscheiden, welches Stück Obst in den Beutel gegeben werden soll, vergleichen Sie das optimale Beutelgewicht mit dem Gewicht des Beutels mit dem zusätzlichen Stück Obst. Wenn es das optimale Gewicht ist, verwenden Sie es. Wenn es übergewichtig ist, minimieren Sie die überschüssige Menge. Wenn es untergewichtig ist, minimieren Sie die überschüssige Menge, nachdem Sie versucht haben, eine optimale Lücke zu lassen.
quelle
Haskell , 9777 Taschen
Dies war mein erster Versuch:
Probieren Sie es online!
quelle
Haskell , 9981 Beutel
Die Codegolf-Python von Angs → Jonathan Allan → JayCe → Fortraan → Alex → Roman Czyborra könnte für eine zusätzliche mathematische Reinheit entlang des gleichen Hauptgedankens zu Haskell zurückkehren
(<miss)==False<True
)für die ganze Zahl umgekehrt die
(m-n)/sqrt(n)==(n+1-m)/sqrt(n+1) <==> n=sqrt(m^2-1/4)-1/2
von einem https://en.wikipedia.org/wiki/Sum_of_normally_distributed_random_variablesgewürzt mit einigen unnötigen Sinnlosigkeit
Probieren Sie es online!
ohne einen anderen numerischen Gewinn auf den zuvor geernteten 9981 Orangennetzen zu erzielen, während mein 10k011-Beutelpacker, der ungeeignete Orangen aus nicht verschlossenen Beuteln zurückholte, von user69850 in persona user202729 disqualifiziert wurde → Jo King → ovs, daher ging die verdiente Prämie an Alex
quelle