WPC... geht weiter! -> wpc12



  • Ponto: Das klappt bei mir ziemlich gut 😞



  • Michael E. schrieb:

    Ponto: Das klappt bei mir ziemlich gut 😞

    Dann lass dir gesagt sein, dass man das meiste hier mathematisch Gesagte nicht für eine schnelle Lösung gebrauchen kann. Man kann auf einen linearen Algorithmus kommen, ohne das alles zu kennen. Ich glaube es kommen alle im Endeffekt auf äquivalente lineare Algorithmen, und nur die Güte der Implementierung wird über den Gewinner entscheiden. Schneller als linear kann man nicht werden, da alle Eingabebits gelesen werden müssen.

    Hattest du nicht am Anfang schon etwas schnelles?



  • Sehe ich genauso. Die mathematische Untersuchung macht einfach Spaß und hilft das Problem *vollständig* zu begreifen. Dazu gehört natürlich auch eine Klassifikation aller möglichen Situationen nach handlichen Kriterien, Eindeutigkeitsbeweise für Lösungen etc.

    Zum implementieren kann man nur einen kleinen Teil der Resultate brauchen. Macht aber nix. Geht ja um's Lernen.



  • und weg



  • Jester schrieb:

    Da ihr inwzischen schon fast alles beweisen konntet was ich auch hab verrate ich mal meinen Beweisansatz. Vielleicht kriegt ihr damit noch mehr raus. 🙂

    Wir haben ja bei d-f-g gesehen, daß es reicht Lampen ausschalten zu können.
    Also kann ich das ganze als Z/2Z-Vektorraum auffassen. Als Erzeugenden-System nehme ich die Bitvektoren die durch das anschalten einer einzelnen Lampe entstehen:

    110....0
    1110...0
    01110..0
       .
       .
       .
    0..01110
    0...0111
    0.000011
    

    sind das. (ist egal ob ihr's waagrecht oder senkrecht lest).
    Eine Lichterkette komplett auszuschalten ist sozusagen eine Lösung des inhom. LGS A*x=b mit dieser Matrix als A und der geg. Lichterkette als b.

    Jetzt sind viele Aussagen leicht: Bei 3*n oder 3*n+1 geht's immer haben wir. Dann sagt uns das: die Matrix muß wohl invertierbar sein => Eindeutigkeit der Lösung.

    Wenn man weiß, daß diese Matrix immer mindestens Rang n-1 hat, daß es maximal zwei Lösungen gibt. Außerdem kennen wir die Struktur der Lösung:

    inhom. Lösung = spezielle Lösung + c*homogene Lösung. Achtung c ist nur 0 oder 1, da wir uns Z/2Z befinden. Die homogene Lösung habt ihr ja auch schon gefunden...

    MfG Jester

    Super, damit hab ich nichts mehr in der Hinterhand, wie es Volkard gesagt hat. 😞



  • Ponto schrieb:

    Super, damit hab ich nichts mehr in der Hinterhand, wie es Volkard gesagt hat. 😞

    haben jetzt alle den spaß verloren und ich bin der einzigste, der einsendet? 😃



  • Ponto schrieb:

    Super, damit hab ich nichts mehr in der Hinterhand, wie es Volkard gesagt hat. 😞

    Ups, aber wie kann das denn sein? 😞

    Ich meine, ich habe überhaupt nichts neues geliefert. Keine neue Aussage, nur einen Beweis für die Eindeutigkeit der Lösung, die war aber schon vor einigen Seiten postuliert.

    Hilft's was wenn ich editiere?



  • Jester schrieb:

    Ponto schrieb:

    Super, damit hab ich nichts mehr in der Hinterhand, wie es Volkard gesagt hat. 😞

    Ups, aber wie kann das denn sein? 😞

    Ich meine, ich habe überhaupt nichts neues geliefert. Keine neue Aussage, nur einen Beweis für die Eindeutigkeit der Lösung, die war aber schon vor einigen Seiten postuliert.

    Hilft's was wenn ich editiere?

    Lass es so wie es ist.



  • volkard schrieb:

    Ponto schrieb:

    Super, damit hab ich nichts mehr in der Hinterhand, wie es Volkard gesagt hat. 😞

    haben jetzt alle den spaß verloren und ich bin der einzigste, der einsendet? 😃

    Nene, ich habe da noch ein paar Tricks 🙂



  • volkard schrieb:

    Ponto schrieb:

    Super, damit hab ich nichts mehr in der Hinterhand, wie es Volkard gesagt hat. 😞

    haben jetzt alle den spaß verloren und ich bin der einzigste, der einsendet? 😃

    einzige ! 🕶

    Ich darf doch ein Zitat von Dir als Sig mißbrauchen!?? 🤡 👍



  • Sgt. Nukem schrieb:

    Ich darf doch ein Zitat von Dir als Sig mißbrauchen!?? 🤡 👍

    aber klar doch.



  • volkard schrieb:

    haben jetzt alle den spaß verloren und ich bin der einzigste, der einsendet? 😃

    Hm, also ich werde sicher auch noch einsenden 😉

    Habe heute noch ein paar Millisekunden herausschlagen können, aber ich glaube, in der Optimierung des Algorithmus selbst kann ich mit meinem Wissen nicht mehr wirklich was erreichen. Das einzige, was jetzt nochmal einen echten Schub geben würde, wäre, wenn ich das Problem mit den zwei Wegen vorab entscheiden könnte... Ich glaube, wer das schafft (oder sogar schon geschafft hat), hat gute Karten auf den Sieg 😉



  • kwaart schrieb:

    Habe heute noch ein paar Millisekunden herausschlagen können, aber ich glaube, in der Optimierung des Algorithmus selbst kann ich mit meinem Wissen nicht mehr wirklich was erreichen. Das einzige, was jetzt nochmal einen echten Schub geben würde, wäre, wenn ich das Problem mit den zwei Wegen vorab entscheiden könnte... Ich glaube, wer das schafft (oder sogar schon geschafft hat), hat gute Karten auf den Sieg 😉

    Da ich bei der Bundeswehr bin und nur im Büro sitze, habe ich heute mal wieder sehr viel Zeit gehabt und meinen Algorithmus noch optimiert. Ich erreiche jetzt mit Dev-Cpp ca. 76 ms bei 1.000.002 Glühbirnen 🙂



  • TomasRiker schrieb:

    kwaart schrieb:

    Habe heute noch ein paar Millisekunden herausschlagen können, aber ich glaube, in der Optimierung des Algorithmus selbst kann ich mit meinem Wissen nicht mehr wirklich was erreichen. Das einzige, was jetzt nochmal einen echten Schub geben würde, wäre, wenn ich das Problem mit den zwei Wegen vorab entscheiden könnte... Ich glaube, wer das schafft (oder sogar schon geschafft hat), hat gute Karten auf den Sieg 😉

    Da ich bei der Bundeswehr bin und nur im Büro sitze, habe ich heute mal wieder sehr viel Zeit gehabt und meinen Algorithmus noch optimiert. Ich erreiche jetzt mit Dev-Cpp ca. 76 ms bei 1.000.002 Glühbirnen 🙂

    Warum gerade 1.000.002 Glübirnen und nicht 1.000.000?



  • Ponto schrieb:

    Warum gerade 1.000.002 Glübirnen und nicht 1.000.000?

    weils durch 3 teilbar ist.



  • borg schrieb:

    Ponto schrieb:

    Warum gerade 1.000.002 Glübirnen und nicht 1.000.000?

    weils durch 3 teilbar ist.

    Kann es sein, dass die Eingabe immer um zwei Elemente erweitert wird?



  • 1. Ich wollte mal fragen, wie weit man eigentlich gehen darf? std::vector<bool> ist nicht gerade der schnellste Container, wie hier schon festgestellt wurde. Wenn man jedoch auf seine interne Repräsentation zugreift, kann man einiges rausholen. Ich hab mal einen Test mit Intels 8.1 Compiler und der libstdc++ gemacht. Bei einer Eingabe von 50000000 Lampen konnte ich den Algorithmus von 1,81 auf 1,21 Sekunden beschleunigen. Deshalb meine Frage darf man sowas machen? Wenn ja, ist es natürlich notwendig zu wissen, welche STL Implementierung zum Auswerten verwendet wird. Aber eigentlich bin ich der Meinung, dass nur das im Standard festgelegte Interface verwendet werden darf.

    2. Ich hab mal einen größeren Rechner mit der Aufgabe beauftragt und festgestellt, dass der Rückgabewert das Problem ist. Ich hab mal 2^32 Lampen verwendet. Die beiden Eingabestrings machen dann 2^33 Bits oder 2^30 Bytes oder 1GiB aus. Die Instanz hatte die optimale Lösung mit ungefähr 3000000000 Positionen. Ein size_t hat auf dem Rechner 8 Byte. Das machte also 24000000000 Byte oder 22,35 GiB. Meine Implementierung benötigte dafür übrigens 107 Sekunden. Ich konnte noch einen Test mit einer Eingabe von 2^33 Lampen machen, was ungefähr 48 GiB verbraucht hat. Bei 2^34 Lampen hat dann der Rechner angefangen zu swappen, so dass es sinnlos war. Das Ergebnis ist eigentlich, dass das Ergebnis verhältnismäßig sehr viel Speicher frisst und man bei einer anderen Darstellung oder bei der alleinigen Ausgabe der Schalteranzahl viel größere Instanzen rechnen könnte.



  • 1. Die Lösung sollte standardkonform sein.

    2. Jo, das ist klar. Aber letztlich geht es ja nicht drum riesige Instanzen zu berechnen, sondern einfach schneller zu sein als alle anderen. Natürlich ist die Rückgabe nicht optimal. Ein std::vector<bool> für welche Schalter werden gekippt, welche nicht wäre auch möglich gewesen. Das hätte aber einige Dinge, die ihr so noch rausfinden durftet vorausgesetzt. Und nur die Zahl schien mir doch fast ein bißchen wenig.



  • Du hast nicht gerade die Testumgebung, die ich mir wünschen würde.

    Mein Algorithmus ist sehr platzsparend, braucht keinen zusätzlichen Speicher ausser für das Ergebnis und ein paar Variablen. Dafür hätte er gerne einen schnellen Prozessor und schnellen RAM.

    Auf meinem durchschnitts PC sieht das so aus:
    Pentium4 1.7GHz, 256MB DDR-SDRAM

    Mit -march=pentium4 -O3 braucht mein Algo nur noch 15ms (Durchschnitt) für Blöcke der Grösse 1 000 002.

    Ich weiss nicht genau, was du mit standardkonform meinst, aber mein Programm sollte auf jedem 32bit-x86 mit gcc >= 2.9 kompilieren und laufen.



  • Kannst Du uns sagen, in welcher Größenordnung die Ketten liegen, die Du zum Testen verwenden wirst? Am besten wäre es, wenn Du möglichst vielseitig testest, d.h. zufällige kleine/mittlere/lange Ketten der Länge 3n/3n+1/3n+2.
    Nicht dass wir hier alle auf Millionen von Lämpchen optimieren und am Ende testest Du es immer nur mit 20 oder 30...

    Mit standardkonform meint er wohl, dass es nicht erlaubt ist, an der "inneren Repräsentation" von vector<bool> herumzuspielen.

    Ich finde eigentlich Wettbewerbe, wo es um die Kürze des Programms geht, viel besser. Da kann man wenigstens sicher sein, dass das Ergebnis überall gleich ist. Hier hat derjenige einen großen Vorteil, der den gleichen Prozessor wie das Testsystem hat.
    Vielleicht sollte man die Einsendungen auch auf mehreren Systemen testen (Celeron, Pentium 3, Pentium 4, Duron, Athlon XP, Athlon 64) und die Mittelwerte nehmen?


Anmelden zum Antworten