Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Zwei Zahlen "gleich schnell" auf 0 bringen
Fabian W. - So 16.04.06 18:36
Titel: Zwei Zahlen "gleich schnell" auf 0 bringen
Folgendes problem:
Ich habe 2 zahlen zB 12 und 19. Nun möchte ich die Zahlen auf null bringen und zwar mit 2 besonderheiten:
a) es soll die selbe anzahl an runden gebraucht werden um sie auf 0 zu bekommen
b) sie sollen nicht linear kleiner werden sondern exponentiel:
_
_
__
___
____
_______
______________
_____________________________
Gibt es dafür irgendeinen Algorithmus?
mfg
EDIT: Das soll auch mit negativen zahlen möglich sein!
JayK - So 16.04.06 19:43
Ich weiß nicht recht.
Stell dir das ganze vllt mal als Koordinatensystem vor, in dem die x-Achse die Anzahl der Runden ist und nach der y-Achse deine Zahlen eingetragen werden.
Du hast Punkte gegeben, einmal (0;0), weil deine Zahlen ja auf die 0 kommen sollen, und jeweils einen Punkt (AnzahlSchritte;Zahl). AnzahlSchritte soll für beide Werte gleich sein (deine beiden Punkte liegen im KOS also übereinander). Du kannst also zwei Funktionen aufstellen, wobei immer einer deiner Punkte auf einem Graphen liegt. Dann hast du im KOS sozusagen zwei Graphen und immer da, wo der Graph bei einem Ganzzahligen x vorbeikommt, ist ein Zählschritt, mit dem du auf deinen Algo kommen musst.
Kann sein, dass dich das überhaupt nicht weiter bringt, aber ich wollte wenigstens versuchen zu helfen ;)
Frohe Ostern
Fabian W. - So 16.04.06 20:23
:idea: Die Idee ist sogar richtig gut, nur gibts da ein Problem: Ich kann keine Funktion für einen Graphen aufstellen bei dem ich nicht mal 3 vollstandige Punkte auf dem Graph hab. Mal schaun vlt fällt mir (oder auch jemand anderes) heute Nacht was ein. ;-)
mfg :D
BenBE - So 16.04.06 20:36
Naja, nimm einfach den LD (Logarithmus Dualis) der kleineren Zahl und setzte diesen gleich der Anzahl an Schritten zur Null-Reduktion ...
Nun kannst Du den Reduktionsfaktor für die zweite Zahl über AnzahlScriptte. Wurzel von Große zahl berechnen ...
Wenn also
x1 = 8, x2 = 64
dann ist ld x1 = 3 --> 3. Wurzel 64 --> 4
Danach einfach x1 durch 2 und x2 durch 4 teilen ;-)
Aristoteles - Mo 17.04.06 13:46
Titel: Re: Zwei Zahlen "gleich schnell" auf 0 bringen
Fabian W. hat folgendes geschrieben: |
b) sie sollen nicht linear kleiner werden sondern exponentiel:
_
_
__
___
____
_______
______________
_____________________________
|
Wie ist das genau gemeint?
Wenn die beiden Zahlen mit einem expotentiellen Algorithmus gegen 0 streben, erreicht keine der Zahlen die 0. Wie willst du dann die "Anzahl der Runden" definieren?
Expotentiell gegen 0 strebt z.B. bei einer Zahl b die folgende Funktion: b*e^(-x) für wachsendes x.
für b=12 und b=19 geht die Funktion gleichermaßen für x-->unendlich gegen 0.
zemy - Mo 17.04.06 13:59
Man kann ja definieren, das wenn der Wert kleiner 0,5 ist, er als 0 angesehen wird oder man einfach fest 30 Schritte oder so nimmt... Das gleichmäßig kann man ja dadurch erreichen, das man in einem Refferenzintervall [0,1] das absinken realisiert und die entsprechenden Werte dann multipliziert.... Ja, müsste klappen
MfG
Fabian W. - Mo 17.04.06 14:38
Also, ich habe BenBEs Methode ausprobiert, leider läst diese keine Bestimmung der "Rundenanzahl" zu (zumindest nicht in dem Raum, den ich brauche.
@Aristoteles:
-> Wie das gemeint ist:
x1: 12
x2: 19
geg runden: 5
x1 -> 12 - 8 - 5 - 3 - 1 - 0*
x2 -> 19 - 13 - 9 - 5 - 2 - 0*
*näherungsweise Null
In dieser Form also.
Das ganze soll wie oben schon erwähnt auch mit negativen zahlen funktionieren (die dann in dieser Form auch gegen Null gehen - also größer werden) und die Anzahl dre Runden sollte zu einem großen Maß frei wählbar sein, also das ganze darf nicht wirklich nur maximal 5 Runden gehen sondern eher >15.
Ich hoffe ich habe das Problem verständlich erleutert ;-)
@zemy:
Könntest du das nochmal näher erleutern?
Zitat: |
Das gleichmäßig kann man ja dadurch erreichen,... |
Es soll ja eben nicht gleichmäßig sondern wie oben beschrieben ablaufen ;-)
Beiri22 - Mo 17.04.06 15:04
eine exponentialfunction y:=a*e^(bx) oder so kann nie null werden, sofern a<>0
gr
Fabian W. - Mo 17.04.06 15:32
Beiri22 hat folgendes geschrieben: |
eine exponentialfunction y:=a*e^(bx) oder so kann nie null werden, sofern a<>0
gr |
Gugst du hier:
Zitat: |
geg runden: 5
x1 -> 12 - 8 - 5 - 3 - 1 - 0*
x2 -> 19 - 13 - 9 - 5 - 2 - 0*
*näherungsweise Null |
oder hier
Zitat: |
Man kann ja definieren, das wenn der Wert kleiner 0,5 ist, er als 0 angesehen wird |
oder hier
Zitat: |
Wenn die beiden Zahlen mit einem expotentiellen Algorithmus gegen 0 streben, erreicht keine der Zahlen die 0 |
;-)
mfg
Beiri22 - Mo 17.04.06 17:26
ok, geb ich dir recht, den part habe ich nicht beachtet.
Jetstream - Mo 17.04.06 17:41
Du brauchst eine Funktion, die positive und negative Zahlen exponentiell schrumpfen lässt, bis sie Null sind, und das in einer endlichen Anzahl von Schritten.
Kennste die Funktion Sinus Hyperbolicus ?
sieht dann so aus:
(copy & paste von wikipedia)
Du könntest jetzt, wenn du zB die 10 und die 27 schrumpfen lassen willst,
erstmal die Umkehrfunktion Areasinus Hyperbolicus auf beide Werte anwenden.
Areasinus Hyperbolicus:
Da bekommste dann für das obige Päarchen 2,998 und 3,989.
Du kannst 10 und 27 jetzt also ausdrücken als sinh(2,998) und sinh(3,989).
Jetzt einfach in 10 Schritten jeweils ein Zehntel des ursprünglichen Wertes abziehen:
sinh(2,998) -> sinh(2,6982) -> sinh(2,3984) -> ... -> sinh(0)
sinh(3,989) -> sinh(3,5901) -> sinh(3,1912) -> ... -> sinh(0)
Am Ende hast du zweimal sinh(0), das ist Null.
Ist die Zahl negativ, musst du sie entsprechend ansteigen lassen bis Null.
Gruß Jetstream
zemy - Di 18.04.06 14:58
Habs mir noch mal durch den Kopf gehen lassen... Wieso so kompliziert??? Es reicht doch, wenn die beiden Zahlen immer mit nem konstanten Faktor kleiner 1 multipliziert werden. Dieser kann dann anhand des größeren Wertes und der gewünschten Schrittzahl ermittelt werden.
als mathematische Formel kommt dann:
Quelltext
1:
| Zahl(n) = Zahl(0) * Faktor^n |
Also konkrtet mal im (Pseudo-)Code (Zielwert 0.5):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| if (Zahl1>Zahl2) myval = Zahl1; else myval:=zahl2; Faktor:=exp( Ln (0.5 / myval) / Schrittzahl); for i:=0 to Schrittzahl do begin Zahl1:=Zahl1*Faktor; Zahl2:=Zahl2*Faktor; end; |
Für negative Werte muss man natürlich den Betrag nehmen bei berrechnung des Faktors. Wenn du Interger brauchst, kannste auch typecasten. Das mit exp(ln(...)/n) ist einfach nur die n-te Wurzel aus 0.5/myval ;)
Hoffe es funzt.
MfG
Jetstream - Di 18.04.06 17:29
Wenn du die 2 Funktionen sinh und arcsinh hast isses ganz einfach. (die gibts in der unit math)
Was is gesucht ? ne Funktion die 3 Werte bekommt (Ursprüngliche Zahl, Anzahl Schritte, momentaner Schritt) und eine Zahl zurückgibt ? Nehmen wir das mal an.
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| uses math; function countdown (zahl:real;anzahlschritte,schritt:integer):real; begin result:=sinh( arcsinh(zahl) * (anzahlschritte-schritt) / anzahlschritte ); end; |
Wenn du für "schritt" ne Null eingibst, isses die Ursprüngliche Zahl: sinh(arcsinh(zahl*1)) = zahl
Bei schritt = anzahlschritte haste dagegen sinh(arcsinh(zahl*0) = sinh(0) = 0
So, jetzt noch der Aufruf (pseudo-code):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| zahl1 := 10; zahl2 := 27; anzahl_schritte := 395; for a:=0 to anzahl_schritte do begin ausgabe1 := countdown(zahl1,anzahl_schritte,a); ausgabe2 := countdown(zahl2,anzahl_schritte,a); end; |
Funzt mit nicht-Integer-Zahlen
Funzt mit negativen Zahlen
Funzt sogar mit mehr als 2 Zahlen
Böse kompliziert ... muss schon sagen =)
Fabian W. - Di 18.04.06 18:48
So, tschuldignung dass ich mich erst jetzt melde, hatte viel um die Ohren^^.
@Jetstream:
Super danke! Funzt einwandfrei!
@Alle anderen:
Auch großes thx an auch für die Mühe, ich nehme Jetstream version (die is ja schon mundgerecht vorgekaut) ;-) :mrgreen:
mfg und nochmal THX für die Hilfe :-D
Jetstream - Di 18.04.06 23:53
Fabian W. hat folgendes geschrieben: |
(die is ja schon mundgerecht vorgekaut) ;-) :mrgreen:
|
Wollte dich erst selber drauf kommen lassen, aber dachte dann,
dass du vielleicht meine erste Antwort zu abstrakt findest ;-)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!