Beschleunigen Sie die Permutation


mohamadmahdi

Ich habe die nächste Aufgabe.

Gegebene ganze Zahlen n( 1 <= n <= 1000000) und k( 1 <= k <= n).

Es ist erforderlich, eine Permutation pvon ganzen Zahlen zu finden, 1, 2, 3, ..., nso dass die absolute Differenz zwischen jeweils zwei aufeinanderfolgenden ganzen Zahlen in der Permutation ist >= k, dh für die Permutation pwird abs(p[i] - p[i + 1]) >= kfür alle benötigt i.

Wenn keine solche Permutation für gegebene nund kdann Ausgabe existiert Impossible.

Die ursprüngliche Online-Aufgabe ist in persischer Sprache, deshalb biete ich keinen Link an.

Ich habe den nächsten Code implementiert. Die Lösung der oben genannten Aufgabe ist jedoch sehr langsam. Wie kann ich die Geschwindigkeit verbessern?

from itertools import permutations

n,k=input('').split(' ')

n=int(n);k=int(k)

def check(n,k):
    n=list(n)
    N=n[:]
    result=[]
    b=n.pop(0)
    while n:
        if abs(b-n[0]) >= k:
            result.append(True)
        b=n.pop(0)
    if len(result)+1 == len(N) and all(result):
        return True
    else:
        return False

def solver(n,k):
    return (i
        for i in (permutations(range(1,n+1)))
        if check(i,k)
    )
try:
    aaa=next(solver(n,k))
    for i in aaa:
        print(i,end=' ')
except :
    print("Impossible")
Arty

Die einfachste Optimierung besteht natürlich darin, die check(...)Funktion mithilfe der sehr beliebten NumPy- Bibliothek zu verbessern. Installieren Sie sie nur NumPyeinmal, bevor Sie den nächsten Code über die python -m pip install numpyBefehlszeile verwenden.

Probieren Sie es online aus!

def check(n, k):
    import numpy as np
    return np.abs(np.diff(n)).min() >= k

Aber wenn die Lösung für Ihre Aufgabe wirklich sehr viel schneller sein sollte, habe ich die nächste neue Lösung implementiert, die für große Unternehmen sehr schnell sein sollte n(1 Million oder sogar mehr). Auch meine nächsten Lösungen verwenden keine zusätzliche Bibliothek wie numpy.

Die Hauptlösungsfunktion besteht solve2(n, k)darin, dass die Liste mit der richtigen Antwort zurückgegeben wird (die Richtigkeit wird von überprüft assert), oder dass die Antwort nicht vorhanden ist und zurückgegeben wird None. Anwendungsbeispiel Diese Lösungsfunktion ist test2()Funktion, nur zum Beispiel werden Antworten für alle kleinen nund kKombinationen erstellt. Wenn das Lösen von Funktionen eine Testfunktion zurückgibt None, wird diese Impossiblevor dem Drucken in einen String konvertiert .

Sie müssen Ihre eigene Variante test2()der Art und Weise implementieren , wie Sie sie für Ihren Fall benötigen, z. B. Eingaben nund kvom Benutzer, wie Sie es in Ihrem ursprünglichen Quellcode getan haben. Ich habe gerade ein test2()Beispiel für die Verwendung meines Codes erstellt.

Probieren Sie es online aus!

def solve2(n, k):
    if k <= 1 or n <= 1:
        p = list(range(n))
    elif n < 2 * k - 1:
        p = None
    elif 2 * k - 1 <= n <= 2 * k + 1:
        p = [None] * n
        cnt, klo = 0, -1
        if n == 2 * k + 1:
            p[0], p[1], p[2], cnt, klo = 0, k, 2 * k, 3, 0
        for i in range(k - 1, klo, -1):
            p[cnt] = i
            cnt += 1
            if cnt >= n:
                break
            p[cnt] = i + k
            cnt += 1
    else:
        if 2 * (k + 1) <= n <= 3 * (k + 1):
            kst = k + 1
        else:
            kst = k
        p = [None] * n
        cnt = 0
        for i in range(kst):
            for j in range(i, n, kst):
                p[cnt] = j
                cnt += 1

    if p is not None:
        assert len(p) == n, (len(p), n)
        p = [(e + 1) for e in p]
        assert all(abs(f - s) >= k for f, s in zip(p[:-1], p[1:]))

    return p

def test2():
    for n in range(1, 16):
        for k in range(1, n + 1):
            answer = solve2(n, k)
            answer = answer if answer is not None else 'Impossible'
            print(n, k, answer, end = '  |  ', flush = True)

test2()

Verwandte Artikel


Beschleunigen Sie die Datenrahmenschleife

Nils Gudat Ich führe zwei verschiedene, aber sehr ähnliche Schleifen über einen Pandas-Datenrahmen aus und frage mich, ob es eine Art Groupby-Operation gibt, die es mir ermöglicht, dies zu beschleunigen, indem ich eine Schleife vermeide. for x in df.var1:

Beschleunigen Sie die Berechnung

Yoko Ich habe diesen Code; es ist langsam und ich möchte, dass es schneller ist (dh in eine Zeile ohne die for-Schleife schreiben) n = 1000000 x = numeric(n) for (i in 1:n) x[i] = rpois(1, 3) + rpois(1, 5) Ronak shah rpois Die Funktion ist vektorisiert, daher

Beschleunigen Sie die Matrixberechnung

ASK22 Ich arbeite an einer linearen Modellvorhersagesteuerung und muss nur einige Matrizen für die Steuerung berechnen. Die Berechnung einer dieser Matrizen nimmt viel Zeit in Anspruch, und ich möchte fragen, ob es einen besseren Weg gibt, diese Berechnung zu

R Beschleunigen Sie die Zeichenfolgenzerlegung

Jon Ich bin relativ neu in R, daher ist mein Befehlsrepertoire begrenzt. Ich versuche, ein Skript zu schreiben, das eine Reihe von Markovschen Sequenzen, die in einer Textzeichenfolge enthalten und mit einem '>' - Zeichen getrennt sind, in eine Kontingenztabel

Beschleunigen Sie die A * -Implementierung in Python

auchanenburg Der A * -Algorithmus ist ein Pfadfindungsalgorithmus, der dem Dijkstra-Algorithmus ähnlich ist. Er besucht Knoten (verwendet eine Heuristik, um zu entscheiden, welcher Knoten als nächstes besucht werden soll) und vergleicht diesen Knoten mit den b

Beschleunigen Sie die geteilte Abfrage

navid sedigh Ich habe eine Zeichenfolge wie unten: R#4039,4040,3508,3512,1006,4506,4514,4011,4035,4513,4518,2009,4012,1998,4037;FF#3007,2018,1005,4515,4020,4027,4029,1503,4516,1999,2003,4026,2002,4007,2011,1004,3006,4519 Ich möchte meine Zeichenfolge t

Beschleunigen Sie die Zoomfunktion in ImageView

Filnik Ich habe es derzeit mit wirklich großen Bildern (7-10 MB) zu tun, deren Größe aus mehreren Gründen nicht geändert oder komprimiert werden kann. Die Idee ist nun, sie in einer benutzerdefinierten ImageView anzuzeigen, die es dem Benutzer ermöglicht, dopp

Python - Beschleunigen Sie die Pfadfindung

DrevanTonder Dies ist meine Wegfindungsfunktion: def get_distance(x1,y1,x2,y2): neighbors = [(-1,0),(1,0),(0,-1),(0,1)] old_nodes = [(square_pos[x1,y1],0)] new_nodes = [] for i in range(50): for node in old_nodes: if node[0]