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

io.github.deepeshpatel.jnumbertools.generator.permutation.unique.UniquePermutationsMth Maven / Gradle / Ivy

/*
 * JNumberTools Library v1.0.3
 * Copyright (c) 2022 Deepesh Patel ([email protected])
 */

package io.github.deepeshpatel.jnumbertools.generator.permutation.unique;

import io.github.deepeshpatel.jnumbertools.base.Calculator;
import io.github.deepeshpatel.jnumbertools.generator.base.AbstractGenerator;
import io.github.deepeshpatel.jnumbertools.numbersystem.FactoradicAlgorithms;

import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.IntStream;

/**
 * Utility to generate permutations with unique values starting from
 * ginve permutation number and then generate every nth permutation in
 * lexicographical order of indices of input values where each value is considered unique.
 * 

* Generating the nth permutation directly is crucial for efficiently handling cases where * generating permutations sequentially would be infeasible due to the enormous number of possible * permutations (e.g., 100! permutations for 100 items). *

* This class provides a mechanism to generate directly the next nth lexicographical * permutation. * * Instance of this class is intended to be created via builder and hence do not have any public constructor. * * @author Deepesh Patel * @param the type of elements to permute */ public final class UniquePermutationsMth extends AbstractGenerator { private final BigInteger start; private final BigInteger increment; private BigInteger numOfPermutations; private final int[] initialIndices; private final Calculator calculator; /** * Constructs a UniquePermutationsMth with the specified parameters. * * @param elements the list of elements to permute * @param increment the increment to generate the next nth permutation * @param start the starting index for permutation generation * @param calculator a calculator instance for computing factorials */ UniquePermutationsMth(List elements, BigInteger increment, BigInteger start, Calculator calculator) { super(elements); this.start = start; this.increment = increment; checkParamIncrement(increment, "unique permutations"); this.calculator = calculator; initialIndices = IntStream.range(0, elements.size()).toArray(); } /** * Builds and returns the mth permutation directly. *

* Use this method instead of the iterator if you need only a specific mth permutation * and not a sequence of permutations. * * @return the mth permutation as a List of elements */ public List build() { var indices = FactoradicAlgorithms.unRank(increment, initialIndices.length); return indicesToValues(indices); } @Override public Iterator> iterator() { synchronized (this) { numOfPermutations = numOfPermutations == null ? calculator.factorial(elements.size()) : numOfPermutations; } return new KthItemIterator(); } private class KthItemIterator implements Iterator> { private BigInteger nextK = start; @Override public boolean hasNext() { return nextK.compareTo(numOfPermutations) < 0; } @Override public List next() { if (!hasNext()) { throw new NoSuchElementException(); } int[] currentIndices = nextPermutation(nextK, initialIndices.length); nextK = nextK.add(increment); return indicesToValues(currentIndices); } /** * Calculates the kth permutation given its rank. * * @param kth the rank of the permutation * @param numberOfItems the total number of items * @return the indices representing the nth permutation */ public int[] nextPermutation(BigInteger kth, int numberOfItems) { return FactoradicAlgorithms.unRank(kth, numberOfItems); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy