improve:点名算法

优化概率模型
This commit is contained in:
2025-11-29 16:58:40 +08:00
parent 094f1223d1
commit b8581b6368
3 changed files with 59 additions and 18 deletions
+2 -2
View File
@@ -3374,7 +3374,7 @@
<Slider x:Name="MLAvoidanceHistorySlider" Minimum="5" <Slider x:Name="MLAvoidanceHistorySlider" Minimum="5"
Maximum="50" Width="168" FontFamily="Microsoft YaHei UI" Maximum="50" Width="168" FontFamily="Microsoft YaHei UI"
ValueChanged="MLAvoidanceHistorySlider_ValueChanged" ValueChanged="MLAvoidanceHistorySlider_ValueChanged"
FontSize="20" IsSnapToTickEnabled="True" Value="20" TickFrequency="5" FontSize="20" IsSnapToTickEnabled="True" Value="50" TickFrequency="5"
TickPlacement="None" AutoToolTipPlacement="None" /> TickPlacement="None" AutoToolTipPlacement="None" />
<TextBlock VerticalAlignment="Center" Margin="12,0,16,0" FontSize="14" <TextBlock VerticalAlignment="Center" Margin="12,0,16,0" FontSize="14"
FontFamily="Consolas" FontFamily="Consolas"
@@ -3387,7 +3387,7 @@
<Slider x:Name="MLAvoidanceWeightSlider" Minimum="0.1" <Slider x:Name="MLAvoidanceWeightSlider" Minimum="0.1"
Maximum="1.0" Width="168" FontFamily="Microsoft YaHei UI" Maximum="1.0" Width="168" FontFamily="Microsoft YaHei UI"
ValueChanged="MLAvoidanceWeightSlider_ValueChanged" ValueChanged="MLAvoidanceWeightSlider_ValueChanged"
FontSize="20" IsSnapToTickEnabled="True" Value="0.8" TickFrequency="0.1" FontSize="20" IsSnapToTickEnabled="True" Value="1.0" TickFrequency="0.1"
TickPlacement="None" AutoToolTipPlacement="None" /> TickPlacement="None" AutoToolTipPlacement="None" />
<TextBlock VerticalAlignment="Center" Margin="12,0,16,0" FontSize="14" <TextBlock VerticalAlignment="Center" Margin="12,0,16,0" FontSize="14"
FontFamily="Consolas" FontFamily="Consolas"
+2 -2
View File
@@ -663,9 +663,9 @@ namespace Ink_Canvas
[JsonProperty("enableMLAvoidance")] [JsonProperty("enableMLAvoidance")]
public bool EnableMLAvoidance { get; set; } = true; public bool EnableMLAvoidance { get; set; } = true;
[JsonProperty("mlAvoidanceHistoryCount")] [JsonProperty("mlAvoidanceHistoryCount")]
public int MLAvoidanceHistoryCount { get; set; } = 20; public int MLAvoidanceHistoryCount { get; set; } = 50;
[JsonProperty("mlAvoidanceWeight")] [JsonProperty("mlAvoidanceWeight")]
public double MLAvoidanceWeight { get; set; } = 0.8; public double MLAvoidanceWeight { get; set; } = 1.0;
[JsonProperty("enableQuickDraw")] [JsonProperty("enableQuickDraw")]
public bool EnableQuickDraw { get; set; } = true; public bool EnableQuickDraw { get; set; } = true;
} }
+55 -14
View File
@@ -170,15 +170,15 @@ namespace Ink_Canvas
private static RollCallHistoryData historyData = null; private static RollCallHistoryData historyData = null;
private static readonly object historyLock = new object(); private static readonly object historyLock = new object();
private static int maxRecentHistory = 20; private static int maxRecentHistory = 20;
private static double avoidanceWeight = 0.8; // 避免重复的权重 private static double avoidanceWeight = 0.8;
private const double FREQUENCY_WEIGHT = 0.2; // 频率平衡的权重 private const double FREQUENCY_WEIGHT = 0.2;
// 概率相关 // 概率相关
private const double DEFAULT_PROBABILITY = 1.0; // 默认概率 private const double DEFAULT_PROBABILITY = 1.0;
private const double BASE_PROBABILITY_DECAY_FACTOR = 0.5; // 基础概率衰减因子 private const double BASE_PROBABILITY_DECAY_FACTOR = 0.5;
private const double MIN_PROBABILITY = 0.1; // 最小概率 private const double MIN_PROBABILITY = 0.01;
private const double PROBABILITY_RECOVERY_RATE = 0.1; // 概率恢复速率 private const double PROBABILITY_RECOVERY_RATE = 0.2;
private const double FREQUENCY_BOOST_FACTOR = 0.5; // 频率平衡增强因子 private const double FREQUENCY_BOOST_FACTOR = 2.0;
// 单次抽相关 // 单次抽相关
private bool isSingleDrawMode = false; private bool isSingleDrawMode = false;
@@ -692,13 +692,22 @@ namespace Ink_Canvas
// 计算频率差异比例 // 计算频率差异比例
double frequencyRatio = nameFrequency / averageFrequency; double frequencyRatio = nameFrequency / averageFrequency;
double boostFactor = FREQUENCY_BOOST_FACTOR * (1.0 - frequencyRatio); double frequencyGap = 1.0 - frequencyRatio;
double boostFactor = FREQUENCY_BOOST_FACTOR * frequencyGap * frequencyGap;
// 增加概率 // 增加概率
double boostedProbability = baseProbability * (1.0 + boostFactor); double boostedProbability = baseProbability * (1.0 + boostFactor);
// 限制最大概率,避免过高 return Math.Min(boostedProbability, DEFAULT_PROBABILITY * 10.0);
return Math.Min(boostedProbability, DEFAULT_PROBABILITY * 2.0); }
else if (nameFrequency > averageFrequency)
{
double frequencyRatio = nameFrequency / averageFrequency;
double reductionFactor = 1.0 - (frequencyRatio - 1.0) * 0.3;
reductionFactor = Math.Max(reductionFactor, MIN_PROBABILITY / DEFAULT_PROBABILITY);
return baseProbability * reductionFactor;
} }
return baseProbability; return baseProbability;
@@ -746,17 +755,28 @@ namespace Ink_Canvas
{ {
// 计算频率差异比例 // 计算频率差异比例
double frequencyRatio = nameFrequency / averageFrequency; double frequencyRatio = nameFrequency / averageFrequency;
double boostFactor = FREQUENCY_BOOST_FACTOR * (1.0 - frequencyRatio); double frequencyGap = 1.0 - frequencyRatio;
double boostFactor = FREQUENCY_BOOST_FACTOR * frequencyGap * frequencyGap;
// 增加概率 // 增加概率
double boostedProbability = currentProbability * (1.0 + boostFactor); double boostedProbability = currentProbability * (1.0 + boostFactor);
// 限制最大概率,避免过高 // 限制最大概率,避免过高
boostedProbability = Math.Min(boostedProbability, DEFAULT_PROBABILITY * 2.0); boostedProbability = Math.Min(boostedProbability, DEFAULT_PROBABILITY * 10.0);
// 保存更新后的概率 // 保存更新后的概率
historyData.NameProbabilities[name] = boostedProbability; historyData.NameProbabilities[name] = boostedProbability;
} }
else if (nameFrequency > averageFrequency)
{
double frequencyRatio = nameFrequency / averageFrequency;
double reductionFactor = 1.0 - (frequencyRatio - 1.0) * 0.3;
reductionFactor = Math.Max(reductionFactor, MIN_PROBABILITY / DEFAULT_PROBABILITY);
double reducedProbability = currentProbability * reductionFactor;
historyData.NameProbabilities[name] = reducedProbability;
}
} }
} }
@@ -893,8 +913,29 @@ namespace Ink_Canvas
// 降重:被选中的人员概率降低 // 降重:被选中的人员概率降低
double currentProbability = GetNameProbability(name); double currentProbability = GetNameProbability(name);
double decayFactor = BASE_PROBABILITY_DECAY_FACTOR * (1.0 + avoidanceWeight); double frequencyBasedDecay = 1.0;
decayFactor = Math.Min(decayFactor, 0.95); if (historyData.NameFrequency != null && historyData.NameFrequency.ContainsKey(name))
{
int totalSelections = historyData.NameFrequency.Values.Sum();
if (totalSelections > 0)
{
int uniqueNamesCount = historyData.NameFrequency.Keys.Count;
if (uniqueNamesCount > 0)
{
double nameFrequency = (double)historyData.NameFrequency[name] / totalSelections;
double averageFrequency = 1.0 / uniqueNamesCount;
if (nameFrequency > averageFrequency)
{
double frequencyRatio = nameFrequency / averageFrequency;
frequencyBasedDecay = 1.0 - (frequencyRatio - 1.0) * 0.2;
}
}
}
}
double decayFactor = BASE_PROBABILITY_DECAY_FACTOR * (1.0 + avoidanceWeight) * frequencyBasedDecay;
decayFactor = Math.Min(decayFactor, 0.85);
double newProbability = currentProbability * decayFactor; double newProbability = currentProbability * decayFactor;
newProbability = Math.Max(newProbability, MIN_PROBABILITY); // 确保不低于最小概率 newProbability = Math.Max(newProbability, MIN_PROBABILITY); // 确保不低于最小概率