Fundamentals 7 min read

Wave Fluctuation Equal Distribution (波动均分) Algorithm: Exhaustive and Quick Allocation Methods

This article introduces the "wave fluctuation equal distribution" algorithm that splits a value into N parts within a bounded range with random variation, explains its characteristics, and provides two JavaScript implementations—an exhaustive enumeration method and a fast random allocation method—along with performance analysis and validation techniques.

JD Tech
JD Tech
JD Tech
Wave Fluctuation Equal Distribution (波动均分) Algorithm: Exhaustive and Quick Allocation Methods

The concept of "wave fluctuation equal distribution" (波动均分) is defined as dividing a specified value A into N parts, each part lying within a fixed interval [max, min] so that the quantities visually fluctuate around the average line with randomness.

The algorithm should exhibit five features: the number of parts, crest height, trough depth, random allocation, and comprehensive combination coverage.

Two implementation approaches are presented:

Exhaustive method – enumerates all possible combinations by constructing a multi‑branch tree and randomly selects a leaf as the result.

Quick allocation method – efficiently generates a single valid combination by dynamically adjusting the allowable range and randomly picking values.

Exhaustive method code:

function exhaustWave(n = 5, crest = 4, trough = 4) {
    let root = {parent: null, count: null, subtotal: 0}; // root node
    let leaves = [root];
    let level = 0;
    // check if current combination is legal
    let isOK = subtotal => {
        if (level < n - 1) {
            if (-subtotal <= (n - level) * crest || subtotal <= (n - level) * trough) return true;
        } else if (subtotal === 0) return true;
        else return false;
    };
    // generate combination tree
    while (level < n) {
        let newLeaves = [];
        leaves.forEach(node => {
            for (let count = -trough; count <= crest; ++count) {
                let subtotal = node.subtotal + count;
                isOK(subtotal) && newLeaves.push({parent: node, count: count, subtotal: subtotal});
            }
        });
        leaves = newLeaves, ++level;
    }
    // randomly pick a leaf
    let leaf = leaves[Math.random() * leaves.length >> 0];
    let group = [leaf.count];
    for (let i = 0; i < 4; ++i) {
        leaf = leaf.parent;
        group.push(leaf.count);
    }
    return group;
}

The exhaustive method cannot be used for infinite sets and is computationally inefficient, making it unsuitable for production use; it is mainly employed to verify the completeness of the quick method.

Quick allocation method code:

function quickWave(n = 5, crest = 4, trough = 4, isInteger = true) {
    // return uniform distribution when wave cannot be applied
    if (crest > (n - 1) * trough || trough > (n - 1) * crest) {
        return new Array(n).fill(0);
    }
    let list = [];
    let base = 0; // minimum needed offset
    let wave = 0; // fluctuation range
    let high = crest; // high bound
    let low = -trough; // low bound
    let sum = 0; // cumulative sum
    let count = n; // remaining parts
    while (--count >= 0) {
        if (crest > count * trough - sum) {
            high = count * trough - sum;
        }
        if (trough > count * crest + sum) {
            low = -sum - count * crest;
        }
        base = low;
        wave = high - low;
        let rnd;
        if (count > 0) {
            rnd = base + Math.random() * (wave + 1);
        } else {
            rnd = -sum;
        }
        if (isInteger === true) {
            rnd = Math.floor(rnd);
        }
        sum += rnd;
        list.push(rnd);
    }
    return list;
}

The quick allocation method is efficient and works for infinite sets, making it suitable for real‑world scenarios.

To validate the quick method, the exhaustive method is used to obtain the total number of possible combinations (e.g., 3951 for n=5, crest=4, trough=4). By repeatedly invoking quickWave many times and collecting distinct results, the coverage approaches the exhaustive total, confirming the randomness and completeness of the quick approach.

Verification code example:

console.log(exhaustWave(5, 4, 4)); // total combinations: 3951
let res = {}, count = 0, len = 10000;
for (let i = 0; i < len; ++i) {
    let name = quickWave(5, 4, 4).join("_");
    res[name] !== true && (res[name] = true, ++count);
}
console.log(count); // number of unique combinations after len runs

In conclusion, the author created this algorithm independently, acknowledges that similar algorithms may exist, and welcomes feedback on potential improvements.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

algorithmJavaScriptexhaustive searchquick allocationrandom distribution
JD Tech
Written by

JD Tech

Official JD technology sharing platform. All the cutting‑edge JD tech, innovative insights, and open‑source solutions you’re looking for, all in one place.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.