public static int scoreScheduleDiversity(IEnumerable<Models.Activity> schedule)
{
double score = 0;
double maxScore = 0;
var sortedSchedule =
from activity in schedule
orderby activity.Group.Name ascending, activity.TimeSlot.Start ascending
select activity;
IDictionary<Models.Group, List<Models.Activity>> groupSchedules =
new Dictionary<Models.Group, List<Models.Activity>>();
//create a dictionary with the groups mapping to their schedules
foreach (Models.Activity activity in sortedSchedule)
{
if (groupSchedules.ContainsKey(activity.Group))
{
groupSchedules[activity.Group].Add(activity);
}
else
{
List<Models.Activity> activities = new List<Models.Activity> { activity };
groupSchedules.Add(activity.Group, activities);
}
}
foreach (Models.Group group in groupSchedules.Keys)
{
maxScore += groupSchedules[group].Count() * groupSchedules[group].Count() * 2;
bool[] isVisited = new bool[groupSchedules[group].Count()];
for (int startingActivityNum = 0; startingActivityNum < groupSchedules[group].Count;
startingActivityNum++)
{
if (isVisited[startingActivityNum])
continue;
bool matchFound = false;
for (int nextActivityNum = startingActivityNum + 1; nextActivityNum < groupSchedules[group].Count;
nextActivityNum++)
{
if (groupSchedules[group][startingActivityNum].Station.isActivityPin)
{
nextActivityNum++;
if (nextActivityNum >= groupSchedules[group].Count)
break;
}
if (groupSchedules[group][startingActivityNum].Station.Name ==
groupSchedules[group][nextActivityNum].Station.Name)
{
matchFound = true;
isVisited[nextActivityNum] = true;
score += nextActivityNum - startingActivityNum;
}
}
if (!matchFound)
score += groupSchedules[group].Count * 2;
}
}
if (score == 0 || maxScore == 0)
return 0;
double scoreRatio = score / maxScore;
return (int) (scoreRatio * 1000);
}