Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a75b45b authored by James O'Leary's avatar James O'Leary
Browse files

Fix initializing clusters with random randoms

During the quantization process, an instance of a Quantizer is created.
When quantization is run, the Quantizer may need to create starting
points that are random. To keep results stable, meaning multiple runs of
a quantizer output the same results, those starting points must
be created using a Random with the same starting seed. Without
specifying a starting seed, or if an instance of Random is reused across
runs, the random starting points will vary across quantizer runs.

With this patch, the Random used to create starting points is no longer
used across multiple runs (i.e. it isn't a static variable anymore).
Additionally, a starting seed is specified.

Test: Add log dumps after the quantization process. Verify that results
from Kmeans remain consistent as long as the input is consistent.
Bug: 182333325

Change-Id: Ia0f984349b7885ae1b44536aaa1b286a28e50587
parent ccc3f976
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -22,20 +22,19 @@ import java.util.Random;
 * Represents a centroid in Kmeans algorithms.
 */
public class Mean {
    private static final Random RANDOM = new Random(0);

    public float[] center;

    /**
     * Constructor.
     *
     * @param upperBound maximum value of a dimension in the space Kmeans is optimizing in
     * @param random used to generate a random center
     */
    Mean(int upperBound) {
    Mean(int upperBound, Random random) {
        center =
                new float[]{
                        RANDOM.nextInt(upperBound + 1), RANDOM.nextInt(upperBound + 1),
                        RANDOM.nextInt(upperBound + 1)
                        random.nextInt(upperBound + 1), random.nextInt(upperBound + 1),
                        random.nextInt(upperBound + 1)
                };
    }

+10 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;


@@ -57,9 +58,12 @@ public class WSMeansQuantizer implements Quantizer {
        }

        if (maxColors > means.length) {
            // Always initialize Random with the same seed. Ensures the results of quantization
            // are consistent, even when random centroids are required.
            Random random = new Random(0x42688);
            int randomMeansToCreate = maxColors - means.length;
            for (int i = 0; i < randomMeansToCreate; i++) {
                mMeans[means.length + i] = new Mean(100);
                mMeans[means.length + i] = new Mean(100, random);
            }
        }

@@ -105,8 +109,12 @@ public class WSMeansQuantizer implements Quantizer {
    /** Create random starting centroids for K-means. */
    public static float[][] randomMeans(int maxColors, int upperBound) {
        float[][] means = new float[maxColors][];

        // Always initialize Random with the same seed. Ensures the results of quantization
        // are consistent, even when random centroids are required.
        Random random = new Random(0x42688);
        for (int i = 0; i < maxColors; i++) {
            means[i] = new Mean(upperBound).center;
            means[i] = new Mean(upperBound, random).center;
        }
        return means;
    }