Archiv verlassen und diese Seite im Standarddesign anzeigen : Suche Funktion f(x)
Mars81
2021-04-10, 14:38:38
Hallo Leute,
ich bin auf der Suche nach einer Funktion, welche in etwa folgende Werte ergibt:
y=1000, x=1,4
y=5000, x=1,3
y=10000, x=1,2
y=100000, x=1,1
Für Werte y<1000 kann es von mir aus gegen unendlich gehen (ist eigentlich egal) und für große y-Werte gegen 1.
Ich habe schon mit verschiedenen Gleichungen und Parametern (1/x, log(x), etc.) herumprobiert, aber ich habe keine Ahnung, wie ich das Problem systematisch angehen soll.
Vielen Dank für eure Hilfe!
Monger
2021-04-10, 16:01:28
Ist zum Glück relativ einfach. TDD bietet dafür folgende Lösung:
Function foo(x)
If (x = 1.4)
Return 1000
If (x = 1.3)
Return 5000
If (x = 1.2)
Return 10000
Das sind über 50% der Use Cases, das reicht den meisten Projektleitern.
Ist zum Glück relativ einfach. TDD bietet dafür folgende Lösung:
Function foo(x)
If (x = 1.4)
Return 1000
If (x = 1.3)
Return 5000
If (x = 1.2)
Return 10000
Das sind über 50% der Use Cases, das reicht den meisten Projektleitern.
nice try ;)
Wie es systematisch geht, weiß ich auch nicht, aber wie wäre es mit folgender Funktion:
100
Kubikwurzel von ----- + 1 = x
y
BAGZZlash
2021-04-10, 16:54:12
Letztlich kommt das darauf an, wie Du den Tradeoff zwischen Genauigkeit und Komplexität haben willst. Eine einfache, lineare Funktion wäre
f(x) = 406500 - 302000x.
Das ist aber ziemlich ungenau, siehe rote Kurve im Schaubild unten. Wenn's etwas komplexer sein darf, ist
f(x) = -362105 + (484950 / x)
geringfügig genauer, siehe blaue Kurve. Wenn's sehr genau sein muss, wird's auch komplex: Dann passt
f(x) = 56759.685730003 + (-39828.6342688643 * x) + (11177563.1337713 * (x ^ -50.9406360108852)) + (2422711.15412725 * (x ^ -200.014908472279)) + (3018327.28964961 * (x ^ -185.0984157991))
ziemlich gut, siehe schwarze Kurve. Die Zahlenwerte darfst Du mit geringfügigem Genauigkeitsverlust runden, etwa zu
f(x) = 56759.7 + (-39828.6 * x) + (11177563.1 * (x ^ -50.9)) + (2422711.2 * (x ^ -200)) + (3018327.3 * (x ^ -185.1)).
74936
Hier mein R-Code, anbei außerdem noch eine Excel-Version, die das Ganze mittels Solver annähert.
x <- c(1.4, 1.3, 1.2, 1.1)
y <- c(1000, 5000, 10000, 100000)
KQ <- lm(y ~ x)
NKQ1 <- nls(y ~ a + (b / x), start = list(a = 0, b = 1), algorithm = "port")
NKQ2 <- nls(y ~ a + (b * x) + (c * (x ^ d)) + (e * (x ^ f)) + (g * (x ^ h)), start = list(a = 0, b = 1, c = 1, d = 1, e = 1, f = 1, g = 1, h = 1), algorithm = "port")
plot (x, y)
abline(KQ, col = "red", lwd = 2)
xz <- seq(from = 1, to = 1.5, length.out = 1000)
#zz <- coef(NKQ1)[1] + (coef(NKQ1)[2] / xz)
zz <- -362105 + (484950 / xz)
lines(xz, zz, col = "blue", lwd = 2)
xz <- seq(from = 1, to = 1.5, length.out = 1000)
#zz <- coef(NKQ2)[1] + (coef(NKQ2)[2] * x) + (coef(NKQ2)[3] * (x ^ coef(NKQ2)[4])) + (coef(NKQ2)[5] * (x ^ coef(NKQ2)[6])) + (coef(NKQ2)[7] * (x ^ coef(NKQ2)[8])
zz <- 56759.685730003 + (-39828.6342688643 * xz) + (11177563.1337713 * (xz ^ -50.9406360108852)) + (2422711.15412725 * (xz ^ -200.014908472279)) + (3018327.28964961 * (xz ^ -185.0984157991))
lines(xz, zz, col = "black", lwd = 2)
Mars81
2021-04-10, 17:29:34
Krass! :eek:
Ähm, ich meine natürlich Vielen Dank :biggrin:
Von deinem Code verstehe ich aber nur Bahnhof. Hast du das jetzt auf die Schnelle aus dem Ärmel geschüttelt, oder brauchst du das öfter?
Edit:
Ah, nur bis NKQ2 ist der eigentliche Code. Danach kommt nur die grafische Darstellung, richtig?
Du hast also eine Gleichung a + (b * x) + (c * (x ^ d)) + (e * (x ^ f)) + (g * (x ^ h)) genommen und dann austesten lassen, welche Werte für die Variablen am besten passen?
BAGZZlash
2021-04-10, 17:39:04
Richtig. Ja, ich arbeite empirisch.
Mars81
2021-04-10, 18:00:47
Jetzt fehlt mir nur noch eine esoterische Lösung ;D
BAGZZlash
2021-04-10, 18:20:51
Was soll das sein?
Mortalvision
2021-04-10, 18:42:59
Er meint einen theoretischen Lösungsansatz :freak:
Mars81
2021-04-10, 18:52:46
Nein, das passt schon. Die empirische Lösung ist für meine Zwecke ausreichend genau.
Obwohl mich schon interessieren würde, ob es dafür noch eine elegantere Funktion gibt.
BAGZZlash
2021-04-10, 20:09:54
Wenn's etwas sparsamer parametrisiert sein soll, kann man im Wesentlichen die letzten beiden Terme weglassen, die machen nicht mehr viel Unterschied. Dann also so:
f(x) = 56758 - (39829 * x) + (11177563 * (x ^ -51))
Ansonsten ist die funktionale Form von Zafi (https://www.forum-3dcenter.org/vbulletin/showpost.php?p=12647951&postcount=4) gar nicht schlecht. Aufgelöst nach y ergibt das ja
f(x) = 100 / (x - 1) ^ 3
Mit dem Optimizer etwas nachgeschärft bekommt man
f(x) = 101.6457 / (x - 1) ^ 2.9856
Das ist zwar nicht supergenau, aber reicht vielleicht. Als Graph siehe hier:
74939
jeder Blinde sieht, dass das nen Powerlaw ist
BAGZZlash
2021-04-11, 14:45:43
Und nun? Wie sieht Dein konstruktiver Beitrag aus?
Silent3sniper
2021-04-11, 15:24:36
Würde probieren
Fit-function f(x) = a(x-b)^c+d
Distroia
2021-04-12, 19:59:46
Wenn man schon klugscheißt, sollte man das wenigstens auf konstruktive Weise tun und dabei schon gar kein Deppen-"nen" verwenden. :freak:
alle sinnvoll vorgestellten Funktionen sind Powerlaws ;)
Timbaloo
2021-04-13, 11:03:57
https://en.wikipedia.org/wiki/Symbolic_regression
Mars81
2021-04-13, 12:18:25
Ich denke
f(x) = 102 / (x - 1) ^ 2.982
passt für meine Zwecke ganz gut und ist ausreichend genau.
Vielen Dank noch mal an alle!
vBulletin®, Copyright ©2000-2024, Jelsoft Enterprises Ltd.