JavaScript Funktion mit 5 Parametern analysieren und threshold value bestimmen

N.N.

Banned
Registriert
Juli 2025
Beiträge
72
Nabend,

zufällig habe ich hier eine Funktion, für die ich einen Threshold bestimmen möchte, sodass nur noch 10 % aller Werte über diesem liegen:

Javascript:
function f(a, b, c, m, n) {
  return (a * 10 + b * 30 + c * 20) / (m + n * 20);
}

let threshold = 2.5;
let c1 = 0;
let c2 = 0;

function typicallyVals(m) {
  let a = parseInt(m / 10);
  if (a < 1) {
    a = 1;
  }
  let b = parseInt(Math.random() * 4);
  let c = a - 1;
  let n1 = 1.0;
  let n2 = 2.5;
  let f1 = f(a, b, c, m, n1);
  let f2 = f(a, b, c, m, n2);
  if (f1 >= threshold) {
    c1++;
    console.log("x", a, b, c, m, n1, f1.toFixed(2));
  } else {
    c2++;
    console.log("o", a, b, c, m, n1, f1.toFixed(2));
  }
  if (f2 >= threshold) {
    c1++;
    console.log("x", a, b, c, m, n2, f2.toFixed(2));
  } else {
    c2++;
    console.log("o", a, b, c, m, n2, f2.toFixed(2));
  }
}

for (let m = 0; m <= 60; m++) typicallyVals(m);
console.log(((c1 / (c1 + c2)) * 100).toFixed(2));

Das Problem ist jedoch, dass ich nur "typische Werte" für diese Funktion kenne, die zudem auch vom Zufall abhängig sind. Wie geht man da heran?

2,5 ist ins Blaue geraten, da mehr als 10 % (20-30) über diesem Wert liegen.
 
gerne mal ausprobieren: https://claude.ai/public/artifacts/da6bfc6e-0419-47f7-9a58-05a52c6ed584

Ich bin jetzt nicht super tief ins Detail gegangen, könnte aber in die richtige Richtung gehen.

Falls Quatsch dann sorry :)

Code:

