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