private static int score(Station S, Group G, int Day, int Slot) { int ret = 0; int i, j; int groupIndex = getGroupIndex(G); // check if other constraints will be violated if this assignment happens. // station cap - 1 for the current assigmment int stationIndex = getStationIndex(S); int stationTotalAvailableSlotsLeft = stationTotalAvailabilityCounts[stationIndex, Day, Slot] - 1; int otherGroupsNeedThisStation = 0; if (stationTotalAvailableSlotsLeft < 0) { return -1000000; } // look for anyone else who wants this station. for (i = 0; i < AllConstraints.Count; i++) { if (ConstraintMet[i] || AllConstraints[i].S != S || AllConstraints[i].G == G) continue; otherGroupsNeedThisStation++; } if (otherGroupsNeedThisStation > stationTotalAvailableSlotsLeft) { ret += CONSTRAINT_PENALTY * (otherGroupsNeedThisStation - stationTotalAvailableSlotsLeft); } // nNotGettingPicks[0] is the count of groups that aren't getting their first picks because of this group int[] nNotGettingPicks = new int[5] { 0, 0, 0, 0, 0 }; // Check how many groups get their second pick instead of first, and how many groups aren't getting any picks // Copy the total assignment count for station, starting at this timeslot. int[] StationAssignmentsCountsTemp = new int[MAXN]; StationAssignmentsCountsTemp[stationIndex]++; int stationPickAvailableSlots; int nPossible; for (i = 0; i < AllGroups.Count; i++) { if(AllGroups[i].nStationsPicked >= 3 ) continue; nPossible = 0; for (j = 0; j < 5; j++) { if (AllGroups[i].StationPicks[j] == -1 || AllGroups[i].StationPicked[j] || AllStations[AllGroups[i].StationPicks[j]] != S) continue; int prefStationIndex = AllGroups[i].StationPicks[j]; nPossible++; stationPickAvailableSlots = stationTotalAvailabilityCounts[prefStationIndex, Day, Slot] - StationSlotAssignmentsCounts[prefStationIndex, Day, Slot] - StationAssignmentsCountsTemp[prefStationIndex]; if (stationPickAvailableSlots <= 0) nNotGettingPicks[j]++; else StationAssignmentsCountsTemp[AllGroups[i].StationPicks[j]]++; break; } } for (i = 0; i < 5; i++) ret += PREF_PENALTIES[i] * nNotGettingPicks[i]; // check if the same group was assigned to another station with the same category int nSameCat = 0; int nSameStation = 0; int nPins = 0; for (i = 1; i <= Slot; i++) { foreach (KeyValuePair<int, int> P in masterSchedule[Day, i]) { if( groupIndex == P.Key ) { if (P.Value != stationIndex && S.Category != "" && AllStations[P.Value].Category == S.Category) nSameCat++; else if (P.Value == stationIndex) nSameStation++; else if (AllStations[P.Value].isActivityPin && S.isActivityPin) nPins++; } } } ret += SAME_CATEGORY_PENALTY * nSameCat; ret += SAME_STATION_PENALTY * nSameStation; ret += SAME_STATION_PENALTY * ( nPins / 2); // if there is any entries in the old schedule, try to minimize them. bool isSameSched = false; foreach(KeyValuePair<int,int> P in oldMasterSchedule[Day,Slot]) { if (P.Key == groupIndex && P.Value == stationIndex) { isSameSched = true; break; } } if ( !generateNewScheduleFromScracth &&!isSameSched) ret += ASSIGNMENT_CHANGE_PENALTY; // space the station out, if it is a pin, space it out from another pin too int slotDifference = totalTimeSlots; KeyValuePair<int, int> Q; if( S.isActivityPin ) Q = lastDaySlotAssignedToPin[groupIndex]; else Q = lastDaySlotAssignedToStation[groupIndex, stationIndex]; if( Q.Key != -1 ) slotDifference = getNumberOfSlotDifference(Q.Key, Q.Value, Day, Slot); ret += (int)(1.0 * (totalTimeSlots - slotDifference) * NOT_SPACED_OUT_PENALTY); // if this station is a pin, and the group already got their preferences, don't schedule it if (S.isActivityPin && G.nStationsPicked == 3) ret += -1000; return ret; }
private static int getGroupIndex(Group g) { int i; for (i = 0; i < AllGroups.Count; i++) { if (AllGroups[i].ID == g.ID) return i; } return -1; }
public Constraint(Group g, Station s, int nV) { G = g; S = s; nVisits = nV; }
public Assignment(Group g, Station s) { G = g; S = s; }