public static <T> InvertibleCodec<ISeq<T>, EnumGene<T>> ofSubSet(
		final ISeq<? extends T> basicSet,
		final int size
	) {
		requireNonNull(basicSet);

		final Map<T, EnumGene<T>> genes =
			IntStream.range(0, basicSet.length())
				.mapToObj(i -> EnumGene.<T>of(i, basicSet))
				.collect(Collectors.toMap(EnumGene::allele, identity()));

		return InvertibleCodec.of(
			Genotype.of(PermutationChromosome.of(basicSet, size)),
			gt -> gt.chromosome().stream()
				.map(EnumGene::allele)
				.collect(ISeq.toISeq()),
			values -> {
				if (values.size() != size) {
					throw new IllegalArgumentException(format(
						"Expected sub-set size of %d, but got %d,",
						size, values.size()
					));
				}

				return Genotype.of(
					new PermutationChromosome<>(
						values.stream()
							.map(genes::get)
							.collect(ISeq.toISeq())
					)
				);
			}
		);
	}
The subset {@link InvertibleCodec} can be used for problems where it is
required to find the best <b>fixed-size</b> subset from a given basic set.

@since 3.4

@see PermutationChromosome
@see PermutationChromosome#of(ISeq, int)

@param <T> the element type of the basic set
@param basicSet the basic set, from where to choose the <i>optimal</i>
       subset.
@param size the length of the desired subsets
@return a new codec which can be used for modelling <i>subset</i>
        problems.
@throws NullPointerException if the given {@code basicSet} is
        {@code null}; {@code null} elements are allowed.
@throws IllegalArgumentException if {@code basicSet.size() < size},
        {@code size <= 0} or {@code basicSet.size()*size} will cause an
        integer overflow.
jenetics/src/main/java/io/jenetics/engine/Codecs.java