stat/combin: Add CombinationToIndex and IndexToCombination functions (#1054)

* stat/combin: Add CombinationToIndex and IndexToCombination functions
This commit is contained in:
Brendan Tracey
2019-08-21 11:10:10 +01:00
committed by GitHub
parent 035030958a
commit d61003946d
4 changed files with 301 additions and 63 deletions

View File

@@ -0,0 +1,130 @@
// Copyright ©2019 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package combin_test
import (
"fmt"
"gonum.org/v1/gonum/stat/combin"
)
func ExampleCombinations_Index() {
data := []string{"a", "b", "c", "d", "e"}
cs := combin.Combinations(len(data), 2)
for _, c := range cs {
fmt.Printf("%s%s\n", data[c[0]], data[c[1]])
}
// Output:
// ab
// ac
// ad
// ae
// bc
// bd
// be
// cd
// ce
// de
}
func ExampleCombinations() {
// combin provides several ways to work with the combinations of
// different objects. Combinations generates them directly.
fmt.Println("Generate list:")
n := 5
k := 3
list := combin.Combinations(n, k)
for i, v := range list {
fmt.Println(i, v)
}
// The returned values can be used to index into a data structure.
data := []string{"a", "b", "c", "d", "e"}
cs := combin.Combinations(len(data), 2)
fmt.Println("\nString combinations:")
for _, c := range cs {
fmt.Printf("%s%s\n", data[c[0]], data[c[1]])
}
// This is easy, but the number of combinations can be very large,
// and generating all at once can use a lot of memory.
// Output:
// Generate list:
// 0 [0 1 2]
// 1 [0 1 3]
// 2 [0 1 4]
// 3 [0 2 3]
// 4 [0 2 4]
// 5 [0 3 4]
// 6 [1 2 3]
// 7 [1 2 4]
// 8 [1 3 4]
// 9 [2 3 4]
//
// String combinations:
// ab
// ac
// ad
// ae
// bc
// bd
// be
// cd
// ce
// de
}
func ExampleCombinationGenerator() {
// combin provides several ways to work with the combinations of
// different objects. CombinationGenerator constructs an iterator
// for the combinations.
n := 5
k := 3
gen := combin.NewCombinationGenerator(n, k)
idx := 0
for gen.Next() {
fmt.Println(idx, gen.Combination(nil)) // can also store in-place.
idx++
}
// Output:
// 0 [0 1 2]
// 1 [0 1 3]
// 2 [0 1 4]
// 3 [0 2 3]
// 4 [0 2 4]
// 5 [0 3 4]
// 6 [1 2 3]
// 7 [1 2 4]
// 8 [1 3 4]
// 9 [2 3 4]
}
func ExampleIndexToCombination() {
// combin provides several ways to work with the combinations of
// different objects. IndexToCombination allows random access into
// the combination order. Combined with CombinationIndex this
// provides a correspondence between integers and combinations.
n := 5
k := 3
comb := make([]int, k)
for i := 0; i < combin.Binomial(n, k); i++ {
combin.IndexToCombination(comb, i, n, k) // can also use nil.
idx := combin.CombinationIndex(comb, n, k)
fmt.Println(i, comb, idx)
}
// Output:
// 0 [0 1 2] 0
// 1 [0 1 3] 1
// 2 [0 1 4] 2
// 3 [0 2 3] 3
// 4 [0 2 4] 4
// 5 [0 3 4] 5
// 6 [1 2 3] 6
// 7 [1 2 4] 7
// 8 [1 3 4] 8
// 9 [2 3 4] 9
}