perf: 优化 combination 包 NCarryM 性能
This commit is contained in:
parent
57936b2b25
commit
abd1db5586
|
@ -88,6 +88,9 @@ func (slf *Combination[T]) Best(items []T) (name string, result []T) {
|
||||||
for _, n := range slf.priority {
|
for _, n := range slf.priority {
|
||||||
matcher := slf.matchers[n]
|
matcher := slf.matchers[n]
|
||||||
matcherBest := matcher.Best(items)
|
matcherBest := matcher.Best(items)
|
||||||
|
if len(matcherBest) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if score := matcher.evaluate(matcherBest); score > best || best == -1 {
|
if score := matcher.evaluate(matcherBest); score > best || best == -1 {
|
||||||
best = score
|
best = score
|
||||||
name = n
|
name = n
|
||||||
|
@ -103,6 +106,9 @@ func (slf *Combination[T]) Worst(items []T) (name string, result []T) {
|
||||||
for _, n := range slf.priority {
|
for _, n := range slf.priority {
|
||||||
matcher := slf.matchers[n]
|
matcher := slf.matchers[n]
|
||||||
matcherWorst := matcher.Worst(items)
|
matcherWorst := matcher.Worst(items)
|
||||||
|
if len(matcherWorst) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if score := matcher.evaluate(matcherWorst); score < worst || worst == -1 {
|
if score := matcher.evaluate(matcherWorst); score < worst || worst == -1 {
|
||||||
worst = score
|
worst = score
|
||||||
name = n
|
name = n
|
||||||
|
|
|
@ -40,9 +40,20 @@ func TestCombination_Best(t *testing.T) {
|
||||||
{Point: 5, Color: 3},
|
{Point: 5, Color: 3},
|
||||||
{Point: 6, Color: 4},
|
{Point: 6, Color: 4},
|
||||||
{Point: 7, Color: 1},
|
{Point: 7, Color: 1},
|
||||||
|
{Point: 8, Color: 2},
|
||||||
|
{Point: 9, Color: 3},
|
||||||
|
{Point: 10, Color: 4},
|
||||||
|
{Point: 11, Color: 1},
|
||||||
|
{Point: 12, Color: 2},
|
||||||
|
{Point: 13, Color: 3},
|
||||||
|
{Point: 10, Color: 3},
|
||||||
|
{Point: 11, Color: 2},
|
||||||
|
{Point: 12, Color: 1},
|
||||||
|
{Point: 13, Color: 4},
|
||||||
|
{Point: 10, Color: 2},
|
||||||
}
|
}
|
||||||
|
|
||||||
name, result := combine.Best(cards)
|
name, result := combine.Worst(cards)
|
||||||
fmt.Println("best:", name)
|
fmt.Println("best:", name)
|
||||||
for _, item := range result {
|
for _, item := range result {
|
||||||
fmt.Println(item)
|
fmt.Println(item)
|
||||||
|
|
|
@ -147,17 +147,23 @@ func WithMatcherNCarryM[T Item, E generic.Ordered](n, m int, getType func(item T
|
||||||
if len(group) != n {
|
if len(group) != n {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ms := slice.Combinations(slice.SubWithCheck(items, group, func(a, b T) bool { return reflect.DeepEqual(a, b) }))
|
other := slice.SubWithCheck(items, group, func(a, b T) bool { return reflect.DeepEqual(a, b) })
|
||||||
for i := 0; i < len(ms); i++ {
|
ms := slice.LimitedCombinations(other, m, m)
|
||||||
ts := make(map[E][]T)
|
for _, otherGroup := range ms {
|
||||||
for _, t := range ms[i] {
|
var t E
|
||||||
tt := getType(t)
|
var init = true
|
||||||
ts[tt] = append(ts[tt], t)
|
var same = true
|
||||||
|
for _, item := range otherGroup {
|
||||||
|
if init {
|
||||||
|
init = false
|
||||||
|
t = getType(item)
|
||||||
|
} else if getType(item) != t {
|
||||||
|
same = false
|
||||||
|
break
|
||||||
}
|
}
|
||||||
for _, cs := range ts {
|
|
||||||
if len(cs) == m {
|
|
||||||
combinations = append(combinations, slice.Merge(group, cs))
|
|
||||||
}
|
}
|
||||||
|
if same {
|
||||||
|
combinations = append(combinations, slice.Merge(group, otherGroup))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,12 +191,9 @@ func WithMatcherNCarryIndependentM[T Item, E generic.Ordered](n, m int, getType
|
||||||
if len(group) != n {
|
if len(group) != n {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ms := slice.Combinations(slice.SubWithCheck(items, group, func(a, b T) bool { return reflect.DeepEqual(a, b) }))
|
ms := slice.LimitedCombinations(slice.SubWithCheck(items, group, func(a, b T) bool { return reflect.DeepEqual(a, b) }), m, m)
|
||||||
for i := 0; i < len(ms); i++ {
|
for _, otherGroup := range ms {
|
||||||
is := ms[i]
|
combinations = append(combinations, slice.Merge(group, otherGroup))
|
||||||
if len(is) == m {
|
|
||||||
combinations = append(combinations, slice.Merge(group, is))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return combinations
|
return combinations
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package slice
|
package slice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
@ -223,10 +224,10 @@ func Combinations[T any](a []T) [][]T {
|
||||||
n := len(a)
|
n := len(a)
|
||||||
|
|
||||||
// 去除重复元素,保留唯一元素
|
// 去除重复元素,保留唯一元素
|
||||||
uniqueSet := make(map[uintptr]bool)
|
uniqueSet := make(map[string]bool)
|
||||||
uniqueSlice := make([]T, 0, n)
|
uniqueSlice := make([]T, 0, n)
|
||||||
for _, val := range a {
|
for _, val := range a {
|
||||||
ptr := reflect.ValueOf(val).Pointer()
|
ptr := fmt.Sprintf("%p", val)
|
||||||
if !uniqueSet[ptr] {
|
if !uniqueSet[ptr] {
|
||||||
uniqueSet[ptr] = true
|
uniqueSet[ptr] = true
|
||||||
uniqueSlice = append(uniqueSlice, val)
|
uniqueSlice = append(uniqueSlice, val)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package storage_test
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/kercylan98/minotaur/utils/slice"
|
||||||
"github.com/kercylan98/minotaur/utils/storage"
|
"github.com/kercylan98/minotaur/utils/storage"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -43,3 +44,13 @@ func TestData_Struct(t *testing.T) {
|
||||||
|
|
||||||
fmt.Println(string(bytes))
|
fmt.Println(string(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestData_Handle(t *testing.T) {
|
||||||
|
var is []int
|
||||||
|
for i := 1; i <= 23; i++ {
|
||||||
|
is = append(is, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := slice.LimitedCombinations(is, 5, 5)
|
||||||
|
fmt.Println("Count:", len(res))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue