All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.sandia.cognition.math.Permutation Maven / Gradle / Ivy

/*
 * File:                Permutation.java
 * Authors:             Justin Basilico
 * Company:             Sandia National Laboratories
 * Project:             Cognitive Foundry
 *
 * Copyright October 30, 2006, Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
 * or on behalf of the U.S. Government. Export of this program may require a
 * license from the United States Government. See CopyrightHistory.txt for
 * complete details.
 *
 */

package gov.sandia.cognition.math;

import gov.sandia.cognition.annotation.CodeReview;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;

/**
 * The Permutation class contains methods for dealing with
 * permutations of object sets.
 *
 * @author Justin Basilico
 * @since  1.0
 */
@CodeReview(
    reviewer="Kevin R. Dixon",
    date="2008-02-26",
    changesNeeded=false,
    comments="Looks good."
)
public class Permutation
    extends Object
{

    /** Creates a new instance of Permutation */
    public Permutation()
    {
        super();
    }

    /**
     * Reorders the elements in a given array list to be a permuted ordering of
     * elements in the collection.
     *
     * @param   
     *      The data type of the list to reorder.
     * @param   list
     *      The array list to reorder.
     * @param   random
     *      The random number generator to use.
     */
    public static  void reorder(
        final ArrayList list,
        final Random random)
    {
        // Go through the list and for each index pick a random index from the
        // remaining part and then swap the two values.
        final int size = list.size();
        for (int i = 0; i < size; i++)
        {
            // Pick an index into the remaining part of the list to swap with
            // element i.
            final int randomIndex = i + random.nextInt(size - i);

            // Now swap the two elements.
            final DataType elementRandom = list.get(randomIndex);
            final DataType elementI = list.get(i);
            list.set(i, elementRandom);
            list.set(randomIndex, elementI);
        }
    }
    
    /**
     * Takes a collection and returns an array list that contains a permutation
     * of the elements of that collection.
     *
     * @param  Data class to reorder
     * @param  collection The collection to create a permutation of.
     * @param  random The random number generator to use.
     * @return A permutation of the given collection.
     */
    public static  ArrayList createReordering(
        Collection collection,
        Random random )
    {
        ArrayList result = new ArrayList( collection );

        // Reorder the result.
        reorder(result, random);

        return result;
    }

    /**
     * Creates a random permutation of the numbers 0 (inclusive) through n 
     * (exclusive). The permutation contains the all the numbers 0 through n
     * in a random order. There are no duplicates.
     * 
     * @param  n The size of the permutation.
     * @param  random The Random generator to use.
     * @return A random permutation of the numbers 0 through n.
     */
    public static int[] createPermutation(
        int n,
        Random random )
    {
        // Initialize the array with the numbers 0 through n.
        int[] result = new int[n];
        for (int i = 0; i < n; i++)
        {
            result[i] = i;
        }

        // Walk the array and randomly pick the next element.
        for (int i = 0; i < n; i++)
        {
            int randomIndex = i + random.nextInt( n - i );
            int temp = result[i];
            result[i] = result[randomIndex];
            result[randomIndex] = temp;
        }

        return result;
    }
    
    /**
     * Creates a random partial permutation of size k of the numbers 0 
     * (inclusive) through n (exclusive). The permutation contains k unique
     * values of the numbers 0 through n in a random order. There are no 
     * duplicates.
     * 
     * @param  n 
     *      The size of the set of numbers to get values of the partial 
     *      permutation from.
     * @param  k
     *      The size of the partial permutation. Must be less than or equal to
     *      n. Cannot be negative.
     * @param  random 
     *      The Random generator to use.
     * @return 
     *      A random permutation of the numbers 0 through n.
     */
    public static int[] createPartialPermutation(
        final int n,
        final int k,
        final Random random)
    {
        if (k > n)
        {
            throw new IllegalArgumentException(
                "The value k (" + k + ") cannot be greater than n (" + n + ")");
        }
        else if (k == n)
        {
            return createPermutation(n, random);
        }
        
// TODO; There should be a faster algorithm that isn't O(n) but instead O(k).
        final int[] permutation = createPermutation(n, random);
        final int[] result = new int[k];
        System.arraycopy(permutation, 0, result, 0, k);
        return result;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy