go:Bit Operation Algorithm

项目结构:

image

 

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:15
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : bfs_combine.go
*/
package algorithm

import (
	"BitOperation/domain/entity"
	"container/list"
)

type node struct {
	mask   int
	totalW float64
	totalP float64
}

// BfsJewelryCombiner BFS+位掩码搭配算法
type BfsJewelryCombiner struct {
	jewels   []*entity.Jewelry
	n        int
	maxW     float64
	maxP     float64
	bestMask int
	bestRate float64
}

func NewBfsJewelryCombiner(list []*entity.Jewelry, maxW, maxP float64) *BfsJewelryCombiner {
	return &BfsJewelryCombiner{
		jewels: list,
		n:      len(list),
		maxW:   maxW,
		maxP:   maxP,
	}
}

func (b *BfsJewelryCombiner) SearchBestCombine() ([]string, float64, float64) {
	queue := list.New()
	queue.PushBack(node{mask: 0, totalW: 0, totalP: 0})
	b.bestMask = 0
	b.bestRate = 0

	for queue.Len() > 0 {
		elem := queue.Front()
		queue.Remove(elem)
		cur := elem.Value.(node)
		rate := 0.0
		if cur.totalW > 0 {
			rate = cur.totalP / cur.totalW
		}
		if rate > b.bestRate {
			b.bestRate = rate
			b.bestMask = cur.mask
		}
		for i := 0; i < b.n; i++ {
			if (cur.mask & (1 << i)) == 0 {
				newMask := cur.mask | (1 << i)
				newW := cur.totalW + b.jewels[i].Weight
				newP := cur.totalP + b.jewels[i].Price
				if newW <= b.maxW && newP <= b.maxP {
					queue.PushBack(node{mask: newMask, totalW: newW, totalP: newP})
				}
			}
		}
	}
	// 解析掩码
	var ids []string
	var tw, tp float64
	for i := 0; i < b.n; i++ {
		if (b.bestMask & (1 << i)) != 0 {
			ids = append(ids, b.jewels[i].JewelID)
			tw += b.jewels[i].Weight
			tp += b.jewels[i].Price
		}
	}
	return ids, tw, tp
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:16
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : bit_array.go
*/
package algorithm

// BitArray 高性能位图,千万级查重、黑名单过滤
type BitArray struct {
	size int
	arr  []byte
}

func NewBitArray(size int) *BitArray {
	byteLen := (size + 7) / 8
	return &BitArray{
		size: size,
		arr:  make([]byte, byteLen),
	}
}

func (b *BitArray) Set(idx int) {
	if idx < 0 || idx >= b.size {
		return
	}
	pos := idx / 8
	bit := idx % 8
	b.arr[pos] |= 1 << bit
}

func (b *BitArray) UnSet(idx int) {
	if idx < 0 || idx >= b.size {
		return
	}
	pos := idx / 8
	bit := idx % 8
	b.arr[pos] &^= 1 << bit
}

func (b *BitArray) Get(idx int) bool {
	if idx < 0 || idx >= b.size {
		return false
	}
	pos := idx / 8
	bit := idx % 8
	return (b.arr[pos] & (1 << bit)) != 0
}

func (b *BitArray) BatchSet(indexList []int) {
	for _, idx := range indexList {
		b.Set(idx)
	}
}

func (b *BitArray) BatchCheck(indexList []int) []bool {
	res := make([]bool, len(indexList))
	for i, idx := range indexList {
		res[i] = b.Get(idx)
	}
	return res
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:15
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : gale_shapley.go
*/
package algorithm

import "BitOperation/domain/entity"

// GaleShapleyMatcher GS稳定婚配算法
type GaleShapleyMatcher struct {
	guideList  []*entity.Guide
	custList   []*entity.Customer
	guideMap   map[string]*entity.Guide
	custMap    map[string]*entity.Customer
	guideMatch map[string]string
	custMatch  map[string]string
	guidePtr   map[string]int
}

func NewGaleShapleyMatcher(guides []*entity.Guide, customers []*entity.Customer) *GaleShapleyMatcher {
	gm := make(map[string]*entity.Guide)
	cm := make(map[string]*entity.Customer)
	ptr := make(map[string]int)
	for _, g := range guides {
		gm[g.GuideID] = g
		ptr[g.GuideID] = 0
	}
	for _, c := range customers {
		cm[c.CustomerID] = c
	}
	return &GaleShapleyMatcher{
		guideList:  guides,
		custList:   customers,
		guideMap:   gm,
		custMap:    cm,
		guideMatch: make(map[string]string),
		custMatch:  make(map[string]string),
		guidePtr:   ptr,
	}
}

func (g *GaleShapleyMatcher) getCustRank(guide *entity.Guide, cid string) int {
	for idx, id := range guide.CustomerPriority {
		if id == cid {
			return idx
		}
	}
	return 999
}

func (g *GaleShapleyMatcher) getGuideRank(cust *entity.Customer, gid string) int {
	guide := g.guideMap[gid]
	score := cust.MatchScore(guide.SkillMask)
	return -score
}

func (g *GaleShapleyMatcher) Match() map[string]string {
	freeGuide := make([]string, 0)
	for _, gObj := range g.guideList {
		freeGuide = append(freeGuide, gObj.GuideID)
	}

	for len(freeGuide) > 0 {
		gid := freeGuide[0]
		freeGuide = freeGuide[1:]
		guide := g.guideMap[gid]
		ptr := g.guidePtr[gid]
		if ptr >= len(guide.CustomerPriority) {
			continue
		}
		cid := guide.CustomerPriority[ptr]
		g.guidePtr[gid]++
		cust := g.custMap[cid]

		if _, ok := g.custMatch[cid]; !ok {
			g.guideMatch[gid] = cid
			g.custMatch[cid] = gid
		} else {
			oldGid := g.custMatch[cid]
			r1 := g.getGuideRank(cust, gid)
			r2 := g.getGuideRank(cust, oldGid)
			if r1 < r2 {
				g.guideMatch[gid] = cid
				g.custMatch[cid] = gid
				delete(g.guideMatch, oldGid)
				freeGuide = append(freeGuide, oldGid)
			} else {
				freeGuide = append(freeGuide, gid)
			}
		}
	}
	return g.custMatch
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:12
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : combine_rule.go
*/
package domain_rule

import (
	"BitOperation/domain/entity"
	"BitOperation/domain/valueobject"
)

// CombineDomainRule 首饰搭配领域约束规则
type CombineDomainRule struct {
	MAX_COMBINE_COUNT  int
	MIN_COMBINE_WEIGHT float64
	MUTEX_GOLD         int
	MUTEX_PLATINUM     int
}

func NewCombineDomainRule() *CombineDomainRule {
	return &CombineDomainRule{
		MAX_COMBINE_COUNT:  6,
		MIN_COMBINE_WEIGHT: 1.0,
		MUTEX_GOLD:         valueobject.GOLD,
		MUTEX_PLATINUM:     valueobject.PLATINUM,
	}
}

// IsSingleJewelValid 单件首饰校验
func (c *CombineDomainRule) IsSingleJewelValid(j *entity.Jewelry) (bool, string) {
	if j == nil {
		return false, "对象非首饰Jewelry实体"
	}
	if j.JewelID == "" {
		return false, "首饰唯一ID为空"
	}
	if j.Weight <= 0 {
		return false, "首饰[" + j.JewelID + "]克重非法,必须大于0"
	}
	if j.Price <= 0 {
		return false, "首饰[" + j.JewelID + "]价格非法,必须大于0"
	}
	return true, "单件首饰校验通过"
}

// CheckMaterialMutex 黄金铂金互斥校验
func (c *CombineDomainRule) CheckMaterialMutex(combineMask int) (bool, string) {
	hasGold := (combineMask & c.MUTEX_GOLD) != 0
	hasPt := (combineMask & c.MUTEX_PLATINUM) != 0
	if hasGold && hasPt {
		return false, "搭配组合违反规则:黄金与铂金禁止放入同一礼盒"
	}
	return true, "材质互斥校验通过"
}

// CheckCombineThreshold 重量价格阈值校验
func (c *CombineDomainRule) CheckCombineThreshold(totalW, totalP, maxW, maxP float64) (bool, string) {
	if totalW < c.MIN_COMBINE_WEIGHT {
		return false, "总克重低于礼盒最低克重1.0g"
	}
	if totalW > maxW {
		return false, "总克重超出上限"
	}
	if totalP > maxP {
		return false, "总价超出价格上限"
	}
	return true, "搭配阈值校验通过"
}

// CheckCombineCount 件数上限
func (c *CombineDomainRule) CheckCombineCount(cnt int) (bool, string) {
	if cnt > c.MAX_COMBINE_COUNT {
		return false, "搭配件数超出礼盒最大件数6件"
	}
	return true, "件数校验通过"
}

// BatchFilterAvailableJewels 批量过滤合法首饰
func (c *CombineDomainRule) BatchFilterAvailableJewels(list []*entity.Jewelry) ([]*entity.Jewelry, []string) {
	var valid []*entity.Jewelry
	var errLog []string
	for _, j := range list {
		ok, msg := c.IsSingleJewelValid(j)
		if ok {
			valid = append(valid, j)
		} else {
			errLog = append(errLog, msg)
		}
	}
	return valid, errLog
}

// FullCombineCheck 组合全量综合校验
func (c *CombineDomainRule) FullCombineCheck(mask int, jewels []*entity.Jewelry, totalW, totalP, maxW, maxP float64) (bool, string) {
	ok, msg := c.CheckCombineCount(len(jewels))
	if !ok {
		return false, msg
	}
	ok, msg = c.CheckMaterialMutex(mask)
	if !ok {
		return false, msg
	}
	ok, msg = c.CheckCombineThreshold(totalW, totalP, maxW, maxP)
	if !ok {
		return false, msg
	}
	return true, "搭配组合完全合规"
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:11
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : match_rule.go
*/
package domain_rule

import (
	"BitOperation/domain/entity"
	"BitOperation/domain/valueobject"
)

// 包内常量:固定全局掩码标识,编译期常量,合法标准写法
const (
	GUIDE_OFFLINE_MASK  = 1 << 30
	CUSTOMER_BLACK_MASK = 1 << 31
	SENIOR_GUIDE_TAG    = 1 << 28
)

// MatchDomainRule 导购-客户匹配领域规则结构体,仅保留运行期赋值字段
type MatchDomainRule struct {
	LUXURY_MASK int // 高奢组合掩码,构造函数内组合赋值
}

// NewMatchDomainRule 构造函数:统一初始化组合掩码
func NewMatchDomainRule() *MatchDomainRule {
	return &MatchDomainRule{
		LUXURY_MASK: valueobject.HIGHPRICE | valueobject.DIAMOND,
	}
}

// IsGuideValid 导购合法性校验
func (m *MatchDomainRule) IsGuideValid(g *entity.Guide) (bool, string) {
	if g == nil {
		return false, "实体类型错误,非导购Guide对象"
	}
	if g.GuideID == "" {
		return false, "导购ID不能为空"
	}
	if len(g.CustomerPriority) == 0 {
		return false, "导购未配置客户接待优先级列表,无法参与匹配"
	}
	if (g.SkillMask & GUIDE_OFFLINE_MASK) != 0 {
		return false, "导购[" + g.GuideID + "]当前离岗,禁止分配客户"
	}
	return true, "导购校验通过"
}

// IsCustomerValid 客户合法性校验
func (m *MatchDomainRule) IsCustomerValid(c *entity.Customer) (bool, string) {
	if c == nil {
		return false, "实体类型错误,非客户Customer对象"
	}
	if c.CustomerID == "" {
		return false, "客户ID不能为空"
	}
	if len(c.PriorityList) == 0 {
		return false, "客户未配置导购偏好优先级,无法参与匹配"
	}
	if (c.PreferenceMask & CUSTOMER_BLACK_MASK) != 0 {
		return false, "客户[" + c.CustomerID + "]处于黑名单,禁止分配导购接待"
	}
	return true, "客户校验通过"
}

// CheckLuxuryMatchLimit 高奢导购资质校验
func (m *MatchDomainRule) CheckLuxuryMatchLimit(g *entity.Guide, c *entity.Customer) (bool, string) {
	needLuxury := (c.PreferenceMask & m.LUXURY_MASK) != 0
	if !needLuxury {
		return true, "非高奢需求,无导购等级限制"
	}
	if (g.SkillMask & SENIOR_GUIDE_TAG) == 0 {
		return false, "客户[" + c.CustomerID + "]存在高奢需求,导购[" + g.GuideID + "]非资深导购,禁止匹配"
	}
	return true, "高奢需求匹配资格校验通过"
}

// BatchCheckMatchEntrance 批量准入过滤
func (m *MatchDomainRule) BatchCheckMatchEntrance(guides []*entity.Guide, customers []*entity.Customer) ([]*entity.Guide, []*entity.Customer, []string) {
	var validGuide []*entity.Guide
	var validCust []*entity.Customer
	var errLog []string

	for _, g := range guides {
		ok, msg := m.IsGuideValid(g)
		if ok {
			validGuide = append(validGuide, g)
		} else {
			errLog = append(errLog, "导购过滤:"+msg)
		}
	}
	for _, c := range customers {
		ok, msg := m.IsCustomerValid(c)
		if ok {
			validCust = append(validCust, c)
		} else {
			errLog = append(errLog, "客户过滤:"+msg)
		}
	}
	return validGuide, validCust, errLog
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:14
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : blacklist.go
*/
package entity

import "sync"

// BlackList 假货黑名单实体
type BlackList struct {
	fakeIds map[string]bool
	mu      sync.RWMutex
}

func NewBlackList() *BlackList {
	return &BlackList{
		fakeIds: make(map[string]bool),
	}
}

func (b *BlackList) AddFake(id string) {
	b.mu.Lock()
	defer b.mu.Unlock()
	b.fakeIds[id] = true
}

func (b *BlackList) BatchAdd(ids []string) {
	b.mu.Lock()
	defer b.mu.Unlock()
	for _, id := range ids {
		b.fakeIds[id] = true
	}
}

func (b *BlackList) IsFake(id string) bool {
	b.mu.RLock()
	defer b.mu.RUnlock()
	return b.fakeIds[id]
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:08
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : customer.go
*/
package entity

// Customer 客户领域实体
type Customer struct {
	CustomerID     string
	PreferenceMask int
	PriorityList   []string // 导购偏好优先级列表
}

// MatchScore 计算与导购技能掩码匹配重合bit数量
func (c *Customer) MatchScore(guideMask int) int {
	sameBit := c.PreferenceMask & guideMask
	cnt := 0
	for sameBit > 0 {
		cnt++
		sameBit &= sameBit - 1
	}
	return cnt
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:13
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : guide.go
*/
package entity

// Guide 导购领域实体
type Guide struct {
	GuideID          string
	SkillMask        int
	CustomerPriority []string // 接待客户优先级
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:13
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : jewelry.go
*/
package entity

// Jewelry 首饰实体
type Jewelry struct {
	JewelID  string
	Mask     int
	Weight   float64
	Price    float64
	GroupTag int
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:07
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : bit_mask.go
*/
package valueobject

// 材质、风格、价位 位掩码常量
const (
	// 材质掩码
	GOLD     = 1 << 0
	KGOLD    = 1 << 1
	PLATINUM = 1 << 2
	DIAMOND  = 1 << 3
	JADE     = 1 << 4
	PEARL    = 1 << 5
	RUBY     = 1 << 6
	SAPPHIRE = 1 << 7

	// 风格掩码
	LUXURY     = 1 << 10
	SIMPLE     = 1 << 11
	RETRO      = 1 << 12
	MINIMALIST = 1 << 13

	// 价位档位
	LOWPRICE  = 1 << 20
	MIDPRICE  = 1 << 21
	HIGHPRICE = 1 << 22
)

// BitMaskHelper 辅助结构体,承载材质/价位等掩码常量,供上层以字段形式访问 mask.DIAMOND 等
type BitMaskHelper struct {
	GOLD      int
	KGOLD     int
	PLATINUM  int
	DIAMOND   int
	JADE      int
	PEARL     int
	HIGHPRICE int
}

func NewPreferenceBitMask() *BitMaskHelper {
	return &BitMaskHelper{
		GOLD:      GOLD,
		KGOLD:     KGOLD,
		PLATINUM:  PLATINUM,
		DIAMOND:   DIAMOND,
		JADE:      JADE,
		PEARL:     PEARL,
		HIGHPRICE: HIGHPRICE,
	}
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:06
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : bit_helper.go
*/
package commonutil

// BitHelper 底层通用位运算工具,基础设施原子能力
type BitHelper struct{}

// AddMask 或运算添加标记
func (bh *BitHelper) AddMask(source, mask int) int {
	return source | mask
}

// RemoveMask 清除指定标记
func (bh *BitHelper) RemoveMask(source, mask int) int {
	return source & (^mask)
}

// HasMask 判断是否包含完整掩码
func (bh *BitHelper) HasMask(source, mask int) bool {
	return (source & mask) == mask
}

// HasAnyMask 包含任意一个掩码
func (bh *BitHelper) HasAnyMask(source int, maskList []int) bool {
	unionMask := 0
	for _, m := range maskList {
		unionMask |= m
	}
	return (source & unionMask) > 0
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:07
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : base_storage.go
*/
package storage

// BaseStorage 仓储顶层抽象接口,依赖倒置
type BaseStorage interface {
	Save(key interface{}, value interface{})
	Get(key interface{}) interface{}
	BatchSave(dataMap map[interface{}]interface{})
	BatchExistCheck(keys []interface{}) []bool
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:07
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : memory_storage.go
*/
package storage

// MemoryStorage 内存存储实现
type MemoryStorage struct {
	dataMap map[interface{}]interface{}
}

func NewMemoryStorage() *MemoryStorage {
	return &MemoryStorage{
		dataMap: make(map[interface{}]interface{}),
	}
}

func (m *MemoryStorage) Save(key interface{}, value interface{}) {
	m.dataMap[key] = value
}

func (m *MemoryStorage) Get(key interface{}) interface{} {
	return m.dataMap[key]
}

func (m *MemoryStorage) BatchSave(dataMap map[interface{}]interface{}) {
	for k, v := range dataMap {
		m.dataMap[k] = v
	}
}

func (m *MemoryStorage) BatchExistCheck(keys []interface{}) []bool {
	res := make([]bool, len(keys))
	for i, k := range keys {
		_, ok := m.dataMap[k]
		res[i] = ok
	}
	return res
}

  

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:20
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : combine_api.go
*/
package api

import (
	"BitOperation/application"
	"BitOperation/domain/entity"
)

var combineService = application.NewJewelryCombineAppService()

func ApiGetJewelryCombine(list []*entity.Jewelry, maxW, maxP float64) application.CombineResult {
	return combineService.GetBestCombine(list, maxW, maxP)
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:21
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : inventory_filter_api.go
*/
package api

import "BitOperation/application"

func ApiCreateFilterService(maxSize int) *application.InventoryFilterAppService {
	return application.NewInventoryFilterAppService(maxSize)
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:20
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : match_api.go
*/
package api

import (
	"BitOperation/application"
	"BitOperation/domain/entity"
)

var matchService = application.NewGuideCustomerMatchAppService()

func ApiMatchGuideCustomer(guides []*entity.Guide, customers []*entity.Customer) application.MatchResult {
	return matchService.DoMatch(guides, customers)
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:18
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : combine_app_service.go
*/
package application

import (
	"BitOperation/domain/algorithm"
	"BitOperation/domain/domain_rule"
	"BitOperation/domain/entity"
)

type CombineResult struct {
	Code        int      `json:"code"`
	Msg         string   `json:"msg"`
	FilterError []string `json:"filter_error"`
	SelectIds   []string `json:"select_jewel_ids"`
	TotalWeight float64  `json:"total_weight"`
	TotalPrice  float64  `json:"total_price"`
}

type JewelryCombineAppService struct {
	rule *domain_rule.CombineDomainRule
}

func NewJewelryCombineAppService() *JewelryCombineAppService {
	return &JewelryCombineAppService{
		rule: domain_rule.NewCombineDomainRule(),
	}
}

func (j *JewelryCombineAppService) GetBestCombine(jewelList []*entity.Jewelry, maxW, maxP float64) CombineResult {
	validList, errLog := j.rule.BatchFilterAvailableJewels(jewelList)
	if len(validList) == 0 {
		return CombineResult{
			Code:        -1,
			Msg:         "无合法首饰可搭配",
			FilterError: errLog,
			SelectIds:   []string{},
		}
	}
	combiner := algorithm.NewBfsJewelryCombiner(validList, maxW, maxP)
	ids, w, p := combiner.SearchBestCombine()
	// 组装掩码
	combineMask := 0
	var selectObjs []*entity.Jewelry
	idMap := make(map[string]*entity.Jewelry)
	for _, obj := range validList {
		idMap[obj.JewelID] = obj
	}
	for _, id := range ids {
		obj := idMap[id]
		combineMask |= obj.Mask
		selectObjs = append(selectObjs, obj)
	}
	ok, msg := j.rule.FullCombineCheck(combineMask, selectObjs, w, p, maxW, maxP)
	code := 0
	if !ok {
		code = -2
	}
	return CombineResult{
		Code:        code,
		Msg:         msg,
		FilterError: errLog,
		SelectIds:   ids,
		TotalWeight: w,
		TotalPrice:  p,
	}
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:18
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : inventory_app_service.go
*/
package application

import (
	"BitOperation/domain/algorithm"
	"BitOperation/domain/entity"
)

type InventoryFilterAppService struct {
	bitArr     *algorithm.BitArray
	blackList  *entity.BlackList
	idIndexMap map[string]int
	indexIdMap map[int]string
}

func NewInventoryFilterAppService(maxSize int) *InventoryFilterAppService {
	return &InventoryFilterAppService{
		bitArr:     algorithm.NewBitArray(maxSize),
		blackList:  entity.NewBlackList(),
		idIndexMap: make(map[string]int),
		indexIdMap: make(map[int]string),
	}
}

func (i *InventoryFilterAppService) RegisterIndex(jid string, idx int) {
	i.idIndexMap[jid] = idx
	i.indexIdMap[idx] = jid
}

func (i *InventoryFilterAppService) BatchMarkInventory(idList []string) {
	var idxList []int
	for _, id := range idList {
		if idx, ok := i.idIndexMap[id]; ok {
			idxList = append(idxList, idx)
		}
	}
	i.bitArr.BatchSet(idxList)
}

func (i *InventoryFilterAppService) CheckRepeat(checkIds []string) [][2]interface{} {
	res := make([][2]interface{}, 0, len(checkIds))
	for _, id := range checkIds {
		idx, ok := i.idIndexMap[id]
		exist := false
		if ok {
			exist = i.bitArr.Get(idx)
		}
		res = append(res, [2]interface{}{id, exist})
	}
	return res
}

func (i *InventoryFilterAppService) FilterBlackList(checkIds []string) []string {
	var safe []string
	for _, id := range checkIds {
		if !i.blackList.IsFake(id) {
			safe = append(safe, id)
		}
	}
	return safe
}

// MarkBlack 将指定商品ID加入假货黑名单
func (i *InventoryFilterAppService) MarkBlack(id string) {
	i.blackList.AddFake(id)
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:16
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : match_app_service.go
*/
package application

import (
	"BitOperation/domain/algorithm"
	"BitOperation/domain/domain_rule"
	"BitOperation/domain/entity"
)

type MatchResult struct {
	Code      int               `json:"code"`
	Msg       string            `json:"msg"`
	ErrorLog  []string          `json:"error_log"`
	MatchData map[string]string `json:"match_data"`
}

// GuideCustomerMatchAppService 导购客户匹配应用服务
type GuideCustomerMatchAppService struct {
	rule *domain_rule.MatchDomainRule
}

func NewGuideCustomerMatchAppService() *GuideCustomerMatchAppService {
	return &GuideCustomerMatchAppService{
		rule: domain_rule.NewMatchDomainRule(),
	}
}

func (g *GuideCustomerMatchAppService) DoMatch(guides []*entity.Guide, customers []*entity.Customer) MatchResult {
	validG, validC, errLog := g.rule.BatchCheckMatchEntrance(guides, customers)
	if len(validG) == 0 || len(validC) == 0 {
		return MatchResult{
			Code:      -1,
			Msg:       "无合法导购/客户,匹配终止",
			ErrorLog:  errLog,
			MatchData: make(map[string]string),
		}
	}
	matcher := algorithm.NewGaleShapleyMatcher(validG, validC)
	data := matcher.Match()
	return MatchResult{
		Code:      0,
		Msg:       "匹配成功",
		ErrorLog:  errLog,
		MatchData: data,
	}
}

  

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/8/4 23:06
# User      :  geovindu
# Product   : GoLand
# Project   : BitOperation
# File      : main.go
*/

package main

import (
	"BitOperation/api"
	"BitOperation/domain/domain_rule"
	"BitOperation/domain/entity"
	"BitOperation/domain/valueobject"
	"fmt"
)

//TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>

func main() {
	mask := valueobject.NewPreferenceBitMask()
	fmt.Println("===导购客户稳定匹配结果(带规则校验)===")
	// 构造离岗导购、资深导购
	g1 := &entity.Guide{
		GuideID:          "G001",
		SkillMask:        mask.DIAMOND | mask.GOLD | domain_rule.GUIDE_OFFLINE_MASK,
		CustomerPriority: []string{"C001", "C002"},
	}
	g2 := &entity.Guide{
		GuideID:          "G002",
		SkillMask:        mask.JADE | mask.PEARL | domain_rule.SENIOR_GUIDE_TAG,
		CustomerPriority: []string{"C002", "C001"},
	}
	c1 := &entity.Customer{
		CustomerID:     "C001",
		PreferenceMask: mask.DIAMOND | mask.HIGHPRICE,
		PriorityList:   []string{"G001", "G002"},
	}
	c2 := &entity.Customer{
		CustomerID:     "C002",
		PreferenceMask: mask.JADE,
		PriorityList:   []string{"G002", "G001"},
	}
	matchRes := api.ApiMatchGuideCustomer([]*entity.Guide{g1, g2}, []*entity.Customer{c1, c2})
	fmt.Printf("code:%d, msg:%s\n", matchRes.Code, matchRes.Msg)
	fmt.Println("errorLog:", matchRes.ErrorLog)
	fmt.Println("match_data:", matchRes.MatchData)

	fmt.Println("\n===首饰最优搭配(互斥规则校验)===")
	jewels := []*entity.Jewelry{
		{JewelID: "J001", Mask: mask.GOLD, Weight: 2.2, Price: 1280},
		{JewelID: "J002", Mask: mask.PLATINUM, Weight: 1.5, Price: 2680},
		{JewelID: "J003", Mask: mask.PEARL, Weight: 1.1, Price: 890},
		{JewelID: "J004", Mask: mask.KGOLD, Weight: 2.8, Price: 1660},
	}
	comRes := api.ApiGetJewelryCombine(jewels, 5.0, 4000)
	fmt.Printf("code:%d, msg:%s\n", comRes.Code, comRes.Msg)
	fmt.Println("select_jewel_ids:", comRes.SelectIds)
	fmt.Printf("total_weight:%.2f, total_price:%.2f\n", comRes.TotalWeight, comRes.TotalPrice)

	fmt.Println("\n===库存查重、黑名单过滤===")
	filter := api.ApiCreateFilterService(10000000)
	filter.RegisterIndex("J001", 1)
	filter.RegisterIndex("J002", 2)
	filter.BatchMarkInventory([]string{"J001", "J002"})
	repeat := filter.CheckRepeat([]string{"J001", "J005"})
	fmt.Println("查重结果:", repeat)
	filter.MarkBlack("J999")
	safe := filter.FilterBlackList([]string{"J001", "J999"})
	fmt.Println("合法商品列表:", safe)
}

  

输出:

image

 

posted @ 2026-08-04 23:42  ®Geovin Du Dream Park™  阅读(2)  评论(0)    收藏  举报