805 lines
27 KiB
C#
805 lines
27 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel.DataAnnotations;
|
||
using System.Linq;
|
||
|
||
namespace NPP.SmartSchedue.Api.Contracts.Services.Integration.Input
|
||
{
|
||
/// <summary>
|
||
/// 智能人员分配优化权重配置
|
||
/// 五层决策模型第三层:优化决策阶段的核心权重配置
|
||
/// 支持多策略、多场景、动态调整的智能权重管理
|
||
/// 深度业务思考:平衡效率、公平性、连续性、专业性等多维度目标
|
||
/// </summary>
|
||
public class OptimizationWeights
|
||
{
|
||
#region 核心权重配置
|
||
|
||
/// <summary>
|
||
/// 指定人员优先权重 (0.0-1.0)
|
||
/// 业务含义:当任务有明确指定人员时的优先级权重
|
||
/// 适用场景:特殊技能需求、客户指定、专项任务等
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "指定人员权重必须在0.0-1.0范围内")]
|
||
public double AssignedPersonnelWeight { get; set; } = 0.8;
|
||
|
||
/// <summary>
|
||
/// 项目FL人员优先权重 (0.0-1.0)
|
||
/// 业务含义:项目内部FL(First Line)人员的优先级权重
|
||
/// 适用场景:项目连续性、知识传承、团队稳定性
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "项目FL人员权重必须在0.0-1.0范围内")]
|
||
public double ProjectFLWeight { get; set; } = 0.6;
|
||
|
||
/// <summary>
|
||
/// 工作负载均衡权重 (0.0-1.0)
|
||
/// 业务含义:人员工作负载分布均衡的重要性权重
|
||
/// 适用场景:公平分配、避免过劳、提升团队稳定性
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "工作负载均衡权重必须在0.0-1.0范围内")]
|
||
public double WorkloadBalanceWeight { get; set; } = 0.4;
|
||
|
||
/// <summary>
|
||
/// 班次连续性权重 (0.0-1.0)
|
||
/// 业务含义:保持人员班次连续性和规律性的权重
|
||
/// 适用场景:生物钟保护、工作效率优化、人员健康管理
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "班次连续性权重必须在0.0-1.0范围内")]
|
||
public double ShiftContinuityWeight { get; set; } = 0.3;
|
||
|
||
/// <summary>
|
||
/// 技能匹配优先权重 (0.0-1.0)
|
||
/// 业务含义:人员技能与任务需求匹配度的权重
|
||
/// 适用场景:质量保证、效率提升、风险控制
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "技能匹配权重必须在0.0-1.0范围内")]
|
||
public double SkillMatchWeight { get; set; } = 0.5;
|
||
|
||
/// <summary>
|
||
/// 协作历史权重 (0.0-1.0)
|
||
/// 业务含义:人员在相关项目的历史协作经验权重
|
||
/// 适用场景:团队默契、沟通效率、项目风险降低
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "协作历史权重必须在0.0-1.0范围内")]
|
||
public double CollaborationHistoryWeight { get; set; } = 0.2;
|
||
|
||
#endregion
|
||
|
||
#region 扩展权重配置
|
||
|
||
/// <summary>
|
||
/// 成本效益权重 (0.0-1.0)
|
||
/// 业务含义:考虑人员成本与任务价值匹配的权重
|
||
/// 适用场景:成本控制、资源优化配置、ROI最大化
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "成本效益权重必须在0.0-1.0范围内")]
|
||
public double CostEfficiencyWeight { get; set; } = 0.3;
|
||
|
||
/// <summary>
|
||
/// 地理位置便利性权重 (0.0-1.0)
|
||
/// 业务含义:人员地理位置与工作地点便利性的权重
|
||
/// 适用场景:交通成本、响应速度、突发事件处理
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "地理位置便利性权重必须在0.0-1.0范围内")]
|
||
public double LocationConvenienceWeight { get; set; } = 0.2;
|
||
|
||
/// <summary>
|
||
/// 培训发展权重 (0.0-1.0)
|
||
/// 业务含义:为人员提供学习和发展机会的权重
|
||
/// 适用场景:人才培养、技能提升、职业发展规划
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "培训发展权重必须在0.0-1.0范围内")]
|
||
public double TrainingDevelopmentWeight { get; set; } = 0.1;
|
||
|
||
/// <summary>
|
||
/// 紧急响应能力权重 (0.0-1.0)
|
||
/// 业务含义:人员处理紧急情况能力的权重
|
||
/// 适用场景:应急任务、关键节点、风险管控
|
||
/// </summary>
|
||
[Range(0.0, 1.0, ErrorMessage = "紧急响应能力权重必须在0.0-1.0范围内")]
|
||
public double EmergencyResponseWeight { get; set; } = 0.4;
|
||
|
||
#endregion
|
||
|
||
#region 权重配置元数据
|
||
|
||
/// <summary>
|
||
/// 权重配置名称
|
||
/// 用于识别和管理不同的权重配置方案
|
||
/// </summary>
|
||
[Required(ErrorMessage = "权重配置名称不能为空")]
|
||
[StringLength(100, ErrorMessage = "权重配置名称长度不能超过100字符")]
|
||
public string ConfigurationName { get; set; } = "默认配置";
|
||
|
||
/// <summary>
|
||
/// 权重配置描述
|
||
/// 详细说明该配置的适用场景和特点
|
||
/// </summary>
|
||
[StringLength(500, ErrorMessage = "权重配置描述长度不能超过500字符")]
|
||
public string Description { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 配置策略类型
|
||
/// 标识该权重配置所属的分配策略类型
|
||
/// </summary>
|
||
public OptimizationStrategy StrategyType { get; set; } = OptimizationStrategy.Balanced;
|
||
|
||
/// <summary>
|
||
/// 是否为系统预设配置
|
||
/// 标识是否为系统内置的标准配置
|
||
/// </summary>
|
||
public bool IsSystemPreset { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 配置创建者ID
|
||
/// 记录创建该配置的用户或系统标识
|
||
/// </summary>
|
||
public long? CreatedBy { get; set; }
|
||
|
||
/// <summary>
|
||
/// 配置创建时间
|
||
/// </summary>
|
||
public DateTime CreatedTime { get; set; } = DateTime.Now;
|
||
|
||
/// <summary>
|
||
/// 最后修改时间
|
||
/// </summary>
|
||
public DateTime LastModifiedTime { get; set; } = DateTime.Now;
|
||
|
||
/// <summary>
|
||
/// 配置版本号
|
||
/// 用于跟踪配置的变更历史
|
||
/// </summary>
|
||
public string Version { get; set; } = "1.0.0";
|
||
|
||
#endregion
|
||
|
||
#region 高级配置选项
|
||
|
||
/// <summary>
|
||
/// 自定义权重规则
|
||
/// 支持用户定义的特殊权重计算规则
|
||
/// </summary>
|
||
public Dictionary<string, CustomWeightRule> CustomWeightRules { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 权重动态调整配置
|
||
/// 根据实时条件动态调整权重的规则配置
|
||
/// </summary>
|
||
public DynamicWeightAdjustment DynamicAdjustment { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 权重约束条件
|
||
/// 定义权重配置必须满足的约束条件
|
||
/// </summary>
|
||
public WeightConstraints Constraints { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 权重归一化方式
|
||
/// 定义如何对权重进行标准化处理
|
||
/// </summary>
|
||
public WeightNormalizationMethod NormalizationMethod { get; set; } = WeightNormalizationMethod.ProportionalSum;
|
||
|
||
#endregion
|
||
|
||
#region 核心业务方法
|
||
|
||
/// <summary>
|
||
/// 验证权重配置的有效性
|
||
/// 深度业务思考:确保权重配置符合业务逻辑和数学约束
|
||
/// </summary>
|
||
public WeightValidationResult ValidateConfiguration()
|
||
{
|
||
var result = new WeightValidationResult { IsValid = true, Issues = new List<string>() };
|
||
|
||
try
|
||
{
|
||
// 1. 基础范围验证(通过DataAnnotations已覆盖)
|
||
var properties = GetType().GetProperties()
|
||
.Where(p => p.PropertyType == typeof(double) && p.Name.EndsWith("Weight"));
|
||
|
||
foreach (var prop in properties)
|
||
{
|
||
var value = (double)prop.GetValue(this);
|
||
if (value < 0.0 || value > 1.0)
|
||
{
|
||
result.IsValid = false;
|
||
result.Issues.Add($"{prop.Name} 值 {value} 超出有效范围 [0.0, 1.0]");
|
||
}
|
||
}
|
||
|
||
// 2. 权重总和合理性检查
|
||
var totalWeight = GetTotalWeight();
|
||
if (totalWeight < 0.1)
|
||
{
|
||
result.Issues.Add($"权重总和过低 ({totalWeight:F2}),可能导致分配结果不稳定");
|
||
}
|
||
else if (totalWeight > 5.0)
|
||
{
|
||
result.Issues.Add($"权重总和过高 ({totalWeight:F2}),建议进行归一化处理");
|
||
}
|
||
|
||
// 3. 业务逻辑一致性检查
|
||
if (AssignedPersonnelWeight < 0.5 && StrategyType == OptimizationStrategy.AssignedPersonnelFirst)
|
||
{
|
||
result.Issues.Add("指定人员优先策略下,指定人员权重应不低于0.5");
|
||
}
|
||
|
||
if (WorkloadBalanceWeight < 0.6 && StrategyType == OptimizationStrategy.LoadBalanceFirst)
|
||
{
|
||
result.Issues.Add("负载均衡优先策略下,工作负载均衡权重应不低于0.6");
|
||
}
|
||
|
||
// 4. 约束条件检查
|
||
if (Constraints != null)
|
||
{
|
||
var constraintResult = Constraints.ValidateConstraints(this);
|
||
if (!constraintResult.IsValid)
|
||
{
|
||
result.IsValid = false;
|
||
result.Issues.AddRange(constraintResult.Issues);
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.IsValid = false;
|
||
result.Issues.Add($"权重配置验证异常:{ex.Message}");
|
||
return result;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取权重总和
|
||
/// </summary>
|
||
public double GetTotalWeight()
|
||
{
|
||
return AssignedPersonnelWeight + ProjectFLWeight + WorkloadBalanceWeight +
|
||
ShiftContinuityWeight + SkillMatchWeight + CollaborationHistoryWeight +
|
||
CostEfficiencyWeight + LocationConvenienceWeight + TrainingDevelopmentWeight +
|
||
EmergencyResponseWeight;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 归一化权重配置
|
||
/// 将所有权重按比例调整到指定的总和
|
||
/// </summary>
|
||
public void NormalizeWeights(double targetSum = 1.0)
|
||
{
|
||
var currentSum = GetTotalWeight();
|
||
if (currentSum <= 0) return;
|
||
|
||
var factor = targetSum / currentSum;
|
||
|
||
AssignedPersonnelWeight *= factor;
|
||
ProjectFLWeight *= factor;
|
||
WorkloadBalanceWeight *= factor;
|
||
ShiftContinuityWeight *= factor;
|
||
SkillMatchWeight *= factor;
|
||
CollaborationHistoryWeight *= factor;
|
||
CostEfficiencyWeight *= factor;
|
||
LocationConvenienceWeight *= factor;
|
||
TrainingDevelopmentWeight *= factor;
|
||
EmergencyResponseWeight *= factor;
|
||
|
||
LastModifiedTime = DateTime.Now;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转换为字典格式
|
||
/// 用于与现有系统的权重配置格式兼容
|
||
/// </summary>
|
||
public Dictionary<string, double> ToDictionary()
|
||
{
|
||
return new Dictionary<string, double>
|
||
{
|
||
["AssignedPersonnel"] = AssignedPersonnelWeight,
|
||
["ProjectFL"] = ProjectFLWeight,
|
||
["WorkloadBalance"] = WorkloadBalanceWeight,
|
||
["ShiftContinuity"] = ShiftContinuityWeight,
|
||
["SkillMatch"] = SkillMatchWeight,
|
||
["CollaborationHistory"] = CollaborationHistoryWeight,
|
||
["CostEfficiency"] = CostEfficiencyWeight,
|
||
["LocationConvenience"] = LocationConvenienceWeight,
|
||
["TrainingDevelopment"] = TrainingDevelopmentWeight,
|
||
["EmergencyResponse"] = EmergencyResponseWeight
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从字典加载权重配置
|
||
/// </summary>
|
||
public void LoadFromDictionary(Dictionary<string, double> weights)
|
||
{
|
||
if (weights == null) return;
|
||
|
||
AssignedPersonnelWeight = weights.GetValueOrDefault("AssignedPersonnel", AssignedPersonnelWeight);
|
||
ProjectFLWeight = weights.GetValueOrDefault("ProjectFL", ProjectFLWeight);
|
||
WorkloadBalanceWeight = weights.GetValueOrDefault("WorkloadBalance", WorkloadBalanceWeight);
|
||
ShiftContinuityWeight = weights.GetValueOrDefault("ShiftContinuity", ShiftContinuityWeight);
|
||
SkillMatchWeight = weights.GetValueOrDefault("SkillMatch", SkillMatchWeight);
|
||
CollaborationHistoryWeight = weights.GetValueOrDefault("CollaborationHistory", CollaborationHistoryWeight);
|
||
CostEfficiencyWeight = weights.GetValueOrDefault("CostEfficiency", CostEfficiencyWeight);
|
||
LocationConvenienceWeight = weights.GetValueOrDefault("LocationConvenience", LocationConvenienceWeight);
|
||
TrainingDevelopmentWeight = weights.GetValueOrDefault("TrainingDevelopment", TrainingDevelopmentWeight);
|
||
EmergencyResponseWeight = weights.GetValueOrDefault("EmergencyResponse", EmergencyResponseWeight);
|
||
|
||
LastModifiedTime = DateTime.Now;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 深拷贝权重配置
|
||
/// </summary>
|
||
public OptimizationWeights DeepClone()
|
||
{
|
||
return new OptimizationWeights
|
||
{
|
||
AssignedPersonnelWeight = AssignedPersonnelWeight,
|
||
ProjectFLWeight = ProjectFLWeight,
|
||
WorkloadBalanceWeight = WorkloadBalanceWeight,
|
||
ShiftContinuityWeight = ShiftContinuityWeight,
|
||
SkillMatchWeight = SkillMatchWeight,
|
||
CollaborationHistoryWeight = CollaborationHistoryWeight,
|
||
CostEfficiencyWeight = CostEfficiencyWeight,
|
||
LocationConvenienceWeight = LocationConvenienceWeight,
|
||
TrainingDevelopmentWeight = TrainingDevelopmentWeight,
|
||
EmergencyResponseWeight = EmergencyResponseWeight,
|
||
ConfigurationName = ConfigurationName + "_Copy",
|
||
Description = Description,
|
||
StrategyType = StrategyType,
|
||
IsSystemPreset = false,
|
||
CreatedBy = CreatedBy,
|
||
CreatedTime = DateTime.Now,
|
||
LastModifiedTime = DateTime.Now,
|
||
Version = "1.0.0",
|
||
CustomWeightRules = new Dictionary<string, CustomWeightRule>(CustomWeightRules),
|
||
DynamicAdjustment = DynamicAdjustment?.DeepClone(),
|
||
Constraints = Constraints?.DeepClone(),
|
||
NormalizationMethod = NormalizationMethod
|
||
};
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 预设配置工厂方法
|
||
|
||
/// <summary>
|
||
/// 创建效率优先配置
|
||
/// 适用场景:紧急任务、关键交付、高价值项目
|
||
/// </summary>
|
||
public static OptimizationWeights CreateEfficiencyFirstConfiguration()
|
||
{
|
||
return new OptimizationWeights
|
||
{
|
||
ConfigurationName = "效率优先配置",
|
||
Description = "优先考虑技能匹配和协作历史,适用于紧急任务和关键交付",
|
||
StrategyType = OptimizationStrategy.EfficiencyFirst,
|
||
IsSystemPreset = true,
|
||
AssignedPersonnelWeight = 0.9,
|
||
SkillMatchWeight = 0.8,
|
||
CollaborationHistoryWeight = 0.7,
|
||
ProjectFLWeight = 0.6,
|
||
EmergencyResponseWeight = 0.8,
|
||
WorkloadBalanceWeight = 0.2,
|
||
ShiftContinuityWeight = 0.2,
|
||
CostEfficiencyWeight = 0.3,
|
||
LocationConvenienceWeight = 0.1,
|
||
TrainingDevelopmentWeight = 0.1
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建公平分配配置
|
||
/// 适用场景:日常任务、团队建设、长期项目
|
||
/// </summary>
|
||
public static OptimizationWeights CreateFairDistributionConfiguration()
|
||
{
|
||
return new OptimizationWeights
|
||
{
|
||
ConfigurationName = "公平分配配置",
|
||
Description = "注重工作负载均衡和培训发展,适用于日常任务和团队建设",
|
||
StrategyType = OptimizationStrategy.FairDistribution,
|
||
IsSystemPreset = true,
|
||
WorkloadBalanceWeight = 0.8,
|
||
TrainingDevelopmentWeight = 0.6,
|
||
SkillMatchWeight = 0.5,
|
||
ShiftContinuityWeight = 0.5,
|
||
ProjectFLWeight = 0.4,
|
||
CollaborationHistoryWeight = 0.3,
|
||
AssignedPersonnelWeight = 0.3,
|
||
CostEfficiencyWeight = 0.4,
|
||
LocationConvenienceWeight = 0.3,
|
||
EmergencyResponseWeight = 0.2
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建连续性优先配置
|
||
/// 适用场景:轮班制工作、健康管理、规律性要求高的任务
|
||
/// </summary>
|
||
public static OptimizationWeights CreateContinuityFirstConfiguration()
|
||
{
|
||
return new OptimizationWeights
|
||
{
|
||
ConfigurationName = "连续性优先配置",
|
||
Description = "强调班次连续性和人员稳定性,适用于轮班制和规律性要求高的工作",
|
||
StrategyType = OptimizationStrategy.ContinuityFirst,
|
||
IsSystemPreset = true,
|
||
ShiftContinuityWeight = 0.9,
|
||
ProjectFLWeight = 0.7,
|
||
CollaborationHistoryWeight = 0.6,
|
||
WorkloadBalanceWeight = 0.6,
|
||
SkillMatchWeight = 0.5,
|
||
LocationConvenienceWeight = 0.4,
|
||
AssignedPersonnelWeight = 0.4,
|
||
CostEfficiencyWeight = 0.3,
|
||
TrainingDevelopmentWeight = 0.2,
|
||
EmergencyResponseWeight = 0.3
|
||
};
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
#region 支持类定义
|
||
|
||
/// <summary>
|
||
/// 优化策略类型枚举
|
||
/// </summary>
|
||
public enum OptimizationStrategy
|
||
{
|
||
/// <summary>
|
||
/// 平衡策略
|
||
/// </summary>
|
||
Balanced = 0,
|
||
|
||
/// <summary>
|
||
/// 效率优先
|
||
/// </summary>
|
||
EfficiencyFirst = 1,
|
||
|
||
/// <summary>
|
||
/// 公平分配
|
||
/// </summary>
|
||
FairDistribution = 2,
|
||
|
||
/// <summary>
|
||
/// 连续性优先
|
||
/// </summary>
|
||
ContinuityFirst = 3,
|
||
|
||
/// <summary>
|
||
/// 指定人员优先
|
||
/// </summary>
|
||
AssignedPersonnelFirst = 4,
|
||
|
||
/// <summary>
|
||
/// 负载均衡优先
|
||
/// </summary>
|
||
LoadBalanceFirst = 5,
|
||
|
||
/// <summary>
|
||
/// 技能匹配优先
|
||
/// </summary>
|
||
SkillMatchFirst = 6,
|
||
|
||
/// <summary>
|
||
/// 成本优化
|
||
/// </summary>
|
||
CostOptimized = 7,
|
||
|
||
/// <summary>
|
||
/// 自定义策略
|
||
/// </summary>
|
||
Custom = 99
|
||
}
|
||
|
||
/// <summary>
|
||
/// 权重归一化方法
|
||
/// </summary>
|
||
public enum WeightNormalizationMethod
|
||
{
|
||
/// <summary>
|
||
/// 不进行归一化
|
||
/// </summary>
|
||
None = 0,
|
||
|
||
/// <summary>
|
||
/// 按比例归一化到总和为1
|
||
/// </summary>
|
||
ProportionalSum = 1,
|
||
|
||
/// <summary>
|
||
/// 按最大值归一化
|
||
/// </summary>
|
||
MaxValue = 2,
|
||
|
||
/// <summary>
|
||
/// 按标准差归一化
|
||
/// </summary>
|
||
StandardDeviation = 3
|
||
}
|
||
|
||
/// <summary>
|
||
/// 权重验证结果
|
||
/// </summary>
|
||
public class WeightValidationResult
|
||
{
|
||
/// <summary>
|
||
/// 验证是否通过
|
||
/// </summary>
|
||
public bool IsValid { get; set; }
|
||
|
||
/// <summary>
|
||
/// 验证问题列表
|
||
/// </summary>
|
||
public List<string> Issues { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 验证建议
|
||
/// </summary>
|
||
public List<string> Suggestions { get; set; } = new();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自定义权重规则
|
||
/// </summary>
|
||
public class CustomWeightRule
|
||
{
|
||
/// <summary>
|
||
/// 规则名称
|
||
/// </summary>
|
||
public string RuleName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 规则表达式
|
||
/// </summary>
|
||
public string RuleExpression { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 规则权重
|
||
/// </summary>
|
||
public double Weight { get; set; }
|
||
|
||
/// <summary>
|
||
/// 是否启用
|
||
/// </summary>
|
||
public bool IsEnabled { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 规则描述
|
||
/// </summary>
|
||
public string Description { get; set; } = string.Empty;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 动态权重调整配置
|
||
/// </summary>
|
||
public class DynamicWeightAdjustment
|
||
{
|
||
/// <summary>
|
||
/// 是否启用动态调整
|
||
/// </summary>
|
||
public bool IsEnabled { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 调整触发条件
|
||
/// </summary>
|
||
public List<AdjustmentTrigger> Triggers { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 调整规则
|
||
/// </summary>
|
||
public List<AdjustmentRule> Rules { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 最大调整幅度
|
||
/// </summary>
|
||
public double MaxAdjustmentRange { get; set; } = 0.3;
|
||
|
||
/// <summary>
|
||
/// 深拷贝
|
||
/// </summary>
|
||
public DynamicWeightAdjustment DeepClone()
|
||
{
|
||
return new DynamicWeightAdjustment
|
||
{
|
||
IsEnabled = IsEnabled,
|
||
Triggers = new List<AdjustmentTrigger>(Triggers),
|
||
Rules = new List<AdjustmentRule>(Rules),
|
||
MaxAdjustmentRange = MaxAdjustmentRange
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调整触发条件
|
||
/// </summary>
|
||
public class AdjustmentTrigger
|
||
{
|
||
/// <summary>
|
||
/// 触发条件名称
|
||
/// </summary>
|
||
public string TriggerName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 触发条件表达式
|
||
/// </summary>
|
||
public string ConditionExpression { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 触发阈值
|
||
/// </summary>
|
||
public double Threshold { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调整规则
|
||
/// </summary>
|
||
public class AdjustmentRule
|
||
{
|
||
/// <summary>
|
||
/// 目标权重字段
|
||
/// </summary>
|
||
public string TargetWeightField { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 调整方式
|
||
/// </summary>
|
||
public AdjustmentType AdjustmentType { get; set; } = AdjustmentType.Multiply;
|
||
|
||
/// <summary>
|
||
/// 调整值
|
||
/// </summary>
|
||
public double AdjustmentValue { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调整方式枚举
|
||
/// </summary>
|
||
public enum AdjustmentType
|
||
{
|
||
/// <summary>
|
||
/// 加法调整
|
||
/// </summary>
|
||
Add = 1,
|
||
|
||
/// <summary>
|
||
/// 乘法调整
|
||
/// </summary>
|
||
Multiply = 2,
|
||
|
||
/// <summary>
|
||
/// 设置固定值
|
||
/// </summary>
|
||
SetValue = 3
|
||
}
|
||
|
||
/// <summary>
|
||
/// 权重约束条件
|
||
/// </summary>
|
||
public class WeightConstraints
|
||
{
|
||
/// <summary>
|
||
/// 总权重最小值
|
||
/// </summary>
|
||
public double MinTotalWeight { get; set; } = 0.1;
|
||
|
||
/// <summary>
|
||
/// 总权重最大值
|
||
/// </summary>
|
||
public double MaxTotalWeight { get; set; } = 10.0;
|
||
|
||
/// <summary>
|
||
/// 必须权重字段
|
||
/// 这些权重字段不能为0
|
||
/// </summary>
|
||
public List<string> RequiredWeightFields { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 互斥权重组
|
||
/// 同组内只能有一个权重大于指定阈值
|
||
/// </summary>
|
||
public List<MutuallyExclusiveWeightGroup> MutuallyExclusiveGroups { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 验证约束条件
|
||
/// </summary>
|
||
public WeightValidationResult ValidateConstraints(OptimizationWeights weights)
|
||
{
|
||
var result = new WeightValidationResult { IsValid = true, Issues = new List<string>() };
|
||
|
||
// 验证总权重范围
|
||
var totalWeight = weights.GetTotalWeight();
|
||
if (totalWeight < MinTotalWeight)
|
||
{
|
||
result.IsValid = false;
|
||
result.Issues.Add($"总权重 {totalWeight:F2} 低于最小值 {MinTotalWeight:F2}");
|
||
}
|
||
if (totalWeight > MaxTotalWeight)
|
||
{
|
||
result.IsValid = false;
|
||
result.Issues.Add($"总权重 {totalWeight:F2} 超过最大值 {MaxTotalWeight:F2}");
|
||
}
|
||
|
||
// 验证必须权重字段
|
||
var weightDict = weights.ToDictionary();
|
||
foreach (var requiredField in RequiredWeightFields)
|
||
{
|
||
if (weightDict.TryGetValue(requiredField, out var value) && value <= 0)
|
||
{
|
||
result.IsValid = false;
|
||
result.Issues.Add($"必须权重字段 {requiredField} 不能为0");
|
||
}
|
||
}
|
||
|
||
// 验证互斥权重组
|
||
foreach (var group in MutuallyExclusiveGroups)
|
||
{
|
||
var highWeightFields = group.WeightFields
|
||
.Where(field => weightDict.TryGetValue(field, out var value) && value > group.Threshold)
|
||
.ToList();
|
||
|
||
if (highWeightFields.Count > 1)
|
||
{
|
||
result.IsValid = false;
|
||
result.Issues.Add($"互斥权重组 {group.GroupName} 中有多个字段超过阈值:{string.Join(", ", highWeightFields)}");
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 深拷贝
|
||
/// </summary>
|
||
public WeightConstraints DeepClone()
|
||
{
|
||
return new WeightConstraints
|
||
{
|
||
MinTotalWeight = MinTotalWeight,
|
||
MaxTotalWeight = MaxTotalWeight,
|
||
RequiredWeightFields = new List<string>(RequiredWeightFields),
|
||
MutuallyExclusiveGroups = MutuallyExclusiveGroups.Select(g => g.DeepClone()).ToList()
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 互斥权重组
|
||
/// </summary>
|
||
public class MutuallyExclusiveWeightGroup
|
||
{
|
||
/// <summary>
|
||
/// 组名称
|
||
/// </summary>
|
||
public string GroupName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 权重字段列表
|
||
/// </summary>
|
||
public List<string> WeightFields { get; set; } = new();
|
||
|
||
/// <summary>
|
||
/// 阈值
|
||
/// </summary>
|
||
public double Threshold { get; set; } = 0.5;
|
||
|
||
/// <summary>
|
||
/// 深拷贝
|
||
/// </summary>
|
||
public MutuallyExclusiveWeightGroup DeepClone()
|
||
{
|
||
return new MutuallyExclusiveWeightGroup
|
||
{
|
||
GroupName = GroupName,
|
||
WeightFields = new List<string>(WeightFields),
|
||
Threshold = Threshold
|
||
};
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
} |