CSharp:Backtracking Algorithm
项目结构:

/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/10 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : BeadItem.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Dto
{
/// <summary>
/// 多宝手串珠子实体
/// </summary>
public class BeadItem
{
public string BeadId { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Material { get; set; } = string.Empty;
public string ColorGroup { get; set; } = string.Empty; // red/green/purple/gold
public double UnitPrice { get; set; }
public int Stock { get; set; }
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/10 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : JewelryItem.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Dto
{
/// <summary>
/// 成套首饰商品
/// </summary>
public class JewelryItem
{
public string SkuId { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty; // necklace / earring
public string Material { get; set; } = string.Empty;
public string Color { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
public double Price { get; set; }
public int Stock { get; set; }
public bool HasGem { get; set; }
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/10 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : IBaseRule.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Rule
{
/// <summary>
/// 规则抽象接口
/// </summary>
/// <typeparam name="T">物料类型 BeadItem / JewelryItem</typeparam>
public interface IBaseRule<T>
{
bool Check(T item, List<T> path);
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/10 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : BraceletRule.cs
*/
using CSharpAlgorithms.Backtracking.Dto;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Rule
{
public class BraceletRule : IBaseRule<BeadItem>
{
public int MaxSingleColor { get; }
public BraceletRule(int maxSingleColor)
{
MaxSingleColor = maxSingleColor;
}
public bool Check(BeadItem item, List<BeadItem> path)
{
// 库存校验
int used = path.Count(x => x.BeadId == item.BeadId);
if (used >= item.Stock)
return false;
// 色系均衡限制
Dictionary<string, int> colorCnt = new();
foreach (var b in path)
{
if (!colorCnt.ContainsKey(b.ColorGroup))
colorCnt[b.ColorGroup] = 0;
colorCnt[b.ColorGroup]++;
}
if (colorCnt.TryGetValue(item.ColorGroup, out var count) && count >= MaxSingleColor)
return false;
return true;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/10 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : SceneJewelryRule.cs
*/
using CSharpAlgorithms.Backtracking.Dto;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Rule
{
public class SceneConfig
{
public HashSet<string> AllowMaterial { get; set; } = new();
public bool MustGem { get; set; }
}
public class SceneJewelryRule : IBaseRule<JewelryItem>
{
private readonly SceneConfig _config;
public SceneJewelryRule(SceneConfig config)
{
_config = config;
}
public bool Check(JewelryItem item, List<JewelryItem> path)
{
if (item.Stock <= 0)
return false;
if (!_config.AllowMaterial.Contains(item.Material))
return false;
if (_config.MustGem && !item.HasGem)
return false;
return true;
}
/// <summary>
/// 场景配置中心,新增场景只在此扩展
/// </summary>
/// <param name="sceneType"></param>
/// <returns></returns>
public static SceneConfig GetSceneConfig(string sceneType)
{
var map = new Dictionary<string, SceneConfig>()
{
{
"wedding", new SceneConfig
{
AllowMaterial = new HashSet<string>{"Au999","18K"},
MustGem = true
}
},
{
"commute", new SceneConfig
{
AllowMaterial = new HashSet<string>{"Au999","S925","18K"},
MustGem = false
}
},
{
"dinner", new SceneConfig
{
AllowMaterial = new HashSet<string>{"18K"},
MustGem = true
}
}
};
if (map.TryGetValue(sceneType, out var cfg))
return cfg;
return map["commute"];
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/10 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : ScoreUtil.cs
*/
using CSharpAlgorithms.Backtracking.Dto;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Common
{
/// <summary>
///
/// </summary>
public static class ScoreUtil
{
/// <summary>
/// 手串方案评分:色系多样性优先
/// </summary>
public static double ScoreBraceletScheme(List<BeadItem> scheme)
{
HashSet<string> colorSet = new();
double totalCost = 0;
foreach (var b in scheme)
{
colorSet.Add(b.ColorGroup);
totalCost += b.UnitPrice;
}
double diversity = colorSet.Count;
return diversity * 10 - totalCost / 200;
}
/// <summary>
/// 成套首饰方案评分
/// </summary>
public static double ScoreJewelryScheme(List<JewelryItem> scheme)
{
int gemCnt = 0;
int stockScore = 0;
foreach (var item in scheme)
{
if (item.HasGem) gemCnt++;
stockScore += Math.Min(item.Stock, 5);
}
return gemCnt * 5 + stockScore;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/06 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : BraceletBackTracker.cs
*/
using CSharpAlgorithms.Backtracking.Dto;
using CSharpAlgorithms.Backtracking.Rule;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Core
{
public class BraceletBackTracker
{
private readonly List<BeadItem> _beadPool;
private readonly IBaseRule<BeadItem> _rule;
private readonly List<List<BeadItem>> _solutions = new();
public BraceletBackTracker(List<BeadItem> beadPool, IBaseRule<BeadItem> rule)
{
_beadPool = beadPool;
_rule = rule;
}
private void Backtrack(List<BeadItem> path, int remain, double totalCost, double budget)
{
if (remain == 0)
{
_solutions.Add(new List<BeadItem>(path));
return;
}
if (totalCost > budget)
return;
foreach (var bead in _beadPool)
{
if (!_rule.Check(bead, path))
continue;
path.Add(bead);
Backtrack(path, remain - 1, totalCost + bead.UnitPrice, budget);
path.RemoveAt(path.Count - 1);
}
}
public List<List<BeadItem>> Run(int targetCount, double budget)
{
_solutions.Clear();
Backtrack(new List<BeadItem>(), targetCount, 0.0, budget);
return _solutions;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/06 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : JewelrySceneBackTracker.cs
*/
using CSharpAlgorithms.Backtracking.Dto;
using CSharpAlgorithms.Backtracking.Rule;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Core
{
/// <summary>
///
/// </summary>
public class JewelrySceneBackTracker
{
private readonly List<JewelryItem> _goodsPool;
private readonly IBaseRule<JewelryItem> _rule;
private readonly List<List<JewelryItem>> _solutions = new();
/// <summary>
///
/// </summary>
/// <param name="goodsPool"></param>
/// <param name="rule"></param>
public JewelrySceneBackTracker(List<JewelryItem> goodsPool, IBaseRule<JewelryItem> rule)
{
_goodsPool = goodsPool;
_rule = rule;
}
/// <summary>
///
/// </summary>
/// <param name="startIdx"></param>
/// <param name="selected"></param>
/// <param name="totalPrice"></param>
/// <param name="budget"></param>
/// <param name="targetCategories"></param>
private void Backtrack(int startIdx, List<JewelryItem> selected, double totalPrice, double budget, HashSet<string> targetCategories)
{
HashSet<string> selectedCats = selected.Select(x => x.Category).ToHashSet();
// 是否集齐所有目标品类
bool complete = targetCategories.All(selectedCats.Contains);
if (complete)
{
_solutions.Add(new List<JewelryItem>(selected));
return;
}
if (totalPrice > budget)
return;
for (int i = startIdx; i < _goodsPool.Count; i++)
{
var item = _goodsPool[i];
if (selectedCats.Contains(item.Category))
continue;
if (!_rule.Check(item, selected))
continue;
selected.Add(item);
Backtrack(i + 1, selected, totalPrice + item.Price, budget, targetCategories);
selected.RemoveAt(selected.Count - 1);
}
}
/// <summary>
///
/// </summary>
/// <param name="budget"></param>
/// <param name="targetCategories"></param>
/// <returns></returns>
public List<List<JewelryItem>> Run(double budget, HashSet<string> targetCategories)
{
_solutions.Clear();
Backtrack(0, new List<JewelryItem>(), 0.0, budget, targetCategories);
return _solutions;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/06 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : BraceletMatchService.cs
*/
using CSharpAlgorithms.Backtracking.Common;
using CSharpAlgorithms.Backtracking.Core;
using CSharpAlgorithms.Backtracking.Dto;
using CSharpAlgorithms.Backtracking.Rule;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Service
{
/// <summary>
///
/// </summary>
public class BraceletMatchService
{
private readonly List<BeadItem> _beadPool;
public BraceletMatchService(List<BeadItem> beadPool)
{
_beadPool = beadPool;
}
public List<List<BeadItem>> Match(int targetCount, double budget, int maxColorLimit, int topN)
{
IBaseRule<BeadItem> rule = new BraceletRule(maxColorLimit);
var tracker = new BraceletBackTracker(_beadPool, rule);
var schemes = tracker.Run(targetCount, budget);
// 打分降序
schemes.Sort((a, b) => ScoreUtil.ScoreBraceletScheme(b).CompareTo(ScoreUtil.ScoreBraceletScheme(a)));
if (schemes.Count > topN)
schemes = schemes.Take(topN).ToList();
return schemes;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/06 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : JewelrySceneMatchService.cs
*/
using CSharpAlgorithms.Backtracking.Common;
using CSharpAlgorithms.Backtracking.Core;
using CSharpAlgorithms.Backtracking.Dto;
using CSharpAlgorithms.Backtracking.Rule;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Backtracking.Service
{
/// <summary>
///
/// </summary>
public class JewelrySceneMatchService
{
private readonly List<JewelryItem> _goodsPool;
/// <summary>
///
/// </summary>
/// <param name="goodsPool"></param>
public JewelrySceneMatchService(List<JewelryItem> goodsPool)
{
_goodsPool = goodsPool;
}
/// <summary>
///
/// </summary>
/// <param name="scene"></param>
/// <param name="budget"></param>
/// <param name="targetCategories"></param>
/// <param name="topN"></param>
/// <returns></returns>
public List<List<JewelryItem>> MatchByScene(string scene, double budget, HashSet<string> targetCategories, int topN)
{
var config = SceneJewelryRule.GetSceneConfig(scene);
IBaseRule<JewelryItem> rule = new SceneJewelryRule(config);
var tracker = new JewelrySceneBackTracker(_goodsPool, rule);
var schemes = tracker.Run(budget, targetCategories);
schemes.Sort((a, b) => ScoreUtil.ScoreJewelryScheme(b).CompareTo(ScoreUtil.ScoreJewelryScheme(a)));
if (schemes.Count > topN)
schemes = schemes.Take(topN).ToList();
return schemes;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Backtracking Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/06 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : DesignAlgorithm
# File : BacktrackingBll.cs
*/
using CSharpAlgorithms.Backtracking.Dto;
using CSharpAlgorithms.Backtracking.Service;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Bll
{
/// <summary>
///
/// </summary>
public class BacktrackingBll
{
static void TestBraceletMatch()
{
var beadPool = new List<BeadItem>()
{
new BeadItem{BeadId = "B01", Name = "南红圆珠", Material = "南红", ColorGroup = "red", UnitPrice = 168, Stock = 4},
new BeadItem{BeadId = "B02", Name = "和田玉圆珠", Material = "和田玉", ColorGroup = "green", UnitPrice = 198, Stock = 5},
new BeadItem{BeadId = "B03", Name = "紫水晶", Material = "紫水晶", ColorGroup = "purple", UnitPrice = 128, Stock = 4},
new BeadItem{BeadId = "B04", Name = "足金隔珠", Material = "足金", ColorGroup = "gold", UnitPrice = 320, Stock = 3},
};
var svc = new BraceletMatchService(beadPool);
var result = svc.Match(targetCount: 8, budget: 2000, maxColorLimit: 4, topN: 6);
Console.WriteLine("===== 多宝手串搭配方案 =====");
for (int idx = 0; idx < result.Count; idx++)
{
var scheme = result[idx];
double total = scheme.Sum(x => x.UnitPrice);
var names = scheme.Select(x => x.Name).ToList();
Console.WriteLine($"方案{idx + 1} 总价:{total:F2} 珠子:[{string.Join(", ", names)}]");
}
}
static void TestJewelrySceneMatch()
{
var goodsPool = new List<JewelryItem>()
{
new JewelryItem{SkuId="N001",Name="碎钻项链",Category="necklace",Material="18K",Color="white",Style="luxury",Price=3299,Stock=12,HasGem=true},
new JewelryItem{SkuId="N003",Name="素金项链",Category="necklace",Material="Au999",Color="yellow",Style="minimalist",Price=2199,Stock=9,HasGem=false},
new JewelryItem{SkuId="E001",Name="白钻耳饰",Category="earring",Material="18K",Color="white",Style="luxury",Price=2199,Stock=15,HasGem=true},
new JewelryItem{SkuId="E003",Name="素金耳饰",Category="earring",Material="Au999",Color="yellow",Style="minimalist",Price=1399,Stock=11,HasGem=false},
};
var svc = new JewelrySceneMatchService(goodsPool);
var targetCats = new HashSet<string> { "necklace", "earring" };
Console.WriteLine("\n===== 婚嫁场景 =====");
var wedding = svc.MatchByScene("wedding", 8000, targetCats, 8);
foreach (var set in wedding)
{
var names = set.Select(x => x.Name).ToList();
double total = set.Sum(x => x.Price);
Console.WriteLine($"[{string.Join(", ", names)}] 总价 {total:F2}");
}
Console.WriteLine("\n===== 通勤场景 =====");
var commute = svc.MatchByScene("commute", 5000, targetCats, 8);
foreach (var set in commute)
{
var names = set.Select(x => x.Name).ToList();
double total = set.Sum(x => x.Price);
Console.WriteLine($"[{string.Join(", ", names)}] 总价 {total:F2}");
}
}
/// <summary>
///
/// </summary>
public void Demo()
{
TestBraceletMatch();
TestJewelrySceneMatch();
}
}
}
输出:

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号