CSharp: Greedy Algorithm
项目结构:

/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Algorithms
# 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 : Const.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Common
{
/// <summary>
/// 全局精度常量
/// </summary>
public static class Const
{
public const int CaratDecimal = 3;
public const int MoneyDecimal = 2;
public const double Eps = 1e-6;
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : Erro.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Common
{
/// <summary>
/// 自定义业务异常
/// </summary>
public class GemBaseException : Exception
{
public GemBaseException(string msg) : base($"珠宝配石异常:{msg}")
{
}
}
/// <summary>
/// 参数非法:克拉/价格小于等于0
/// </summary>
public class GemParamInvalidException : GemBaseException
{
public GemParamInvalidException(string msg) : base($"参数非法:{msg}") { }
}
/// <summary>
/// 预算为0或负数
/// </summary>
public class BudgetZeroException : GemBaseException
{
public BudgetZeroException() : base("预算必须大于0") { }
}
/// <summary>
/// 库存无宝石
/// </summary>
public class StockEmptyException : GemBaseException
{
public StockEmptyException() : base("宝石库存为空,无法执行配石") { }
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : Util.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Common
{
/// <summary>
/// 克拉、金额四舍五入工具
/// </summary>
public static class Util
{
/// <summary>
/// 克拉保留3位小数
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static double RoundCarat(double val)
{
var mul = Math.Pow(10, Const.CaratDecimal);
return Math.Round(val * mul) / mul;
}
/// <summary>
/// 金额保留2位小数
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static double RoundMoney(double val)
{
var mul = Math.Pow(10, Const.MoneyDecimal);
return Math.Round(val * mul) / mul;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : GemAllocateItem.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Entity
{
/// <summary>
/// 配石明细
/// </summary>
public class GemAllocateItem
{
/// <summary>
///
/// </summary>
public string StoneName { get; set; }
/// <summary>
///
/// </summary>
public double UseCarat { get; set; }
/// <summary>
///
/// </summary>
public double UseCost { get; set; }
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : GemAllocateResultDTO.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
using CSharpAlgorithms.Greedy.Common;
namespace CSharpAlgorithms.Greedy.Entity
{
/// <summary>
/// 对外返回DTO
/// </summary>
public class GemAllocateResultDTO
{
/// <summary>
///
/// </summary>
public double BudgetTotal { get; set; }
/// <summary>
/// /
/// </summary>
public double CostActual { get; set; }
/// <summary>
///
/// </summary>
public double BudgetRemain { get; set; }
/// <summary>
///
/// </summary>
public double TotalCarat { get; set; }
/// <summary>
///
/// </summary>
public List<GemAllocateItem> DetailList { get; set; } = new List<GemAllocateItem>();
/// <summary>
/// 转字典,输出结构与Python/Go完全一致
/// </summary>
public Dictionary<string, object> ToDict()
{
var detail = DetailList.Select(item => new Dictionary<string, object>
{
["宝石名称"] = item.StoneName,
["取用克拉"] = Util.RoundCarat(item.UseCarat),
["花费金额"] = Util.RoundMoney(item.UseCost)
}).ToList();
return new Dictionary<string, object>
{
["预算总额"] = Util.RoundMoney(BudgetTotal),
["实际花费"] = Util.RoundMoney(CostActual),
["剩余预算"] = Util.RoundMoney(BudgetRemain),
["总匹配克拉"] = Util.RoundCarat(TotalCarat),
["选用裸石明细"] = detail
};
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : GemStone.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Entity
{
/// <summary>
/// 库存宝石实体
/// </summary>
public class GemStone
{
/// <summary>
/// 宝石名称
/// </summary>
public string StoneName { get; set; }
/// <summary>
/// 批次总克拉
/// </summary>
public double TotalCarat { get; set; }
/// <summary>
/// 整批总价
/// </summary>
public double BatchPrice { get; set; }
/// <summary>
/// 单位预算对应克拉(性价比排序指标)
/// </summary>
public double UnitCaratValue => TotalCarat / BatchPrice;
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : GemMemoryRepo.cs
*/
using CSharpAlgorithms.Greedy.Entity;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Repository
{
/// <summary>
/// 内存仓储实现
/// </summary>
public class GemMemoryRepo : IBaseGemRepo
{
private readonly List<GemStone> _storage = new List<GemStone>();
/// <summary>
///
/// </summary>
/// <param name="gem"></param>
public void AddGem(GemStone gem)
{
_storage.Add(gem);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public List<GemStone> GetAllGems()
{
// 返回拷贝,防止外部篡改内部集合
return new List<GemStone>(_storage);
}
/// <summary>
///
/// </summary>
public void ClearAll()
{
_storage.Clear();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public int Count()
{
return _storage.Count;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : IBaseGemRepo.cs
*/
using CSharpAlgorithms.Greedy.Entity;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Repository
{
/// <summary>
/// 仓储抽象接口
/// </summary>
public interface IBaseGemRepo
{
void AddGem(GemStone gem);
List<GemStone> GetAllGems();
void ClearAll();
int Count();
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : GemAllocateService.cs
*/
using CSharpAlgorithms.Greedy.Algorithm;
using CSharpAlgorithms.Greedy.Common;
using CSharpAlgorithms.Greedy.Entity;
using CSharpAlgorithms.Greedy.Repository;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Service
{
/// <summary>
/// 业务门面服务层
/// </summary>
public class GemAllocateService
{
private readonly IBaseGemRepo _repo;
private readonly IBaseGreedy _alg;
// 依赖注入
public GemAllocateService(IBaseGemRepo repo, IBaseGreedy alg)
{
_repo = repo;
_alg = alg;
}
/// <summary>
/// 添加库存宝石,统一参数校验
/// </summary>
/// <param name="stoneName"></param>
/// <param name="totalCarat"></param>
/// <param name="batchPrice"></param>
/// <exception cref="GemParamInvalidException"></exception>
public void AddStoneStock(string stoneName, double totalCarat, double batchPrice)
{
if (totalCarat <= Const.Eps || batchPrice <= Const.Eps)
throw new GemParamInvalidException($"宝石[{stoneName}]克拉/价格必须大于0");
var gem = new GemStone
{
StoneName = stoneName,
TotalCarat = totalCarat,
BatchPrice = batchPrice
};
_repo.AddGem(gem);
}
/// <summary>
/// 执行业务配石完整流程
/// </summary>
/// <param name="budget"></param>
/// <returns></returns>
/// <exception cref="StockEmptyException"></exception>
public GemAllocateResultDTO Allocate(double budget)
{
var gemList = _repo.GetAllGems();
if (gemList.Count == 0)
throw new StockEmptyException();
var items = _alg.Calculate(gemList, budget);
double totalCarat = 0;
double totalCost = 0;
foreach (var item in items)
{
totalCarat += item.UseCarat;
totalCost += item.UseCost;
}
double remain = budget - totalCost;
return new GemAllocateResultDTO
{
BudgetTotal = budget,
CostActual = totalCost,
BudgetRemain = remain,
TotalCarat = totalCarat,
DetailList = items
};
}
/// <summary>
/// 清空库存,复用服务实例处理下一笔订单
/// </summary>
public void ClearStock()
{
_repo.ClearAll();
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : GemFractionGreedy.cs
*/
using CSharpAlgorithms.Greedy.Common;
using CSharpAlgorithms.Greedy.Entity;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Algorithm
{
/// <summary>
/// 分数背包贪心核心
/// </summary>
public class GemFractionGreedy : IBaseGreedy
{
private readonly ISortStrategy _sortStrategy;
/// <summary>
///
/// </summary>
/// <param name="sortStrategy"></param>
public GemFractionGreedy(ISortStrategy sortStrategy = null)
{
_sortStrategy = sortStrategy ?? new UnitValueDescStrategy();
}
/// <summary>
///
/// </summary>
/// <param name="gemList"></param>
/// <param name="budget"></param>
/// <returns></returns>
/// <exception cref="BudgetZeroException"></exception>
public List<GemAllocateItem> Calculate(List<GemStone> gemList, double budget)
{
if (budget <= Const.Eps)
throw new BudgetZeroException();
var sorted = _sortStrategy.Sort(gemList);
double remainBudget = budget;
var result = new List<GemAllocateItem>();
foreach (var gem in sorted)
{
if (remainBudget <= Const.Eps) break;
double useCarat, useCost;
if (gem.BatchPrice <= remainBudget)
{
useCarat = gem.TotalCarat;
useCost = gem.BatchPrice;
}
else
{
double ratio = remainBudget / gem.BatchPrice;
useCarat = gem.TotalCarat * ratio;
useCost = remainBudget;
}
result.Add(new GemAllocateItem
{
StoneName = gem.StoneName,
UseCarat = useCarat,
UseCost = useCost
});
remainBudget -= useCost;
}
return result;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : IBaseGreedy.cs
*/
using CSharpAlgorithms.Greedy.Entity;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Algorithm
{
/// <summary>
/// 贪心算法顶层接口
/// </summary>
public interface IBaseGreedy
{
List<GemAllocateItem> Calculate(List<GemStone> gemList, double budget);
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : ISortStrategy.cs
*/
using CSharpAlgorithms.Greedy.Entity;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Algorithm
{
/// <summary>
/// 排序策略抽象
/// </summary>
public interface ISortStrategy
{
List<GemStone> Sort(List<GemStone> gemList);
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : MaxCaratDescStrategy.cs
*/
using CSharpAlgorithms.Greedy.Entity;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Algorithm
{
/// <summary>
/// 扩展策略:优先大克拉宝石
/// </summary>
public class MaxCaratDescStrategy : ISortStrategy
{
public List<GemStone> Sort(List<GemStone> gemList)
{
return gemList
.OrderByDescending(g => g.TotalCarat)
.ToList();
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : UnitValueDescStrategy.cs
*/
using CSharpAlgorithms.Greedy.Entity;
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharpAlgorithms.Greedy.Algorithm
{
/// <summary>
/// 默认策略:性价比从高到低
///
/// </summary>
public class UnitValueDescStrategy : ISortStrategy
{
public List<GemStone> Sort(List<GemStone> gemList)
{
return gemList
.OrderByDescending(g => g.UnitCaratValue)
.ToList();
}
}
}
调用:
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Greedy 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 : GreedyBll.cs
*/
using CSharpAlgorithms.Greedy.Algorithm;
using CSharpAlgorithms.Greedy.Common;
using CSharpAlgorithms.Greedy.Repository;
using CSharpAlgorithms.Greedy.Service;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
namespace CSharpAlgorithms.Bll
{
/// <summary>
///
/// </summary>
public class GreedyBll
{
// 全局统一Json配置:关闭中文Unicode转义、格式化输出
private static readonly JsonSerializerOptions _jsonOpts = new JsonSerializerOptions
{
WriteIndented = true,
// 使用不转义的编码器,中文直接输出
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
static void DemoCase1()
{
Console.WriteLine("===== 案例1|性价比优先配石结果 =====");
IBaseGemRepo repo = new GemMemoryRepo();
IBaseGreedy alg = new GemFractionGreedy();
var svc = new GemAllocateService(repo, alg);
svc.AddStoneStock("0.8ct白钻", 0.8, 10500);
svc.AddStoneStock("0.5ct白钻", 0.5, 6800);
svc.AddStoneStock("0.3ct白钻", 0.3, 4200);
svc.AddStoneStock("0.2ct粉钻", 0.2, 2800);
var dto = svc.Allocate(18000);
var dict = dto.ToDict();
// 使用自定义配置序列化
string json = JsonSerializer.Serialize(dict, _jsonOpts);
Console.WriteLine(json);
}
static void DemoCase2()
{
Console.WriteLine("\n===== 案例2|优先大克拉配石结果 =====");
IBaseGemRepo repo = new GemMemoryRepo();
ISortStrategy bigCaratSort = new MaxCaratDescStrategy();
IBaseGreedy alg = new GemFractionGreedy(bigCaratSort);
var svc = new GemAllocateService(repo, alg);
svc.AddStoneStock("0.8ct白钻", 0.8, 10500);
svc.AddStoneStock("0.5ct白钻", 0.5, 6800);
var dto = svc.Allocate(12000);
var dict = dto.ToDict();
string json = JsonSerializer.Serialize(dict, _jsonOpts);
Console.WriteLine(json);
}
/// <summary>
///
/// </summary>
public void Demo()
{
try
{
DemoCase1();
DemoCase2();
}
catch (GemBaseException ex)
{
Console.WriteLine($"业务异常:{ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"系统异常:{ex.Message}");
}
}
}
}
输出:

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