HTML:
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threshold Calculator</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
        }
        .container {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            padding: 30px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
        }
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
        }
        .controls {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }
        .control-group {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 10px;
            border: 2px solid #e9ecef;
        }
        label {
            display: block;
            font-weight: bold;
            margin-bottom: 5px;
            color: #495057;
        }
        input, button {
            width: 100%;
            padding: 10px;
            border: 1px solid #ced4da;
            border-radius: 5px;
            font-size: 14px;
        }
        button {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            cursor: pointer;
            font-weight: bold;
            transition: transform 0.2s;
        }
        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
        }
        .results {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-top: 20px;
        }
        .result-box {
            background: #f8f9fa;
            padding: 20px;
            border-radius: 10px;
            border-left: 5px solid #667eea;
        }
        .result-box h3 {
            margin-top: 0;
            color: #333;
        }
        .threshold-result {
            font-size: 24px;
            font-weight: bold;
            color: #667eea;
            text-align: center;
            margin: 10px 0;
        }
        .stats {
            font-family: monospace;
            background: #fff;
            padding: 15px;
            border-radius: 5px;
            margin-top: 10px;
        }
        .histogram {
            margin-top: 20px;
        }
        .bar {
            display: flex;
            align-items: center;
            margin: 2px 0;
        }
        .bar-label {
            width: 60px;
            font-size: 12px;
            text-align: right;
            margin-right: 10px;
        }
        .bar-fill {
            height: 15px;
            background: linear-gradient(90deg, #667eea, #764ba2);
            border-radius: 3px;
            transition: width 0.3s ease;
        }
        .bar-count {
            margin-left: 10px;
            font-size: 12px;
            color: #666;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎯 Threshold Calculator für 90%-Quantil</h1>
        
        <div class="controls">
            <div class="control-group">
                <label for="samples">Anzahl Samples:</label>
                <input type="number" id="samples" value="10000" min="1000">
            </div>
            <div class="control-group">
                <label for="maxM">Maximaler m-Wert:</label>
                <input type="number" id="maxM" value="60" min="10">
            </div>
            <div class="control-group">
                <label for="targetPercentile">Ziel-Percentil (%):</label>
                <input type="number" id="targetPercentile" value="90" min="50" max="99" step="0.1">
            </div>
            <div class="control-group">
                <button onclick="calculateThreshold()">🔄 Threshold berechnen</button>
            </div>
        </div>

        <div class="results">
            <div class="result-box">
                <h3>📊 Ergebnis</h3>
                <div id="thresholdResult" class="threshold-result">-</div>
                <div id="stats" class="stats"></div>
            </div>
            <div class="result-box">
                <h3>📈 Verteilung</h3>
                <div id="histogram" class="histogram"></div>
            </div>
        </div>
    </div>

    <script>
        // Deine ursprüngliche Funktion
        function f(a, b, c, m, n) {
            return (a * 10 + b * 30 + c * 20) / (m + n * 20);
        }

        // Generiere einen einzelnen Wert basierend auf deiner Logik
        function generateValue(m) {
            let a = Math.max(1, Math.floor(m / 10));
            let b = Math.floor(Math.random() * 4);
            let c = a - 1;
            
            // Beide n-Werte testen
            let values = [];
            values.push(f(a, b, c, m, 1.0));
            values.push(f(a, b, c, m, 2.5));
            
            return values;
        }

        function calculateThreshold() {
            const samples = parseInt(document.getElementById('samples').value);
            const maxM = parseInt(document.getElementById('maxM').value);
            const targetPercentile = parseFloat(document.getElementById('targetPercentile').value);
            
            let allValues = [];
            
            // Sammle viele Samples
            for (let i = 0; i < samples; i++) {
                const m = Math.floor(Math.random() * (maxM + 1));
                const values = generateValue(m);
                allValues.push(...values);
            }
            
            // Sortiere die Werte
            allValues.sort((a, b) => a - b);
            
            // Berechne das gewünschte Percentil
            const index = Math.floor((targetPercentile / 100) * allValues.length);
            const threshold = allValues[index];
            
            // Teste den Threshold
            let above = 0;
            let total = 0;
            
            for (let m = 0; m <= maxM; m++) {
                for (let test = 0; test < 100; test++) {
                    const values = generateValue(m);
                    values.forEach(val => {
                        total++;
                        if (val >= threshold) above++;
                    });
                }
            }
            
            const actualPercentage = (above / total) * 100;
            
            // Zeige Ergebnisse
            document.getElementById('thresholdResult').textContent = threshold.toFixed(3);
            
            const stats = `
Threshold: ${threshold.toFixed(3)}
Tatsächlich über Threshold: ${actualPercentage.toFixed(1)}%
Ziel war: ${targetPercentile}%
Samples verwendet: ${allValues.length.toLocaleString()}
Min Wert: ${Math.min(...allValues).toFixed(3)}
Max Wert: ${Math.max(...allValues).toFixed(3)}
Median: ${allValues[Math.floor(allValues.length/2)].toFixed(3)}
            `;
            document.getElementById('stats').textContent = stats;
            
            // Erstelle Histogram
            createHistogram(allValues, threshold);
        }
        
        function createHistogram(values, threshold) {
            const bins = 20;
            const min = Math.min(...values);
            const max = Math.max(...values);
            const binSize = (max - min) / bins;
            
            const histogram = new Array(bins).fill(0);
            
            values.forEach(val => {
                const bin = Math.min(bins - 1, Math.floor((val - min) / binSize));
                histogram[bin]++;
            });
            
            const maxCount = Math.max(...histogram);
            const histogramDiv = document.getElementById('histogram');
            histogramDiv.innerHTML = '';
            
            histogram.forEach((count, i) => {
                const binStart = min + i * binSize;
                const binEnd = min + (i + 1) * binSize;
                const isThresholdBin = threshold >= binStart && threshold < binEnd;
                
                const bar = document.createElement('div');
                bar.className = 'bar';
                
                const width = (count / maxCount) * 100;
                
                bar.innerHTML = `
                    <div class="bar-label">${binStart.toFixed(1)}</div>
                    <div class="bar-fill" style="width: ${width}%; ${isThresholdBin ? 'background: #ff6b6b;' : ''}"></div>
                    <div class="bar-count">${count}</div>
                `;
                
                histogramDiv.appendChild(bar);
            });
        }

        // Initialer Durchlauf
        calculateThreshold();
    </script>
</body>
</html>
 
blablub1212 schrieb:
const stats = ` Threshold: ${threshold.toFixed(3)} Tatsächlich über Threshold: ${actualPercentage.toFixed(1)}% Ziel war: ${targetPercentile}% Samples verwendet: ${allValues.length.toLocaleString()}
Uff, ja man merkt, dass das eine KI war...

Ein JsFiddle wäre besser.
 
Ehm, ich kann dir nicht ganz folgen, du hast eine Funktion f mit 5 Variablen und kennst den Wertebereich der einzelnen Variablen nicht. Soweit richtig?

Reduziere zum Nachdenken mal dein Problem auf eine variable und nicht auf 5. Dann hast du im x/y Plot eine Gerade, du suchst dann eine andere Gerade die deine Gerade entsprechend schneidet, so dass deine Anforderung erfüllt ist, jetzt erweiter das auf zwei variablen und du hast eine Ebene im 3D Raum und du suchst wieder eine Ebene usw.

Du hast keinen einzelnen Wert, sondern du suchst eine neue Funktion g die deine Anforderungen erfüllt und es wird bei höheren Dimensionen mehr als eine Funktion geben und im allgemeinen hat die Funktion g die gleiche Anzahl von Variablen wie f.

Mathematisch müsste das dann auf Differentialgleichungen über multiple Variablen rauslaufen, meine Mathevorlesungen sind zu lange her dass ich mich daran erinnern würde ;)

Geh in ein Matheforum und frag da nach, dann nimm Mathematica um das Problem zu lösen.
 
  • Gefällt mir
Reaktionen: N.N.
Ich habe das noch einmal verfeinert, und der Threshold 3,0 ist näher an dem gewünschten Ergebnis:

Javascript:
function f(a, b, c, m, n) {
  return (a * 10 + b * 30 + c * 20) / (Math.max(5, m) + Math.max(1.0, n) * 20);
}

let threshold = 3.0;
let c1 = 0;
let c2 = 0;

function typicallyVals(m) {
  for (let b = 0; b <= 4; b++) {
    let a = parseInt(m / 5);
    if (a < 1) {
      a = 1;
    }
    let c = a - 1;
    let n1 = 1.0;
    let n2 = 2.0;
    let f1 = f(a, b, c, m, n1);
    let f2 = f(a, b, c, m, n2);
    if (f1 >= threshold) {
      c1++;
      console.log("x", a, b, c, m, n1, f1.toFixed(2));
    } else {
      c2++;
      //console.log("o", a, b, c, m, n1, f1.toFixed(2));
    }
    if (f2 >= threshold) {
      c1++;
      console.log("x", a, b, c, m, n2, f2.toFixed(2));
    } else {
      c2++;
      //console.log("o", a, b, c, m, n2, f2.toFixed(2));
    }
  }
}

for (let m = 0; m <= 30; m++) typicallyVals(m);
console.log(((c1 / (c1 + c2)) * 100).toFixed(2));

Aber das ist, naja, eher geraten, denn gewusst wie...

Tornhoof schrieb:
und kennst den Wertebereich der einzelnen Variablen nicht. Soweit richtig?
Ja, das ist ein Problem. Ich kenne zwar den Wertebereich, doch dieser ist theoretisch nicht limitiert.

Also a,b,c,m sind ints und n ist float, alle Werte sind nicht negativ.

Dann kenne ich noch ein paar "typische Eigenschaften":

a ist meist c+1
b ist oft <=5
n ist oft <=4.5

Die Multiplikanden 10,30,20,20 sind gewissermaßen Gewichtungen in der Funktion.

So, und dann hört leider mein Wissen auf. :rolleyes: Sorry, vielleicht ist meine Frage auch unsinnig, ich weiß es nicht.
 
Auch meine Mathematikvorlesungen sind lange her, aber ich meine mich grob zu erinnern, da man da mit Wahrscheinlichkeitsgeschichten herangeht. Wie @Tornhoof schrieb, das ist ein Thema für ein Mathematikforum (einer Uni)
 
  • Gefällt mir
Reaktionen: N.N.
Die Fragestellung bzw. auch die zu untersuchende Definition muss erst mal definiert werden.
Die Funktionen aus dem ersten und dem aktuellsten Beitrag sind ja durchaus unterschiedlich.

Dann ist eben die Frage, ob a,b,c,m ∈ ℕ oder dann doch beschränkt auf bspw. ∈ {n ∈ ℕ | n<2 147 483 648}.

Und dann, ob weitere Einschränkungen für den Definitionsbereich (die "typischen Werte" gelten sollen oder nicht.)
Lässt man alle natürlichen Zahlen zu, dann ist offensichtlich, dass der Bildbereich nicht nach oben beschränkt ist und dass es bei einer zufalls-/gleichverteilten Stichprobe an Argumenten keine Quantile für den Bildbereich angegeben werden können.

Wenn man nun hingegen Verteilungen für die Funktionsargumente hätte, könnte man daraus ggf. Verteilungen für die Funktionswerte berechnen.
 
  • Gefällt mir
Reaktionen: N.N.
Unter einer Zufallsverteilung würde man ja oftmals gerade keine Gaußsche Normalverteilung, sondern eine Gleichverteiung verstehen.
Aber wenn die Argumente einer gewissen Verteilung folgen sollen, dann versuch doch mal, den Definitionsbereich der Argumente und die Wahrscheinlichkeitsverteilung anzugeben.

Denn, wie erwähnt, wenn das ganze für einfach alle natürlichen Zahlen als Argumente gelten soll, dann gibt es unendlich viele beliebig große Funktionswerte und man kann nicht das im ersten Post gesuchte 90%-Perzentil bestimmen.

Simpleres Beispiel: f(n) = 2n,n ∈ ℕ . Egal welchen endlichen Wert y du hier heranziehst, es gibt immer nur endlich viele andere Funktionswerte, die kleiner sind als dieser Wert und unendlich viele andere Funktiionswerte die größer sind.
 
  • Gefällt mir
Reaktionen: N.N.
Zurück
Oben