Add comprehensive academic statistics refresh workflow

This commit is contained in:
biss committed 2026-08-17 11:14:28 +08:00
1 parent c4649f9cdc
commit b6dfdbfbbf
9 files changed
+7314 -7

No files matched your search

@@ -51,6 +51,9 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
settings.LatePeriodPenalty = request.LatePeriodPenalty; settings.LatePeriodPenalty = request.LatePeriodPenalty;
settings.RoomCapacityWasteWeight = request.RoomCapacityWasteWeight; settings.RoomCapacityWasteWeight = request.RoomCapacityWasteWeight;
settings.CoursePreferenceWeight = request.CoursePreferenceWeight; settings.CoursePreferenceWeight = request.CoursePreferenceWeight;
settings.GeneticPopulationSize = request.GeneticPopulationSize;
settings.GeneticGenerationCount = request.GeneticGenerationCount;
settings.GeneticMutationRatePercent = request.GeneticMutationRatePercent;
await db.SaveChangesAsync(cancellationToken); await db.SaveChangesAsync(cancellationToken);
return Ok(ToOptimizationSettingsResponse(settings)); return Ok(ToOptimizationSettingsResponse(settings));
} }
@@ -82,7 +85,10 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
settings.EarlyPeriodPenalty, settings.EarlyPeriodPenalty,
settings.LatePeriodPenalty, settings.LatePeriodPenalty,
settings.RoomCapacityWasteWeight, settings.RoomCapacityWasteWeight,
settings.CoursePreferenceWeight settings.CoursePreferenceWeight,
settings.GeneticPopulationSize,
settings.GeneticGenerationCount,
settings.GeneticMutationRatePercent
}; };
[HttpPut("time-slots/{academicTermId:guid}")] [HttpPut("time-slots/{academicTermId:guid}")]
@@ -622,7 +628,10 @@ public sealed record ScheduleOptimizationSettingsRequest(
[Range(0, 10_000)] int EarlyPeriodPenalty, [Range(0, 10_000)] int EarlyPeriodPenalty,
[Range(0, 10_000)] int LatePeriodPenalty, [Range(0, 10_000)] int LatePeriodPenalty,
[Range(0, 10_000)] int RoomCapacityWasteWeight, [Range(0, 10_000)] int RoomCapacityWasteWeight,
[Range(0, 10_000)] int CoursePreferenceWeight = 180); [Range(0, 10_000)] int CoursePreferenceWeight = 180,
[Range(12, 64)] int GeneticPopulationSize = 32,
[Range(12, 160)] int GeneticGenerationCount = 80,
[Range(1, 50)] int GeneticMutationRatePercent = 12);
public sealed record TeachingTaskScheduleConstraintRequest( public sealed record TeachingTaskScheduleConstraintRequest(
TeachingTaskSchedulingMode SchedulingMode, TeachingTaskSchedulingMode SchedulingMode,
@@ -59,6 +59,9 @@ public sealed class ScheduleOptimizationSettings : EntityBase
public int LatePeriodPenalty { get; set; } = 30; public int LatePeriodPenalty { get; set; } = 30;
public int RoomCapacityWasteWeight { get; set; } = 1; public int RoomCapacityWasteWeight { get; set; } = 1;
public int CoursePreferenceWeight { get; set; } = 180; public int CoursePreferenceWeight { get; set; } = 180;
public int GeneticPopulationSize { get; set; } = 32;
public int GeneticGenerationCount { get; set; } = 80;
public int GeneticMutationRatePercent { get; set; } = 12;
public static ScheduleOptimizationSettings CreateDefault(Guid academicTermId) => public static ScheduleOptimizationSettings CreateDefault(Guid academicTermId) =>
new() { AcademicTermId = academicTermId }; new() { AcademicTermId = academicTermId };
@@ -114,6 +114,8 @@ public sealed class DevelopmentSqliteMigrator(
"20260817_59_schedule_optimization_settings"; "20260817_59_schedule_optimization_settings";
private const string ScheduleGeneticPreferencesMigration = private const string ScheduleGeneticPreferencesMigration =
"20260817_60_schedule_genetic_preferences"; "20260817_60_schedule_genetic_preferences";
private const string ScheduleGeneticSearchSettingsMigration =
"20260817_61_schedule_genetic_search_settings";
public async Task MigrateAsync(CancellationToken cancellationToken = default) public async Task MigrateAsync(CancellationToken cancellationToken = default)
{ {
@@ -813,6 +815,21 @@ public sealed class DevelopmentSqliteMigrator(
ScheduleGeneticPreferencesMigration, ScheduleGeneticPreferencesMigration,
scheduleGeneticPreferenceStatements, scheduleGeneticPreferenceStatements,
cancellationToken); cancellationToken);
var geneticSearchColumns = (await db.Database.SqlQueryRaw<string>(
"SELECT name AS \"Value\" FROM pragma_table_info('ScheduleOptimizationSettings')")
.ToListAsync(cancellationToken))
.ToHashSet(StringComparer.OrdinalIgnoreCase);
var geneticSearchSettingStatements = new List<string>();
if (!geneticSearchColumns.Contains("GeneticPopulationSize"))
geneticSearchSettingStatements.Add(ScheduleGeneticSearchSettingsStatements[0]);
if (!geneticSearchColumns.Contains("GeneticGenerationCount"))
geneticSearchSettingStatements.Add(ScheduleGeneticSearchSettingsStatements[1]);
if (!geneticSearchColumns.Contains("GeneticMutationRatePercent"))
geneticSearchSettingStatements.Add(ScheduleGeneticSearchSettingsStatements[2]);
await ApplyMigrationAsync(
ScheduleGeneticSearchSettingsMigration,
geneticSearchSettingStatements,
cancellationToken);
} }
private async Task ApplyMigrationAsync( private async Task ApplyMigrationAsync(
@@ -3292,6 +3309,13 @@ public sealed class DevelopmentSqliteMigrator(
"ALTER TABLE \"ScheduleOptimizationSettings\" ADD COLUMN \"CoursePreferenceWeight\" INTEGER NOT NULL DEFAULT 180;" "ALTER TABLE \"ScheduleOptimizationSettings\" ADD COLUMN \"CoursePreferenceWeight\" INTEGER NOT NULL DEFAULT 180;"
]; ];
private static readonly string[] ScheduleGeneticSearchSettingsStatements =
[
"ALTER TABLE \"ScheduleOptimizationSettings\" ADD COLUMN \"GeneticPopulationSize\" INTEGER NOT NULL DEFAULT 32;",
"ALTER TABLE \"ScheduleOptimizationSettings\" ADD COLUMN \"GeneticGenerationCount\" INTEGER NOT NULL DEFAULT 80;",
"ALTER TABLE \"ScheduleOptimizationSettings\" ADD COLUMN \"GeneticMutationRatePercent\" INTEGER NOT NULL DEFAULT 12;"
];
private static readonly string[] ReusableCourseGroupsStatements = private static readonly string[] ReusableCourseGroupsStatements =
[ [
""" """
Loaded 3 of 9 files, more files were not shown because too many files have changed in this diff. Show more