go:Backtracking Algorithm
项目结构/* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:03 # User : geovindu # Product : GoLand # Project : goalgorithms # File : bead.go */ package dto // BeadItem 多宝手串珠子实体 type BeadItem struct { BeadID string Name string Material string ColorGroup string // red/green/purple/gold UnitPrice float64 Stock int } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:03 # User : geovindu # Product : GoLand # Project : goalgorithms # File : jewelry.go */ package dto // JewelryItem 成套首饰商品 type JewelryItem struct { SkuID string Name string Category string // necklace / earring / bracelet / ring Material string // Au999 / 18K / S925 Color string Style string Price float64 Stock int HasGem bool } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:04 # User : geovindu # Product : GoLand # Project : goalgorithms # File : bracelet_rule.go */ package rule import goalgorithms/backtracking/dto // BraceletRule 手串搭配约束 type BraceletRule struct { MaxSingleColor int } func (r *BraceletRule) Check(item dto.BeadItem, path []dto.BeadItem) bool { // 1.库存校验 used : 0 for _, p : range path { if p.BeadID item.BeadID { used } } if used item.Stock { return false } // 2.色系均衡限制 colorCnt : make(map[string]int) for _, b : range path { colorCnt[b.ColorGroup] } if colorCnt[item.ColorGroup] r.MaxSingleColor { return false } return true } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:04 # User : geovindu # Product : GoLand # Project : goalgorithms # File : scene_jewelry_rule.go */ package rule import goalgorithms/backtracking/dto // SceneConfig 场景配置 type SceneConfig struct { AllowMaterial map[string]bool MustGem bool } // SceneJewelryRule 场景首饰规则 type SceneJewelryRule struct { conf SceneConfig } func NewSceneJewelryRule(conf SceneConfig) *SceneJewelryRule { return SceneJewelryRule{conf: conf} } func (r *SceneJewelryRule) Check(item dto.JewelryItem, path []dto.JewelryItem) bool { if item.Stock 0 { return false } if !r.conf.AllowMaterial[item.Material] { return false } if r.conf.MustGem !item.HasGem { return false } return true } // GetSceneConfig 场景配置中心新增场景只在这里扩展 func GetSceneConfig(sceneType string) SceneConfig { sceneMap : map[string]SceneConfig{ wedding: { AllowMaterial: map[string]bool{Au999: true, 18K: true}, MustGem: true, }, commute: { AllowMaterial: map[string]bool{Au999: true, S925: true, 18K: true}, MustGem: false, }, dinner: { AllowMaterial: map[string]bool{18K: true}, MustGem: true, }, } cfg, ok : sceneMap[sceneType] if !ok { return sceneMap[commute] } return cfg } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:05 # User : geovindu # Product : GoLand # Project : goalgorithms # File : score_util.go */ package common import goalgorithms/backtracking/dto // ScoreBraceletScheme 手串方案评分 func ScoreBraceletScheme(scheme []dto.BeadItem) float64 { colorSet : make(map[string]bool) var totalCost float64 for _, b : range scheme { colorSet[b.ColorGroup] true totalCost b.UnitPrice } diversity : float64(len(colorSet)) return diversity*10 - totalCost/200 } // ScoreJewelryScheme 成套首饰方案评分 func ScoreJewelryScheme(scheme []dto.JewelryItem) float64 { gemCnt : 0 stockScore : 0 for _, item : range scheme { if item.HasGem { gemCnt } if item.Stock 5 { stockScore item.Stock } else { stockScore 5 } } return float64(gemCnt*5 stockScore) } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:05 # User : geovindu # Product : GoLand # Project : goalgorithms # File : backtrack_bracelet.go */ package core import ( goalgorithms/backtracking/dto goalgorithms/backtracking/rule ) // BraceletBackTracker 手串回溯器 type BraceletBackTracker struct { beadPool []dto.BeadItem rule *rule.BraceletRule solutions [][]dto.BeadItem } func NewBraceletBackTracker(pool []dto.BeadItem, r *rule.BraceletRule) *BraceletBackTracker { return BraceletBackTracker{ beadPool: pool, rule: r, } } func (bt *BraceletBackTracker) backtrack(path []dto.BeadItem, remain int, totalCost float64, budget float64) { if remain 0 { cp : make([]dto.BeadItem, len(path)) copy(cp, path) bt.solutions append(bt.solutions, cp) return } if totalCost budget { return } for _, bead : range bt.beadPool { if !bt.rule.Check(bead, path) { continue } path append(path, bead) bt.backtrack(path, remain-1, totalCostbead.UnitPrice, budget) path path[:len(path)-1] } } func (bt *BraceletBackTracker) Run(targetCount int, budget float64) [][]dto.BeadItem { bt.solutions make([][]dto.BeadItem, 0) bt.backtrack([]dto.BeadItem{}, targetCount, 0.0, budget) return bt.solutions } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:06 # User : geovindu # Product : GoLand # Project : goalgorithms # File : backtrack_jewelry.go */ package core import ( goalgorithms/backtracking/dto goalgorithms/backtracking/rule ) // JewelrySceneBackTracker 首饰成套回溯器 type JewelrySceneBackTracker struct { goodsPool []dto.JewelryItem rule *rule.SceneJewelryRule solutions [][]dto.JewelryItem } func NewJewelrySceneBackTracker(pool []dto.JewelryItem, r *rule.SceneJewelryRule) *JewelrySceneBackTracker { return JewelrySceneBackTracker{ goodsPool: pool, rule: r, } } func (bt *JewelrySceneBackTracker) backtrack(startIdx int, selected []dto.JewelryItem, totalPrice float64, budget float64, targetCategories map[string]bool) { // 判断是否集齐目标品类 selectedCats : make(map[string]bool) for _, item : range selected { selectedCats[item.Category] true } complete : true for cat : range targetCategories { if !selectedCats[cat] { complete false break } } if complete { cp : make([]dto.JewelryItem, len(selected)) copy(cp, selected) bt.solutions append(bt.solutions, cp) return } if totalPrice budget { return } for i : startIdx; i len(bt.goodsPool); i { item : bt.goodsPool[i] if selectedCats[item.Category] { continue } if !bt.rule.Check(item, selected) { continue } selected append(selected, item) bt.backtrack(i1, selected, totalPriceitem.Price, budget, targetCategories) selected selected[:len(selected)-1] } } func (bt *JewelrySceneBackTracker) Run(budget float64, targetCategories map[string]bool) [][]dto.JewelryItem { bt.solutions make([][]dto.JewelryItem, 0) bt.backtrack(0, []dto.JewelryItem{}, 0.0, budget, targetCategories) return bt.solutions } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:06 # User : geovindu # Product : GoLand # Project : goalgorithms # File : bracelet_service.go */ package service import ( goalgorithms/backtracking/common goalgorithms/backtracking/core goalgorithms/backtracking/dto goalgorithms/backtracking/rule sort ) // BraceletMatchService 手串搭配业务服务 type BraceletMatchService struct { beadPool []dto.BeadItem } func NewBraceletMatchService(pool []dto.BeadItem) *BraceletMatchService { return BraceletMatchService{beadPool: pool} } func (svc *BraceletMatchService) Match(targetCount int, budget float64, maxColorLimit int, topN int) [][]dto.BeadItem { r : rule.BraceletRule{MaxSingleColor: maxColorLimit} tracker : core.NewBraceletBackTracker(svc.beadPool, r) schemes : tracker.Run(targetCount, budget) // 打分排序 sort.Slice(schemes, func(i, j int) bool { return common.ScoreBraceletScheme(schemes[i]) common.ScoreBraceletScheme(schemes[j]) }) if len(schemes) topN { schemes schemes[:topN] } return schemes } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:07 # User : geovindu # Product : GoLand # Project : goalgorithms # File : jewelry_scene_service.go */ package service import ( goalgorithms/backtracking/common goalgorithms/backtracking/core goalgorithms/backtracking/dto goalgorithms/backtracking/rule sort ) // JewelrySceneMatchService 场景首饰搭配服务 type JewelrySceneMatchService struct { goodsPool []dto.JewelryItem } func NewJewelrySceneMatchService(pool []dto.JewelryItem) *JewelrySceneMatchService { return JewelrySceneMatchService{goodsPool: pool} } func (svc *JewelrySceneMatchService) MatchByScene(scene string, budget float64, targetCategories map[string]bool, topN int) [][]dto.JewelryItem { cfg : rule.GetSceneConfig(scene) r : rule.NewSceneJewelryRule(cfg) tracker : core.NewJewelrySceneBackTracker(svc.goodsPool, r) schemes : tracker.Run(budget, targetCategories) sort.Slice(schemes, func(i, j int) bool { return common.ScoreJewelryScheme(schemes[i]) common.ScoreJewelryScheme(schemes[j]) }) if len(schemes) topN { schemes schemes[:topN] } return schemes }调用/* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Backtracking 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/7/23 7:07 # User : geovindu # Product : GoLand # Project : goalgorithms # File : backtrackingbll.go */ package bll import ( fmt goalgorithms/backtracking/dto goalgorithms/backtracking/service ) func testBraceletMatch() { beadPool : []dto.BeadItem{ {BeadID: B01, Name: 南红圆珠, Material: 南红, ColorGroup: red, UnitPrice: 168, Stock: 4}, {BeadID: B02, Name: 和田玉圆珠, Material: 和田玉, ColorGroup: green, UnitPrice: 198, Stock: 5}, {BeadID: B03, Name: 紫水晶, Material: 紫水晶, ColorGroup: purple, UnitPrice: 128, Stock: 4}, {BeadID: B04, Name: 足金隔珠, Material: 足金, ColorGroup: gold, UnitPrice: 320, Stock: 3}, } svc : service.NewBraceletMatchService(beadPool) result : svc.Match(8, 2000, 4, 6) fmt.Println( 多宝手串搭配方案 ) for idx, scheme : range result { var total float64 var names []string for _, b : range scheme { total b.UnitPrice names append(names, b.Name) } fmt.Printf(方案%d 总价:%.2f 珠子:%v\n, idx1, total, names) } } func testJewelrySceneMatch() { goodsPool : []dto.JewelryItem{ {SkuID: N001, Name: 碎钻项链, Category: necklace, Material: 18K, Color: white, Style: luxury, Price: 3299, Stock: 12, HasGem: true}, {SkuID: N003, Name: 素金项链, Category: necklace, Material: Au999, Color: yellow, Style: minimalist, Price: 2199, Stock: 9, HasGem: false}, {SkuID: E001, Name: 白钻耳饰, Category: earring, Material: 18K, Color: white, Style: luxury, Price: 2199, Stock: 15, HasGem: true}, {SkuID: E003, Name: 素金耳饰, Category: earring, Material: Au999, Color: yellow, Style: minimalist, Price: 1399, Stock: 11, HasGem: false}, } svc : service.NewJewelrySceneMatchService(goodsPool) targetCats : map[string]bool{necklace: true, earring: true} fmt.Println(\n 婚嫁场景 ) wedding : svc.MatchByScene(wedding, 8000, targetCats, 8) for _, set : range wedding { var names []string var total float64 for _, item : range set { names append(names, item.Name) total item.Price } fmt.Printf(%v 总价 %.2f\n, names, total) } fmt.Println(\n 通勤场景 ) commute : svc.MatchByScene(commute, 5000, targetCats, 8) for _, set : range commute { var names []string var total float64 for _, item : range set { names append(names, item.Name) total item.Price } fmt.Printf(%v 总价 %.2f\n, names, total) } } func BacktrackingMain() { testBraceletMatch() testJewelrySceneMatch() }介绍了一个基于回溯算法的珠宝搭配系统实现主要包含数据结构定义BeadItem手串珠子和JewelryItem成套首饰的实体结构规则引擎BraceletRule手串搭配约束和SceneJewelryRule场景首饰规则回溯算法核心分别实现了手串搭配和场景首饰搭配的回溯算法服务层提供BraceletMatchService和JewelrySceneMatchService业务服务评分系统根据颜色多样性、库存状况等指标对搭配方案进行评分排序系统支持特定场景婚嫁、通勤等的珠宝搭配推荐并考虑预算、库存等约束条件最终输出按评分排序的TopN推荐方案。输出