Generating competition rankings
Descriptions of the various ranking strategies can be found here: Wikipedia: Ranking
Standard competition ranking, "1224"
Idea: Start with ranking 1, assign same as previous if score is equal, otherwise assign index + 1
.
// scores = [10, 15, 15, 20] (sorted)
int[] rankings = new int[scores.length];
rankings[0] = 1;
for (int i = 1; i < rankings.length; i++)
rankings[i] = scores[i] == scores[i - 1] ? rankings[i - 1] : i + 1;
// rankings = [1, 2, 2, 4]
Modified competition ranking, "1334"
Idea: Same as above, but start from the end:
int[] rankings = new int[scores.length];
rankings[scores.length - 1] = scores.length;
for (int i = rankings.length - 2; i >= 0; i--)
rankings[i] = scores[i] == scores[i + 1] ? rankings[i + 1] : i + 1;
// rankings = [1, 3, 3, 4]
Dense ranking, "1223"
Idea: Increment ranking only if current score differs from previous:
int[] rankings = new int[scores.length];
rankings[0] = 1;
for (int i = 1, r = 1; i < rankings.length; i++)
rankings[i] = scores[i] == scores[i - 1] ? r : ++r;
// rankings = [1, 2, 2, 3]
Ordinal ranking, "1234"
Trivial: Ranking equals index + 1
.
The key desirable property in ordinal ranking is that it's stable. Luckily Arrays.sort
, Collections.sort
and List.sort
are all stable.
Fractional ranking, "1 2½ 2½ 4"
List<Integer> clusters = new ArrayList<>();
clusters.add(1);
for (int i = 1; i < scores.length; i++) {
if (scores[i] == scores[i - 1]) {
int last = clusters.size() - 1;
clusters.set(last, clusters.get(last) + 1);
} else {
clusters.add(1);
}
}
double[] rankings = new double[scores.length];
int index = 0;
for (int cluster : clusters) {
double ranking = index + (1 + cluster) / 2.0;
Arrays.fill(rankings, index, index += cluster, ranking);
}
// rankings = [1, 2.5, 2.5, 4]
Comments
Be the first to comment!