新增每门课程的“优先上课日 / 偏好节次范围”,与硬性可排范围分离。
遗传算法在满足冲突、容量、场地等硬约束后,优先满足课程偏好;偏好无法满足时仍会安排可行课次。 管理员可通过“课程偏好权重”控制偏好的影响程度。 修复遗传适应度:教室容量冗余、同一任务分散、日负载和实验场地偏好现在都会实际参与种群评分
This commit is contained in:
1 parent
94bc064697
commit
c4649f9cdc
10 files changed
+7403
-11
No files matched your search
@@ -50,6 +50,7 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
|
|||||||
settings.EarlyPeriodPenalty = request.EarlyPeriodPenalty;
|
settings.EarlyPeriodPenalty = request.EarlyPeriodPenalty;
|
||||||
settings.LatePeriodPenalty = request.LatePeriodPenalty;
|
settings.LatePeriodPenalty = request.LatePeriodPenalty;
|
||||||
settings.RoomCapacityWasteWeight = request.RoomCapacityWasteWeight;
|
settings.RoomCapacityWasteWeight = request.RoomCapacityWasteWeight;
|
||||||
|
settings.CoursePreferenceWeight = request.CoursePreferenceWeight;
|
||||||
await db.SaveChangesAsync(cancellationToken);
|
await db.SaveChangesAsync(cancellationToken);
|
||||||
return Ok(ToOptimizationSettingsResponse(settings));
|
return Ok(ToOptimizationSettingsResponse(settings));
|
||||||
}
|
}
|
||||||
@@ -80,7 +81,8 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
|
|||||||
settings.ConsecutiveClassWeight,
|
settings.ConsecutiveClassWeight,
|
||||||
settings.EarlyPeriodPenalty,
|
settings.EarlyPeriodPenalty,
|
||||||
settings.LatePeriodPenalty,
|
settings.LatePeriodPenalty,
|
||||||
settings.RoomCapacityWasteWeight
|
settings.RoomCapacityWasteWeight,
|
||||||
|
settings.CoursePreferenceWeight
|
||||||
};
|
};
|
||||||
|
|
||||||
[HttpPut("time-slots/{academicTermId:guid}")]
|
[HttpPut("time-slots/{academicTermId:guid}")]
|
||||||
@@ -189,6 +191,9 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
|
|||||||
AllowedDayOfWeeks = ParseDays(constraint?.AllowedDayOfWeeks),
|
AllowedDayOfWeeks = ParseDays(constraint?.AllowedDayOfWeeks),
|
||||||
constraint?.EarliestPeriod,
|
constraint?.EarliestPeriod,
|
||||||
constraint?.LatestPeriod,
|
constraint?.LatestPeriod,
|
||||||
|
PreferredDayOfWeeks = ParseDays(constraint?.PreferredDayOfWeeks),
|
||||||
|
constraint?.PreferredEarliestPeriod,
|
||||||
|
constraint?.PreferredLatestPeriod,
|
||||||
AllowedClassroomIds = constraint?.AllowedClassrooms
|
AllowedClassroomIds = constraint?.AllowedClassrooms
|
||||||
.Select(x => x.ClassroomId) ?? [],
|
.Select(x => x.ClassroomId) ?? [],
|
||||||
AllowedExperimentClassroomIds = constraint?.AllowedExperimentClassrooms
|
AllowedExperimentClassroomIds = constraint?.AllowedExperimentClassrooms
|
||||||
@@ -210,6 +215,12 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
|
|||||||
request.LatestPeriod.HasValue &&
|
request.LatestPeriod.HasValue &&
|
||||||
request.EarliestPeriod > request.LatestPeriod)
|
request.EarliestPeriod > request.LatestPeriod)
|
||||||
return ValidationProblem("最早节次不能晚于最晚节次。");
|
return ValidationProblem("最早节次不能晚于最晚节次。");
|
||||||
|
if (request.PreferredDayOfWeeks?.Any(day => day is < 1 or > 7) == true)
|
||||||
|
return ValidationProblem("偏好上课日必须位于星期一至星期日。");
|
||||||
|
if (request.PreferredEarliestPeriod.HasValue &&
|
||||||
|
request.PreferredLatestPeriod.HasValue &&
|
||||||
|
request.PreferredEarliestPeriod > request.PreferredLatestPeriod)
|
||||||
|
return ValidationProblem("偏好最早节次不能晚于偏好最晚节次。");
|
||||||
if (!Enum.IsDefined(request.SchedulingMode))
|
if (!Enum.IsDefined(request.SchedulingMode))
|
||||||
return ValidationProblem("授课方式无效。");
|
return ValidationProblem("授课方式无效。");
|
||||||
var task = await db.TeachingTasks
|
var task = await db.TeachingTasks
|
||||||
@@ -322,6 +333,11 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
|
|||||||
: string.Join(',', request.AllowedDayOfWeeks.Distinct().Order());
|
: string.Join(',', request.AllowedDayOfWeeks.Distinct().Order());
|
||||||
constraint.EarliestPeriod = request.EarliestPeriod;
|
constraint.EarliestPeriod = request.EarliestPeriod;
|
||||||
constraint.LatestPeriod = request.LatestPeriod;
|
constraint.LatestPeriod = request.LatestPeriod;
|
||||||
|
constraint.PreferredDayOfWeeks = request.PreferredDayOfWeeks?.Count > 0
|
||||||
|
? string.Join(',', request.PreferredDayOfWeeks.Distinct().Order())
|
||||||
|
: null;
|
||||||
|
constraint.PreferredEarliestPeriod = request.PreferredEarliestPeriod;
|
||||||
|
constraint.PreferredLatestPeriod = request.PreferredLatestPeriod;
|
||||||
constraint.AllowedExperimentVenueNatures = request.AllowedExperimentVenueNatures;
|
constraint.AllowedExperimentVenueNatures = request.AllowedExperimentVenueNatures;
|
||||||
db.TeachingTaskAllowedClassrooms.RemoveRange(constraint.AllowedClassrooms);
|
db.TeachingTaskAllowedClassrooms.RemoveRange(constraint.AllowedClassrooms);
|
||||||
db.TeachingTaskAllowedExperimentClassrooms.RemoveRange(constraint.AllowedExperimentClassrooms);
|
db.TeachingTaskAllowedExperimentClassrooms.RemoveRange(constraint.AllowedExperimentClassrooms);
|
||||||
@@ -566,6 +582,9 @@ public sealed class ScheduleSettingsController(AppDbContext db, IAppCache cache)
|
|||||||
constraint.AllowedDayOfWeeks = null;
|
constraint.AllowedDayOfWeeks = null;
|
||||||
constraint.EarliestPeriod = null;
|
constraint.EarliestPeriod = null;
|
||||||
constraint.LatestPeriod = null;
|
constraint.LatestPeriod = null;
|
||||||
|
constraint.PreferredDayOfWeeks = null;
|
||||||
|
constraint.PreferredEarliestPeriod = null;
|
||||||
|
constraint.PreferredLatestPeriod = null;
|
||||||
db.TeachingTaskAllowedClassrooms.RemoveRange(constraint.AllowedClassrooms);
|
db.TeachingTaskAllowedClassrooms.RemoveRange(constraint.AllowedClassrooms);
|
||||||
db.TeachingTaskAllowedExperimentClassrooms.RemoveRange(constraint.AllowedExperimentClassrooms);
|
db.TeachingTaskAllowedExperimentClassrooms.RemoveRange(constraint.AllowedExperimentClassrooms);
|
||||||
constraint.AllowedClassrooms = [];
|
constraint.AllowedClassrooms = [];
|
||||||
@@ -602,7 +621,8 @@ public sealed record ScheduleOptimizationSettingsRequest(
|
|||||||
[Range(0, 10_000)] int ConsecutiveClassWeight,
|
[Range(0, 10_000)] int ConsecutiveClassWeight,
|
||||||
[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);
|
||||||
|
|
||||||
public sealed record TeachingTaskScheduleConstraintRequest(
|
public sealed record TeachingTaskScheduleConstraintRequest(
|
||||||
TeachingTaskSchedulingMode SchedulingMode,
|
TeachingTaskSchedulingMode SchedulingMode,
|
||||||
@@ -616,7 +636,10 @@ public sealed record TeachingTaskScheduleConstraintRequest(
|
|||||||
TeachingVenueNature AllowedExperimentVenueNatures = 0,
|
TeachingVenueNature AllowedExperimentVenueNatures = 0,
|
||||||
IReadOnlyList<Guid>? AllowedExperimentClassroomIds = null,
|
IReadOnlyList<Guid>? AllowedExperimentClassroomIds = null,
|
||||||
Guid? ExperimentRequiredCampusId = null,
|
Guid? ExperimentRequiredCampusId = null,
|
||||||
Guid? ExperimentRequiredBuildingId = null);
|
Guid? ExperimentRequiredBuildingId = null,
|
||||||
|
IReadOnlyList<int>? PreferredDayOfWeeks = null,
|
||||||
|
[Range(1, 30)] int? PreferredEarliestPeriod = null,
|
||||||
|
[Range(1, 30)] int? PreferredLatestPeriod = null);
|
||||||
|
|
||||||
public sealed record TeachingTaskScheduleConstraintBatchRequest(
|
public sealed record TeachingTaskScheduleConstraintBatchRequest(
|
||||||
Guid AcademicTermId,
|
Guid AcademicTermId,
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public sealed class ScheduleOptimizationSettings : EntityBase
|
|||||||
public int EarlyPeriodPenalty { get; set; } = 30;
|
public int EarlyPeriodPenalty { get; set; } = 30;
|
||||||
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 static ScheduleOptimizationSettings CreateDefault(Guid academicTermId) =>
|
public static ScheduleOptimizationSettings CreateDefault(Guid academicTermId) =>
|
||||||
new() { AcademicTermId = academicTermId };
|
new() { AcademicTermId = academicTermId };
|
||||||
@@ -79,6 +80,9 @@ public sealed class TeachingTaskScheduleConstraint : EntityBase
|
|||||||
public string? AllowedDayOfWeeks { get; set; }
|
public string? AllowedDayOfWeeks { get; set; }
|
||||||
public int? EarliestPeriod { get; set; }
|
public int? EarliestPeriod { get; set; }
|
||||||
public int? LatestPeriod { get; set; }
|
public int? LatestPeriod { get; set; }
|
||||||
|
public string? PreferredDayOfWeeks { get; set; }
|
||||||
|
public int? PreferredEarliestPeriod { get; set; }
|
||||||
|
public int? PreferredLatestPeriod { get; set; }
|
||||||
public TeachingVenueNature AllowedExperimentVenueNatures { get; set; }
|
public TeachingVenueNature AllowedExperimentVenueNatures { get; set; }
|
||||||
public ICollection<TeachingTaskAllowedClassroom> AllowedClassrooms { get; set; } = [];
|
public ICollection<TeachingTaskAllowedClassroom> AllowedClassrooms { get; set; } = [];
|
||||||
public ICollection<TeachingTaskAllowedExperimentClassroom> AllowedExperimentClassrooms { get; set; } = [];
|
public ICollection<TeachingTaskAllowedExperimentClassroom> AllowedExperimentClassrooms { get; set; } = [];
|
||||||
|
|||||||
@@ -532,6 +532,7 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
|
|||||||
builder.Entity<TeachingTaskScheduleConstraint>(entity =>
|
builder.Entity<TeachingTaskScheduleConstraint>(entity =>
|
||||||
{
|
{
|
||||||
entity.Property(x => x.AllowedDayOfWeeks).HasMaxLength(20);
|
entity.Property(x => x.AllowedDayOfWeeks).HasMaxLength(20);
|
||||||
|
entity.Property(x => x.PreferredDayOfWeeks).HasMaxLength(20);
|
||||||
entity.HasIndex(x => x.TeachingTaskId).IsUnique();
|
entity.HasIndex(x => x.TeachingTaskId).IsUnique();
|
||||||
entity.HasOne(x => x.TeachingTask)
|
entity.HasOne(x => x.TeachingTask)
|
||||||
.WithMany()
|
.WithMany()
|
||||||
|
|||||||
Loaded 3 of 10 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user