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;
}