Go
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Enumeration 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/15 20:57
# User : geovindu
# Product : GoLand
# Project : goalgorithms
# File : enumeration.go
*/
package enumeration
import (
"fmt"
"sort"
"strings"
)
// Jewelry 珠宝商品结构体
type Jewelry struct {
JID string // 商品编号
Category string // 品类:项链/戒指/手镯/耳饰
Material string // 材质:黄金/铂金/钻石/K金/银饰
Price float64 // 售价
Stock int // 库存
Sales int // 销量
SceneTags []string // 适用场景:婚嫁/日常/送礼
}
// String 格式化输出,和Python __repr__ 保持一致
func (j Jewelry) String() string {
scenes := strings.Join(j.SceneTags, ",")
return fmt.Sprintf("【%s】%s | %s | 售价:%.0f元 | 库存:%d件 | 销量:%d | 适用场景:%s",
j.JID, j.Category, j.Material, j.Price, j.Stock, j.Sales, scenes)
}
// RecommendItem 带评分的候选商品
type RecommendItem struct {
Score int
Goods Jewelry
}
// Combo 套装组合:项链+戒指
type Combo struct {
Necklace Jewelry
Ring Jewelry
Total float64
}
// EnumerateFilter 枚举全商品,多条件过滤并打分排序
// maxBudget 最高预算, targetMaterial 指定材质, targetCategory 指定品类, targetScene 指定场景
func EnumerateFilter(goodsList []Jewelry, maxBudget float64, targetMaterial, targetCategory, targetScene string) (mainList []Jewelry, upgradeList []Jewelry) {
var candidates []RecommendItem
// 枚举全部商品(枚举算法核心)
for _, item := range goodsList {
// 约束1:无库存直接跳过
if item.Stock < 1 {
continue
}
// 约束2:超出预算120%直接过滤
if item.Price > maxBudget*1.2 {
continue
}
// 约束3:材质匹配(非空才校验)
if targetMaterial != "" && item.Material != targetMaterial {
continue
}
// 约束4:品类匹配(非空才校验)
if targetCategory != "" && item.Category != targetCategory {
continue
}
// 开始计算推荐得分
score := 0
priceRatio := item.Price / maxBudget
// 价格分:预算70%-90%最优
if priceRatio >= 0.7 && priceRatio <= 0.9 {
score += 50
} else if priceRatio <= 1.0 {
score += 30
} else {
score += 10 // 小幅超预算升级款
}
// 场景匹配加分
if targetScene != "" {
for _, s := range item.SceneTags {
if s == targetScene {
score += 30
break
}
}
}
// 销量加分,上限20分
saleScore := item.Sales / 10
if saleScore > 20 {
saleScore = 20
}
score += saleScore
candidates = append(candidates, RecommendItem{
Score: score,
Goods: item,
})
}
// 按分数降序排序
sort.Slice(candidates, func(i, j int) bool {
return candidates[i].Score > candidates[j].Score
})
// 拆分主推款(预算内)、升级款(小幅超预算)
for _, c := range candidates {
if c.Goods.Price <= maxBudget {
mainList = append(mainList, c.Goods)
} else {
upgradeList = append(upgradeList, c.Goods)
}
}
return mainList, upgradeList
}
// EnumerateCombo 枚举项链+戒指成套组合,总价不超预算
func EnumerateCombo(goodsList []Jewelry, totalBudget float64) []Combo {
var combos []Combo
// 筛选项链、戒指
var necklaces []Jewelry
var rings []Jewelry
for _, g := range goodsList {
if g.Stock < 1 {
continue
}
if g.Category == "项链" {
necklaces = append(necklaces, g)
}
if g.Category == "戒指" {
rings = append(rings, g)
}
}
// 双层枚举所有搭配组合
for _, n := range necklaces {
for _, r := range rings {
sum := n.Price + r.Price
if sum <= totalBudget {
combos = append(combos, Combo{
Necklace: n,
Ring: r,
Total: sum,
})
}
}
}
return combos
}
// InitStoreData 初始化门店珠宝库存数据
func InitStoreData() []Jewelry {
return []Jewelry{
{
JID: "N001",
Category: "项链",
Material: "黄金",
Price: 5280,
Stock: 12,
Sales: 120,
SceneTags: []string{"婚嫁", "送礼"},
},
{
JID: "N002",
Category: "项链",
Material: "铂金",
Price: 7600,
Stock: 3,
Sales: 60,
SceneTags: []string{"求婚", "日常"},
},
{
JID: "N003",
Category: "项链",
Material: "钻石",
Price: 12800,
Stock: 5,
Sales: 45,
SceneTags: []string{"纪念日"},
},
{
JID: "N004",
Category: "项链",
Material: "K金",
Price: 3680,
Stock: 8,
Sales: 150,
SceneTags: []string{"日常"},
},
{
JID: "R001",
Category: "戒指",
Material: "黄金",
Price: 2150,
Stock: 15,
Sales: 200,
SceneTags: []string{"日常", "婚嫁"},
},
{
JID: "R002",
Category: "戒指",
Material: "钻石",
Price: 9999,
Stock: 2,
Sales: 88,
SceneTags: []string{"求婚"},
},
{
JID: "R003",
Category: "戒指",
Material: "银饰",
Price: 599,
Stock: 30,
Sales: 320,
SceneTags: []string{"日常"},
},
{
JID: "B001",
Category: "手镯",
Material: "黄金",
Price: 8600,
Stock: 4,
Sales: 80,
SceneTags: []string{"婚嫁", "送礼"},
},
{
JID: "B002",
Category: "手镯",
Material: "银饰",
Price: 1280,
Stock: 22,
Sales: 260,
SceneTags: []string{"日常"},
},
{
JID: "E001",
Category: "耳饰",
Material: "K金",
Price: 1680,
Stock: 18,
Sales: 190,
SceneTags: []string{"日常", "纪念日"},
},
{
JID: "E002",
Category: "耳饰",
Material: "铂金",
Price: 4200,
Stock: 6,
Sales: 72,
SceneTags: []string{"求婚"},
},
{
JID: "E003",
Category: "耳饰",
Material: "钻石",
Price: 6500,
Stock: 0, // 无库存过滤
Sales: 30,
SceneTags: []string{"纪念日"},
},
}
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Enumeration 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/15 20:58
# User : geovindu
# Product : GoLand
# Project : goalgorithms
# File : enumerationbll.go
*/
package bll
import (
"fmt"
"goalgorithms/enumeration"
"strings"
)
func EnumerationMain() {
allJewelry := enumeration.InitStoreData()
// 1. 打印全店所有商品
fmt.Println("===== 珠宝门店全部商品(枚举全集) =====")
for _, item := range allJewelry {
fmt.Println(item)
}
fmt.Println(strings.Repeat("-", 90))
// 场景1:预算6000,不限材质、不限品类、不限场景
fmt.Println("\n【顾客需求1】预算≤6000元,任意品类任意材质,有库存")
main1, up1 := enumeration.EnumerateFilter(allJewelry, 6000, "", "", "")
if len(main1) == 0 {
fmt.Println("无符合条件首饰")
} else {
for _, g := range main1 {
fmt.Println(g)
}
}
// 场景2:预算10000,材质黄金,品类手镯,场景婚嫁
fmt.Println("\n【顾客需求2】预算≤10000元,仅黄金手镯,婚嫁场景")
main2, up2 := enumeration.EnumerateFilter(allJewelry, 10000, "黄金", "手镯", "婚嫁")
if len(main2) == 0 {
fmt.Println("无符合条件首饰")
} else {
for _, g := range main2 {
fmt.Println(g)
}
}
if len(up2) > 0 {
fmt.Println("\n [升级备选款]")
for _, g := range up2 {
fmt.Println(g)
}
}
// 场景3:预算5000,铂金、耳饰、求婚场景
fmt.Println("\n【顾客需求3】预算≤5000元,铂金耳饰,求婚场景")
main3, up3 := enumeration.EnumerateFilter(allJewelry, 5000, "铂金", "耳饰", "求婚")
if len(main3) == 0 {
fmt.Println("无符合条件首饰")
} else {
for _, g := range main3 {
fmt.Println(g)
}
}
if len(up3) > 0 {
fmt.Println("\n [升级备选款]")
for _, g := range up3 {
fmt.Println(g)
}
}
// 场景4:预算8000,钻石戒指,求婚场景(无匹配)
fmt.Println("\n【顾客需求4】预算≤8000元,钻石戒指,求婚场景")
main4, up4 := enumeration.EnumerateFilter(allJewelry, 8000, "钻石", "戒指", "求婚")
if len(main4) == 0 {
fmt.Println("无符合条件首饰")
} else {
for _, g := range main4 {
fmt.Println(g)
}
}
if len(up4) > 0 {
fmt.Println("\n [升级备选款]")
for _, g := range up4 {
fmt.Println(g)
}
}
if len(main4) == 0 && len(up4) == 0 {
fmt.Println("无匹配首饰")
}
// 打印小幅超预算升级款示例
fmt.Println("\n【升级备选款示例(预算6000)】")
for _, g := range up1 {
fmt.Println(g)
}
// 枚举配套组合:项链+戒指,总价≤10000
fmt.Println("\n===== 项链+戒指组合套装(总价≤10000元) =====")
comboList := enumeration.EnumerateCombo(allJewelry, 10000)
if len(comboList) == 0 {
fmt.Println("无可用套装")
} else {
for _, c := range comboList {
fmt.Printf("套装组合:\n %s\n %s\n 合计总价:%.0f元\n", c.Necklace, c.Ring, c.Total)
fmt.Println("----------------------------------------")
}
}
}
代码实现了一个珠宝商品推荐系统,主要包含两个核心功能:
-
单品推荐算法:根据预算、材质、品类和场景等多条件筛选珠宝商品,并基于价格匹配度、销量和场景适用性进行智能评分排序,输出预算内主推款和超预算升级款。
-
套装组合算法:枚举所有项链+戒指的组合,筛选总价不超过预算的可行搭配方案。系统还包含完整的珠宝商品数据结构(含ID、品类、材质、价格等属性)和初始化数据方法,支持格式化输出商品信息。通过条件过滤和智能推荐算法,帮助用户快速找到符合需求的珠宝商品或套装组合。
输出:
