io.github.deepeshpatel.jnumbertools.generator.permutation.k.KPermutationCombinationOrderMth Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jnumbertools Show documentation
Show all versions of jnumbertools Show documentation
JNumberTools is the combinatorics and number-theory library which provides
useful APIS related to said topics
The newest version!
/*
* JNumberTools Library v1.0.3
* Copyright (c) 2022 Deepesh Patel ([email protected])
*/
package io.github.deepeshpatel.jnumbertools.generator.permutation.k;
import io.github.deepeshpatel.jnumbertools.base.Calculator;
import io.github.deepeshpatel.jnumbertools.base.Combinations;
import io.github.deepeshpatel.jnumbertools.base.Permutations;
import io.github.deepeshpatel.jnumbertools.generator.base.AbstractGenerator;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
/**
* Implements the iterable generating every nth unique permutation of size k.
* Permutations are generated in lex order of combinations of indices of input values, considering value at each index as unique.
* Instance of this class is intended to be created via builder and hence do not have any public constructor.
* @author Deepesh Patel
*/
public final class KPermutationCombinationOrderMth extends AbstractKPermutation {
final BigInteger totalPermutations;
final long permutationsPerList;
final BigInteger increment;
final BigInteger start;
private final Calculator calculator;
/**
* Implements the iterable generating every nth unique permutation of size k.
* Permutations are generated in lex order of indices of input values, considering value at each index as unique.
* @param elements Input of size n from which permutations of size k will be generated
* @param k size of permutations. k must be <=n
* @param increment position relative to first permutation which will be generated next in lexicographical order.
* generating every 'increment' permutation in a sequence.
* For example, if increment is set to 2, the output will generate 0th, 2nd,
* 4th.. permutations.
* This is important because for large k, it is impractical to generate all possible k! permutations
* and then increment to the desired position
*/
KPermutationCombinationOrderMth(List elements, int k, BigInteger increment, BigInteger start, Calculator calculator) {
super(elements, k);
AbstractGenerator.checkParamIncrement(increment, "mth K-Permutation");
this.start = start;
this.increment = increment;
this.totalPermutations = calculator.nPr(elements.size(), k);
this. permutationsPerList = calculator.factorial(k).longValue();
this.calculator = calculator;
}
@Override
public Iterator> iterator() {
return ( k==0 || elements.isEmpty()) ? newEmptyIterator() : new Itr();
}
private class Itr implements Iterator> {
BigInteger currentIncrement = start;
public Itr() {
}
@Override
public boolean hasNext() {
return currentIncrement.compareTo(totalPermutations) < 0;
}
@Override
public List next() {
BigInteger[] divideAndRemainder = currentIncrement.divideAndRemainder(BigInteger.valueOf(permutationsPerList));
BigInteger combinationListNumber = divideAndRemainder[0];
long permutationIncrement = divideAndRemainder[1].longValue();
currentIncrement = currentIncrement.add(increment);
List next = combinationListNumber.equals(BigInteger.ZERO) ?
new Combinations(calculator).unique(k,elements).lexOrder().iterator().next() :
new Combinations(calculator).unique(k, elements).lexOrderMth(combinationListNumber, BigInteger.ZERO).build();
return permutationIncrement == 0 ?
new Permutations(calculator).unique(next).lexOrder().iterator().next() :
new Permutations(calculator).unique(next).lexOrderMth(permutationIncrement,0).build();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy