Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
mir.combinatorics
This module contains various combinatorics algorithms.
Authors:
Sebastian Wilzbach, Ilya Yaroshenko
License:
Examples:
import mir.ndslice.fuse; assert(['a', 'b'].permutations.fuse == [['a', 'b'], ['b', 'a']]); assert(['a', 'b'].cartesianPower(2).fuse == [['a', 'a'], ['a', 'b'], ['b', 'a'], ['b', 'b']]); assert(['a', 'b'].combinations(2).fuse == [['a', 'b']]); assert(['a', 'b'].combinationsRepeat(2).fuse == [['a', 'a'], ['a', 'b'], ['b', 'b']]); assert(permutations!ushort(2).fuse == [[0, 1], [1, 0]]); assert(cartesianPower!ushort(2, 2).fuse == [[0, 0], [0, 1], [1, 0], [1, 1]]); assert(combinations!ushort(2, 2).fuse == [[0, 1]]); assert(combinationsRepeat!ushort(2, 2).fuse == [[0, 0], [0, 1], [1, 1]]); assert([3, 1].permutations!ubyte.fuse == [[3, 1], [1, 3]]); assert([3, 1].cartesianPower!ubyte(2).fuse == [[3, 3], [3, 1], [1, 3], [1, 1]]); assert([3, 1].combinations!ubyte(2).fuse == [[3, 1]]); assert([3, 1].combinationsRepeat!ubyte(2).fuse == [[3, 3], [3, 1], [1, 1]]);
- R
binomial
(R = ulong, T)(Tn
, Tk
)
if (isArithmetic!(R, T) && (is(typeof(T.min < 0)) && is(typeof(T.init & 1)) || !is(typeof(T.min < 0)))); - Computes the binomial coefficient of n and k. It is also known as "n choose k" or more formally as _n!/_k!(_n-_k). If a fixed-length integer type is used and an overflow happens, 0 is returned.Uses the generalized binomial coefficient for negative integers and floating point numberParameters:
T n
arbitrary arithmetic type T k
arbitrary arithmetic type Returns:Binomial coefficientExamples:assert(binomial(5, 2) == 10); assert(binomial(6, 4) == 15); assert(binomial(3, 1) == 3); import std.bigint: BigInt; assert(binomial!BigInt(1000, 10) == BigInt("263409560461970212832400"));
- IndexedRoR!(Collection, Range)
indexedRoR
(Collection, Range)(Collectioncollection
, Rangerange
)
if (__traits(compiles, Range.init[size_t.init]));
structIndexedRoR
(Collection, Range) if (__traits(compiles, Range.init[size_t.init])); - Creates a projection of a generalized Collection range for the numeric case case starting from 0 onto a custom
range
of any type.Parameters:Collection collection
range to be projected from Range range
random access range to be projected to Returns:Range with a projection to range for every element of collectionSee Also:Examples:import mir.ndslice.fuse; auto perms = 2.permutations; assert(perms.save.fuse == [[0, 1], [1, 0]]); auto projection = perms.indexedRoR([1, 2]); assert(projection.fuse == [[1, 2], [2, 1]]);
Examples:import mir.ndslice.fuse; // import mir.ndslice.topology: only; auto projectionD = 2.permutations.indexedRoR("ab"d); assert(projectionD.fuse == [['a', 'b'], ['b', 'a']]); // auto projectionC = 2.permutations.indexedRoR(only('a', 'b')); // assert(projectionC.fuse == [['a', 'b'], ['b', 'a']]);
- pure nothrow @safe Permutations!T
permutations
(T = uint)(size_tn
)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof));
pure nothrow @safe IndexedRoR!(Permutations!T, Range)permutations
(T = uint, Range)(Ranger
)
if (__traits(compiles, Range.init[size_t.init]));
Permutations!TmakePermutations
(T = uint, Allocator)(auto ref Allocatoralloc
, size_tn
)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazily computes all permutations of
r
using Heap's algorithm.While generating a new item is in O(k) (amortized O(1)), the number of permutations is |n
|!.Parameters:size_t n
number of elements (| r
|)Range r
random access field. A field may not have iteration primitivies. Allocator alloc
custom Allocator Returns:Forward range, which yields the permutationsSee Also: - struct
Permutations
(T) if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazy Forward range of permutations using Heap's algorithm.It always generates the permutations from 0 to n - 1, use indexedRoR to map it to your range. Generating a new item is in O(k) (amortized O(1)), the total number of elements is n^k.See Also:Examples:
import mir.ndslice.fuse; import mir.ndslice.topology : iota; auto expectedRes = [[0, 1, 2], [1, 0, 2], [2, 0, 1], [0, 2, 1], [1, 2, 0], [2, 1, 0]]; auto r = iota(3); auto rp = permutations(r.length).indexedRoR(r); assert(rp.fuse == expectedRes); // direct style auto rp2 = iota(3).permutations; assert(rp2.fuse == expectedRes);
Examples:import mir.algorithm.iteration: equal; import mir.ndslice.slice: sliced; import mir.ndslice.topology : iota; import std.experimental.allocator.mallocator; static immutable expected2 = [0, 1, 1, 0]; auto r = iota(2); auto rp = makePermutations(Mallocator.instance, r.length); assert(expected2.sliced(2, 2).equal(rp.indexedRoR(r))); dispose(Mallocator.instance, rp);
- alias
DeepElement
= T; - pure nothrow @nogc @safe this()(T[]
state
, T[]indices
); - state should have the length of n - 1, whereas the length of indices should be n
- pure nothrow @nogc @property @safe Slice!(const(T)*)
front
()();
pure nothrow @nogc scope @safe voidpopFront
()();
const pure nothrow @nogc @property scope @safe boolempty
()();
const pure nothrow @nogc @property scope @safe size_tlength
()(); - Input range primitives
- const @property scope size_t[2]
shape
()(); - pure nothrow @property @safe Permutations
save
()(); - Forward range primitive. Allocates using GC.
- void
dispose
(T, Allocator)(auto ref Allocatoralloc
, auto ref Permutations!Tperm
); - Disposes a Permutations object. It destroys and then deallocates the Permutations object pointed to by a pointer. It is assumed the respective entities had been allocated with the same allocator.Parameters:
Allocator alloc
Custom allocator Permutations!T perm
Permutations object See Also: - pure nothrow @safe CartesianPower!T
cartesianPower
(T = uint)(size_tn
, size_trepeat
= 1)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof));
IndexedRoR!(CartesianPower!T, Range)cartesianPower
(T = uint, Range)(Ranger
, size_trepeat
= 1)
if (isUnsigned!T && __traits(compiles, Range.init[size_t.init]));
CartesianPower!TmakeCartesianPower
(T = uint, Allocator)(auto ref Allocatoralloc
, size_tn
, size_trepeat
)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazily computes the Cartesian power of
r
with itself for a number of repetitions Drepeat
. If the input is sorted, the product is in lexicographic order.While generating a new item is in O(k) (amortized O(1)), the total number of elements isn
^k.Parameters:size_t n
number of elements (| r
|)Range r
random access field. A field may not have iteration primitivies. size_t repeat
number of repetitions Allocator alloc
custom Allocator Returns:Forward range, which yields the product itemsSee Also: - struct
CartesianPower
(T) if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazy Forward range of Cartesian Power. It always generates Cartesian Power from 0 to n - 1, use indexedRoR to map it to your range.Generating a new item is in O(k) (amortized O(1)), the total number of elements is n^k.See Also:Examples:
import mir.ndslice.fuse; import mir.ndslice.topology: iota; assert(iota(2).cartesianPower.fuse == [[0], [1]]); assert(iota(2).cartesianPower(2).fuse == [[0, 0], [0, 1], [1, 0], [1, 1]]); auto three_nums_two_bins = [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]; assert(iota(3).cartesianPower(2).fuse == three_nums_two_bins); assert("AB"d.cartesianPower(2).fuse == ["AA"d, "AB"d, "BA"d, "BB"d]);
Examples:import mir.ndslice.topology: iota; import mir.algorithm.iteration: equal; import mir.ndslice.slice: sliced; import std.experimental.allocator.mallocator: Mallocator; auto alloc = Mallocator.instance; static immutable expected2r2 = [ 0, 0, 0, 1, 1, 0, 1, 1]; auto r = iota(2); auto rc = alloc.makeCartesianPower(r.length, 2); assert(expected2r2.sliced(4, 2).equal(rc.indexedRoR(r))); alloc.dispose(rc);
- alias
DeepElement
= T; - pure nothrow @nogc @safe this()(size_t
n
, T[]state
); - state should have the length of repeat
- pure nothrow @nogc @property @safe Slice!(const(T)*)
front
()();
pure nothrow @nogc scope @safe voidpopFront
()();
const pure nothrow @nogc @property scope @safe size_tlength
()();
const pure nothrow @nogc @property scope @safe boolempty
()(); - Input range primitives
- const @property scope size_t[2]
shape
()(); - pure nothrow @property @safe CartesianPower
save
()(); - Forward range primitive. Allocates using GC.
- void
dispose
(T = uint, Allocator)(auto ref Allocatoralloc
, auto ref CartesianPower!TcartesianPower
); - Disposes a CartesianPower object. It destroys and then deallocates the CartesianPower object pointed to by a pointer. It is assumed the respective entities had been allocated with the same allocator.Parameters:
Allocator alloc
Custom allocator CartesianPower!T cartesianPower
CartesianPower object See Also: - pure nothrow @safe Combinations!T
combinations
(T = uint)(size_tn
, size_tk
= 1)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof));
IndexedRoR!(Combinations!T, Range)combinations
(T = uint, Range)(Ranger
, size_tk
= 1)
if (isUnsigned!T && __traits(compiles, Range.init[size_t.init]));
Combinations!TmakeCombinations
(T = uint, Allocator)(auto ref Allocatoralloc
, size_tn
, size_trepeat
)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazily computes all k-combinations of
r
. Imagine this as the cartesianPower filtered for only strictly ordered items.While generating a new combination is in O(k
), the number of combinations is binomial(n
,k
).Parameters:size_t n
number of elements (| r
|)Range r
random access field. A field may not have iteration primitivies. size_t k
number of combinations Allocator alloc
custom Allocator Returns:Forward range, which yields the k-combinations itemsSee Also: - struct
Combinations
(T) if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazy Forward range of Combinations. It always generates combinations from 0 to n - 1, use indexedRoR to map it to your range.Generating a new combination is in O(k), the number of combinations is binomial(n, k).See Also:Examples:
import mir.ndslice.fuse; import mir.ndslice.topology: iota; assert(iota(3).combinations(2).fuse == [[0, 1], [0, 2], [1, 2]]); assert("AB"d.combinations(2).fuse == ["AB"d]); assert("ABC"d.combinations(2).fuse == ["AB"d, "AC"d, "BC"d]);
Examples:import mir.algorithm.iteration: equal; import mir.ndslice.slice: sliced; import mir.ndslice.topology: iota; import std.experimental.allocator.mallocator; auto alloc = Mallocator.instance; static immutable expected3r2 = [ 0, 1, 0, 2, 1, 2]; auto r = iota(3); auto rc = alloc.makeCombinations(r.length, 2); assert(expected3r2.sliced(3, 2).equal(rc.indexedRoR(r))); alloc.dispose(rc);
- alias
DeepElement
= T; - pure nothrow @nogc @safe this()(size_t
n
, T[]state
); - state should have the length of repeat
- pure nothrow @nogc @property @safe Slice!(const(T)*)
front
()();
pure nothrow @nogc scope @safe voidpopFront
()();
const pure nothrow @nogc @property scope @safe size_tlength
()();
const pure nothrow @nogc @property scope @safe boolempty
()(); - Input range primitives
- const @property scope size_t[2]
shape
()(); - pure nothrow @property @safe Combinations
save
()(); - Forward range primitive. Allocates using GC.
- void
dispose
(T, Allocator)(auto ref Allocatoralloc
, auto ref Combinations!Tperm
); - Disposes a Combinations object. It destroys and then deallocates the Combinations object pointed to by a pointer. It is assumed the respective entities had been allocated with the same allocator.Parameters:
Allocator alloc
Custom allocator Combinations!T perm
Combinations object See Also: - pure nothrow @safe CombinationsRepeat!T
combinationsRepeat
(T = uint)(size_tn
, size_tk
= 1)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof));
IndexedRoR!(CombinationsRepeat!T, Range)combinationsRepeat
(T = uint, Range)(Ranger
, size_tk
= 1)
if (isUnsigned!T && __traits(compiles, Range.init[size_t.init]));
CombinationsRepeat!TmakeCombinationsRepeat
(T = uint, Allocator)(auto ref Allocatoralloc
, size_tn
, size_trepeat
)
if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazily computes all k-combinations of
r
with repetitions. A k-combination with repetitions, or k-multicombination, or multisubset of size k from a set S is given by a sequence of k not necessarily distinct elements of S, where order is not taken into account. Imagine this as the cartesianPower filtered for only ordered items.While generating a new combination with repeats is in O(k
), the number of combinations with repeats is binomial(n
+k
- 1,k
).Parameters:size_t n
number of elements (| r
|)Range r
random access field. A field may not have iteration primitivies. size_t k
number of combinations Allocator alloc
custom Allocator Returns:Forward range, which yields the k-multicombinations itemsSee Also: - struct
CombinationsRepeat
(T) if (isUnsigned!T && (T.sizeof <= size_t.sizeof)); - Lazy Forward range of combinations with repeats. It always generates combinations with repeats from 0 to n - 1, use indexedRoR to map it to your range.Generating a new combination with repeats is in O(k), the number of combinations with repeats is binomial(n, k).See Also:Examples:
import mir.ndslice.fuse; import mir.ndslice.topology: iota; assert(iota(2).combinationsRepeat.fuse == [[0], [1]]); assert(iota(2).combinationsRepeat(2).fuse == [[0, 0], [0, 1], [1, 1]]); assert(iota(3).combinationsRepeat(2).fuse == [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]); assert("AB"d.combinationsRepeat(2).fuse == ["AA"d, "AB"d, "BB"d]);
Examples:import mir.algorithm.iteration: equal; import mir.ndslice.slice: sliced; import mir.ndslice.topology: iota; import std.experimental.allocator.mallocator; auto alloc = Mallocator.instance; static immutable expected3r1 = [ 0, 1, 2]; auto r = iota(3); auto rc = alloc.makeCombinationsRepeat(r.length, 1); assert(expected3r1.sliced(3, 1).equal(rc.indexedRoR(r))); alloc.dispose(rc);
- alias
DeepElement
= T; - pure nothrow @nogc @safe this()(size_t
n
, T[]state
); - state should have the length of repeat
- pure nothrow @nogc @property @safe Slice!(const(T)*)
front
()();
pure nothrow @nogc scope @safe voidpopFront
()();
const pure nothrow @nogc @property scope @safe size_tlength
()();
const pure nothrow @nogc @property scope @safe boolempty
()(); - Input range primitives
- const @property scope size_t[2]
shape
()(); - pure nothrow @property @safe CombinationsRepeat
save
()(); - Forward range primitive. Allocates using GC.
- void
dispose
(T, Allocator)(auto ref Allocatoralloc
, auto ref CombinationsRepeat!Tperm
); - Disposes a CombinationsRepeat object. It destroys and then deallocates the CombinationsRepeat object pointed to by a pointer. It is assumed the respective entities had been allocated with the same allocator.Parameters:
Allocator alloc
Custom allocator CombinationsRepeat!T perm
CombinationsRepeat object See Also:
Copyright © 2016-2022 by Ilya Yaroshenko | Page generated by
Ddoc on Tue Jan 11 06:37:07 2022