Sortieren Sie 2 Listen in Python basierend auf dem Verhältnis der einzelnen entsprechenden Elemente oder basierend auf einer dritten Liste

8

Ich versuche, verschiedene Implementierungen für ein gebrochenes Rucksackproblem zu schreiben.

Dafür habe ich zwei Arrays:

  1. Werte
  2. Gewichte

Der Elementwert [n] entspricht Elementgewichten [n]. So können wir value_per_unit als:

berechnen %Vor%

Ich brauche jetzt die 2 Arrays (Werte und Gewichte), die nach dem value_per_unit Array

sortiert werden sollen

zB: Wenn

  • Werte = [60, 100, 120]
  • Gewichte = [20, 50, 30]

Dann

  • values_per_unit = [3.0, 2.0, 4.0]

  • und so lautet values_per_unit_sorted [2.0, 3.0, 4.0]

Ich brauche die Arrays für Werte und Gewichte:

  • values_sorted = [100, 60, 120]
  • weights_sorted = [50,20,30]

Gibt es eine Möglichkeit, dies mit einfachen Lambda-Funktionen zu erreichen?

Ich kann immer noch so etwas machen, aber es scheint jedes Mal sehr ineffizient zu sein, wenn ich auf die Elemente zugreifen muss:

%Vor%     
Yogesh 19.07.2017, 16:33
quelle

4 Antworten

6

In einer Zeile:

%Vor%

Um zu erklären: Zippen Sie zuerst die Listen, um sie zu paaren.

%Vor%

Sortieren Sie dann nach dem Quotienten aus Wert und Gewicht.

%Vor%

Entpacken Sie sie schließlich wieder in separate Listen.

%Vor%

Eine Alternative besteht darin, Tupel zu konstruieren, die explizit das Verhältnis als erstes Element enthalten.

%Vor%

Ersteres scheint bei einigen schnellen Tests etwas schneller zu sein. Wenn Sie nach einem optimalen Algorithmus suchen, werden Sie wahrscheinlich Dinge ausrollen müssen und die Lösung wird nicht so prägnant sein.

Und um den Kommentar von @TomWyllie zu adressieren, können Sie, wenn Sie bereits die Liste der Verhältnisse haben, verwenden:

%Vor%

Beachten Sie, dass diese beiden letzten Lösungen sich von der ursprünglichen Lösung unterscheiden, wenn zwei Paare das gleiche Verhältnis haben. Diese Lösungen werden sekundär nach Wert sortiert, während die erste Lösung die Elemente in der gleichen Reihenfolge wie die ursprüngliche Liste enthält.

    
Jared Goguen 19.07.2017, 16:40
quelle
0

Eine elegante Methode ist eine multidimensionale Liste mit den Werten und Gewichten:

%Vor%

Verwenden Sie dann die Sortiermethode mit einem Wert geteilt durch das Gewicht als Schlüssel.

%Vor%     
jmcampbell 19.07.2017 16:50
quelle
0

Für eine explizitere (aber wohl weniger pythische) Lösung erstellen Sie eine Liste von Indizes, sortiert nach dem Wert in diesem Index in value_per_unit , und ordnen Sie values und weights entsprechend neu an .

%Vor%

Ausgaben:

%Vor%

Sie können das aufräumen, indem Sie unnötige zusätzliche Schleifen mit zip und mit einem Generatorausdruck beseitigen;

%Vor%

Welche Ausgänge;

%Vor%

Beachten Sie, dass diese endgültigen Werte tuples nicht lists sind. Wenn die Ausgabe wirklich eine Liste sein soll, sollte ein einfaches values, weights = map(list, (values, weights)) genügen. Du könntest das sogar in den einen Liner einwickeln, obwohl es zu diesem Zeitpunkt wahrscheinlich ziemlich schwer wird, dem zu folgen, was passiert.

    
Tom Wyllie 19.07.2017 16:48
quelle
-1

Das Problem, das Sie haben, liegt daran, dass Sie für jedes Element ein berechnetes Feld verwenden (Element I wird den berechneten Wert values[I]/weights[I] haben). Um dies zu lösen und es trotzdem extrem einfach zu halten, können Sie es in ein Tupel dieser Form verwandeln: ( calculated_value, (value, weight) ) , pro Element.

Mit diesem Ansatz ist es einfach zu lesen und zu verstehen. Sehen Sie sich die folgende Lösung an:

%Vor%

Beachten Sie auch, dass ich die Schleife von Ihrem ursprünglichen Code geändert habe:

range(values) wurde in range(len(values))

geändert

Da der Bereich die Länge der Liste und nicht die Liste selbst benötigen würde.

    
Ori 19.07.2017 17:06
quelle

Tags und Links