public static double rank(final Schedule schedule) {
		double rank;

		// the best distribution of schedules is that every slot has the same amount of sections
		final double mean = (double)Resources.getSections().size() / (double)Schedule.SLOTS;

		// variant
		double variant = 0.0;

		// slot counter, each int is the number of sections assigned to that slot
		// the array is always Scheulde.SLOTS long
		final int[] slotCounter = schedule.getSlotCounter();

		// initialize stats counters
		final int[] counters = schedule.getCounters();
		Arrays.fill(counters, 0);

		// calculate variant
		for(int i=0;i<slotCounter.length;i++)
			variant += ((double)slotCounter[i] - mean) * ((double)slotCounter[i] - mean);
		variant /= (double)slotCounter.length;

		if(variant > WEIGHT_VARIANT_THRESHOLD) {
			// variant is too big, discard this schedule
			rank = Double.POSITIVE_INFINITY;
		} else  {
			// add the weight
			rank = variant * WEGIHT_VARIANT;

			// get students' votes
			final Collection<Student> students = Resources.getStudents().values();
			for(final Student student : students) {
				rank += student.vote(schedule, counters);
				// a little bit optimization
				if(Double.isInfinite(rank)) break;
			}
		}
		// set the rank on the schedule
		schedule.setRank(rank);
		return rank;
	}