private bool Matches(Expression <Action> expression) { this.state = CreateCall(expression); return(this.state.Matches()); }
private bool Matches(Expression<Action> expression) { this.state = CreateCall(expression); return this.state.Matches(); }
private static IEnumerable <ArgumentInfo> GetExpressionArguments(MethodCallExpression expression) { return(ConstraintState.GetArgumentInfos(expression.Arguments, expression.Method.GetParameters())); }
private Solution CreateInitialSolution() { const int chunkSize = 256; var hardPenalty = 0; var softPenalty = 0; var classStates = new ClassState[Classes.Length]; var studentStates = new StudentState[Students.Length]; for (var i = 0; i < classStates.Length; i++) { var classData = Classes[i]; classStates[i] = new ClassState( PullOne(classData.PossibleRooms, 1), PullOne(classData.PossibleSchedules, 1), 0, 0, 0, 0); } var totalPenaltyStudent = 0; var totalPenaltyTime = 0; var totalPenaltyRoom = 0; var totalPenaltyDistribution = 0; for (var i = 0; i < studentStates.Length; i++) { var studentData = Students[i]; var enrollmentStates = new List <EnrollmentState>(); var classesSoFar = new List <(Schedule schedule, int room)>(); var conflicts = 0; foreach (var courseId in studentData.Courses) { var course = Courses[courseId]; var chain = course.ClassChains[i % course.ClassChains.Length]; var enrollmentState = new EnrollmentState(chain.ConfigIndex, chain.Indexes); enrollmentStates.Add(enrollmentState); var enrolledSubparts = enrollmentState.Subparts; var config = course.Configurations[chain.ConfigIndex]; for (var j = 0; j < enrolledSubparts.Length; j++) { var subpart = config.Subparts[j]; var classIndex = enrolledSubparts[j]; var classObject = subpart.Classes[classIndex]; var classData = Classes[classObject.Id]; var classState = classStates[classObject.Id]; classStates[classObject.Id] = classState = classState .WithAttendees(classState.Attendees + 1, 0, 0); var schedule = classData.PossibleSchedules[classState.Time]; var room = classState.Room >= 0 ? classData.PossibleRooms[classState.Room].Id : -1; foreach (var(prevSchedule, prevRoom) in classesSoFar) { var travelTime = room >= 0 && prevRoom >= 0 ? TravelTimes[room, prevRoom] : 0; if (schedule.Overlaps(prevSchedule, travelTime)) { conflicts++; } } classesSoFar.Add((schedule, room)); } } softPenalty += conflicts * StudentPenalty; totalPenaltyStudent += conflicts; studentStates[i] = new StudentState(enrollmentStates.ToArray(), conflicts); } var classConflicts = 0; var roomsUnavailable = 0; var classOverflows = 0; for (var i = 0; i < classStates.Length; i++) { var state = classStates[i]; var classData = Classes[i]; var schedule = classData.PossibleSchedules[state.Time]; softPenalty += TimePenalty * schedule.Penalty; totalPenaltyTime += schedule.Penalty; var roomId = -1; var roomCapacityPenalty = 0; var roomUnavailablePenalty = 0; var classCapacityPenalty = state.Attendees > classData.Capacity ? Solution.ClassCapacityOverflowBase + (state.Attendees - classData.Capacity) / Solution.ClassCapacityOverflowRate : 0; classOverflows += classCapacityPenalty; if (state.Room >= 0) { var roomAssignment = classData.PossibleRooms[state.Room]; roomId = roomAssignment.Id; var room = Rooms[roomId]; roomCapacityPenalty = state.Attendees > room.Capacity ? Solution.RoomCapacityOverflowBase + (state.Attendees - room.Capacity) / Solution.RoomCapacityOverflowRate : 0; hardPenalty += roomCapacityPenalty; roomUnavailablePenalty = 0; foreach (var unavailableSchedule in room.UnavailableSchedules) { if (schedule.Overlaps(unavailableSchedule)) { roomUnavailablePenalty = 1; break; } } hardPenalty += roomUnavailablePenalty; roomsUnavailable += roomUnavailablePenalty; softPenalty += RoomPenalty * roomAssignment.Penalty; totalPenaltyRoom += roomAssignment.Penalty; } for (var j = 0; j < i; j++) { var otherClassState = classStates[j]; var otherClassData = Classes[j]; if (otherClassState.Room < 0) { continue; } var otherRoomId = otherClassData.PossibleRooms[otherClassState.Room].Id; if (roomId != otherRoomId) { continue; } var otherSchedule = otherClassData.PossibleSchedules[otherClassState.Time]; if (schedule.Overlaps(otherSchedule)) { classConflicts++; } } classStates[i] = new ClassState( state.Room, state.Time, state.Attendees, classCapacityPenalty, roomCapacityPenalty, roomUnavailablePenalty); } hardPenalty += classConflicts; var constraintStates = new ConstraintState[Constraints.Length]; var partialSolution = new Solution( this, hardPenalty, softPenalty, classOverflows, classConflicts, roomsUnavailable, new ChunkedArray <ClassState>(classStates, chunkSize), new ChunkedArray <StudentState>(studentStates, chunkSize), new ChunkedArray <ConstraintState>(constraintStates, chunkSize)); foreach (var constraint in Constraints) { var(h, s) = constraint.Evaluate(this, partialSolution); var normalized = (constraint.Required ? (double)h : s) / constraint.WorstCase; constraintStates[constraint.Id] = new ConstraintState(h, s, normalized); hardPenalty += h; softPenalty += s * DistributionPenalty; totalPenaltyDistribution += s; } var initialSolution = new Solution( this, hardPenalty, softPenalty, classOverflows, classConflicts, roomsUnavailable, new ChunkedArray <ClassState>(classStates, chunkSize), new ChunkedArray <StudentState>(studentStates, chunkSize), new ChunkedArray <ConstraintState>(constraintStates, chunkSize)); return(initialSolution); }