Wer schuldet wem Geld Optimierung
Sagen, Sie haben n Personen, für jeden, der Schulden sich gegenseitig Geld. Im Allgemeinen sollte es möglich sein, reduzieren Sie die Menge der Transaktionen, die stattfinden müssen. d.h. wenn X schuldet Y £4 und Y schuldet X £8, dann Y muss nur zahlen X £4 (1 Transaktion statt 2).
Diese wird härter, wenn X schuldet Y, aber Y schuldet Z, verdankt X als gut. Ich kann sehen, dass Sie können leicht berechnen einen bestimmten Zyklus. Es hilft mir, wenn ich denke, dass es zu einer vollständig vernetzten Graphen mit den Kanten wird die Anzahl jede person schuldet.
Problem scheint zu sein, die NP-vollständigen, aber auf welche Art von Optimierungsalgorithmus konnte ich machen, dennoch, reduzieren sich die insgesamt Anzahl der Transaktionen? Muss nicht sein, dass eine effiziente, durch N ist Recht klein für mich.
Edit:
Dem Zweck, dieses problem würde in der Lage sein, in der Buchhaltung etwas sagen können zu jeder person, die beim log-in "können Sie entfernen M Höhe von Transaktionen, indem Sie einfach die Zahlung jemand den Betrag X, und jemand anderes Y Betrag". Damit die bank die Lösung (obwohl optimal, wenn alle zahlen zugleich), kann nicht wirklich sein verwendet hier.
- Es erscheint Expensure dieses problem gelöst haben. Finden Sie Ihre faq-Eintrag Rundschreiben Schulden Auflösung™.
- Wenn es keine Transaktionskosten, gibt es eine einfache Lösung mit einer bank. Wenn es gibt Transaktionskosten, es ist viel schwieriger.
- Wir können Sie so modifizieren, das problem zu beseitigen, die die bank ausstellen. Fügen wir die Einschränkung, "kann eine person beteiligt sein, höchstens (N-1) - Transaktionen". Also keine bank, keinen Kandidaten zu nominieren.
- By the way, was ist die Kernaufgabe von dieser Optimierung? Ist es den Prozess schneller oder etwas, das nicht in die Frage?
- Noch eine Frage: ist standardmäßig möglich ?
- Ich sah etwas erweitert, aber dann festgestellt, dass Schulden die übertragung ist in der Praxis eine schlechte Idee, wenn Sie nicht 100% Vertrauen, alle Ihre Schulden zu bezahlen. Wenn einige Forderungen vielleicht schlecht sein, wenn Sie nicht wollen, übertragen Sie decken einige sonst gute Schulden. Im Effekt-Schulden haben einen Wert Verschieden von Ihre Geld-label. Dies könnte ein Fall, dass ignoriert werden können, hier aber ist es ein interessanter realen Welt berücksichtigt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Menschen erforderlich, um klar Ihre Schulden durch die Zahlung jemand, dass Sie tatsächlich Geld Schulden persönlich? Wenn nicht, das folgende zu funktionieren scheint verdächtig leicht:
Für jede person, arbeiten aus dem Netto-Betrag, den Sie zahlen sollte oder erhalten sollte.
Jemandem Geld schuldet, net jemanden bezahlen, der sollte Geld bekommen net min(Betrag, Betrag erhalten). Nach diesem, mindestens einen der beiden Teilnehmer schuldet nichts und sollte auch nichts bekommen, und können so entfernt werden das problem.
Vorausgesetzt, ich habe etwas verpasst, was sind die Einschränkungen, die hier gelten (oder grobe Fehler gemacht)?
Ich erstellt habe, eine Android-app die dieses problem löst. Sie können die input-Kosten während der Reise, er empfiehlt sogar, das Sie "wer soll das bezahlen weiter". Am Ende wird berechnet ", der senden sollte, wie viel an wen". Mein Algorithmus berechnet minimale erforderliche Anzahl von Transaktionen, und Sie können setup "Transaktion " Toleranz", um Transaktionen noch weiter (Sie kümmern sich nicht um die 1 $ - Transaktionen) Probieren Sie es aus, es heißt zu Begleichen:
https://market.android.com/details?id=cz.destil.settleup
Beschreibung meines Algorithmus:
Habe ich grundlegende Algorithmus löst das problem mit n-1 Geschäfte, aber es ist nicht optimal. Es funktioniert wie folgt: Aus-Zahlungen berechne ich die balance für jedes Mitglied. Gleichgewicht ist, was er bezahlt, minus dem, was er zahlen soll. Ich Sortiere die Mitglieder nach balance immer. Dann habe ich immer die ärmsten und die reichsten und die Transaktion durchgeführt wird. Mindestens einer von Ihnen landet mit null-Saldo und der ist ausgeschlossen von den weiteren Berechnungen. Mit dieser, die Anzahl der Transaktionen kann nicht schlimmer sein als n-1. Es minimiert auch die Menge des Geldes in Transaktionen. Aber es ist nicht optimal, weil es nicht erkennen Untergruppen, die können abrechnen intern.
Finden Untergruppen, die können abrechnen intern ist schwer. Ich es lösen durch die Erzeugung aller Kombinationen von Elementen und die Prüfung, ob die Summe der Salden in der Untergruppe gleich null. Ich beginne mit der 2-Paare, dann 3-pair-Mädchen ... (n-1)Paare. Implementierungen der Kombination Generatoren sind verfügbar. Wenn ich eine Untergruppe, berechne ich Transaktionen in der Untergruppe mit basic-Algorithmus wie oben beschrieben. Für jede Gefundene Untergruppe, eine Transaktion verschont.
Die Lösung optimal ist, aber die Komplexität steigt auf O(n!). Dies sieht schrecklich aus, aber der trick ist, es gibt nur kleine Anzahl von Mitgliedern in der Realität. Ich habe es getestet auf Nexus One (1 Ghz procesor) und die Ergebnisse sind: bis zu 10 Mitglieder: <100 ms, 15 Mitglieder: 1 s, 18 Mitglieder: 8 s, 20 Mitglieder: 55 s. Also bis 18 Mitgliedern, die Ausführungszeit ist in Ordnung. Workaround für >15 Mitglieder kann nur der grundlegende Algorithmus (es ist schnell und korrekt, aber nicht optimal).
Source code:
Source-code verfügbar ist, in einem Bericht über den Algorithmus geschrieben in Tschechisch. Source code ist am Ende und es ist in Englisch:
http://settleup.destil.cz/report.pdf
Nominieren einer person willkürlich der Bankier zu sein.
Jede andere person überträgt die Summe aller ausgehenden Transaktionen, abzüglich der eingehenden Transaktionen (also entweder Einzahlungen oder Abhebungen) für die person.
Gibt es maximal (n-1) - Transaktionen, die ist ziemlich klein. Es ist schnell. Es ist einfach.
Gegeben, dass alle, die transfers, die Geld haben, werden an einer Transaktion beteiligten sowieso*, es ist begrenzt zu werden, im schlimmsten Fall zweimal der optimale Fall.**
* Ausnahme ist der Bankier sich. Eine schnelle Optimierung ist es, dass die Nominierten Bankier ist nicht derjenige sein, der hält eine Neutrale position.
** Erklären meine Obergrenze Logik weiter:
Angenommen, der optimale Fall ist gibt $1 auf B, und C gibt $1 auf D, und E ist neutral = zwei Transaktionen.
Dann mit dieser Logik, wenn E die Nominierten Bankier, Einen gibt $1 auf E, - E gibt ein $1 zu B, C gibt $1 auf E und E gibt, $1 D = vier Transaktionen.
Mit der Optimierung, so dass Sie sicher, dass Sie nicht wählen, eine Neutrale person für den Bankier, wählen Sie Eine statt.
A $1-B, C gibt $1 bis A. A $1 D = drei Transaktionen.
Nur daran denke, würde ich anfangen zu suchen bei jedem Zyklus im gerichteten Graphen und die Verringerung der jede Kante in den Zyklus durch den Wert der minimalen Kante im Zyklus, dann entfernen Sie die minimalen Rand insgesamt. Spülen und wiederholen.
Hier ist die Python-Lösung, die ich verwendet; es ist die gleiche Idee, als Gunner ' s post, mit ein paar änderungen:
Arbeitet ein Genuss.
Können Sie es testen mit also:
Ich glaube, Sie brauchen, um zu bauen eine andere Datenstruktur ( Baum, jeder Zeit eine person ist der root-node), das überprüfen wird für jede person, wie viele "Transaktion" kann Sie "töten", als die beste zu wählen, um den Zyklus, und es wieder aufbauen.es ist nicht o(N), ich Denke, es ist N^2 aber, und es wird nicht geben Ihnen das beste Ergebnis. es ist nur eine Strategie.
Diesem problem begegnet werden kann mit dem Warshall-Algorithmus.
Nachdem der Algorithmus beendet ist, wird die Gesamtzahl der Transaktionen, die erforderlich wäre, die Anzahl der positiven Einträge in der schuldet Tabelle.
Habe ich noch nicht verifiziert, ob der Algorithmus funktioniert, basiert auf der Natur des Problems kann es funktionieren. Lösung ist O(N^3).
Ich denke, dass müssen Sie entfernen alle cicles Verringerung der Kanten, der durch minimale Rand-Wert und removingedges mit dem Wert 0. Nachdem er Sie erhalten graph ohne cicles. Ich denke, dass Sie finden, müssen die Eckpunkte, die haben keine Zeiger, um Sie (Mann wich schuldet nur übrig das Geld). Dieser Mann muss Geld bezahlen, beacouse es keinen gibt, der das Geld zu zahlen für Sie. Also mein Punkt ist, dass Sie finden, irgendwie, wer Sie bezahlen muss.
Habe ich eine Lösung für das problem in matlab geschrieben. Es basiert auf einer matrix, wer schuldet wem was. Die Zahl in der (i,j) bedeutet, dass person j schuldet person, mit der ich die Anzahl. E. g.
B schuldet A 2
und A schuldet B 1
natürlich in diesem Fall ist es trivial, dass B nur Ein 1 geben
Diese wird komplexer, mit mehr Einträgen. Jedoch mit dem Algorithmus, den ich schrieb, ich kann garantieren, dass nicht mehr als N-1 Transaktionen erfolgt, wobei N die Anzahl der persones 2 in diesem Fall.
Hier ist der code, den ich schrieb.
Ende