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