Update Swiss tournament pairing - For the last round, for each unpaired player pair against the highest ranked player they haven't played against

This commit is contained in:
Quercitron 2015-11-20 02:54:50 +03:00
parent b30a6c4b15
commit 7e58dc70d5
3 changed files with 44 additions and 29 deletions

View file

@ -68,10 +68,11 @@ public abstract class TournamentSwiss extends TournamentImpl {
protected Round createRoundSwiss() {
List<TournamentPlayer> roundPlayers = getActivePlayers();
boolean isLastRound = (rounds.size() + 1 == getNumberRounds());
RoundPairings roundPairings;
if (roundPlayers.size() <= 16) {
SwissPairingMinimalWeightMatching swissPairing = new SwissPairingMinimalWeightMatching(roundPlayers, rounds);
SwissPairingMinimalWeightMatching swissPairing = new SwissPairingMinimalWeightMatching(roundPlayers, rounds, isLastRound);
roundPairings = swissPairing.getRoundPairings();
} else {
SwissPairingSimple swissPairing = new SwissPairingSimple(roundPlayers, rounds);
@ -86,7 +87,7 @@ public abstract class TournamentSwiss extends TournamentImpl {
for (TournamentPlayer playerBye : roundPairings.getPlayerByes()) {
// player free round - add to bye players of this round
round.getPlayerByes().add(playerBye);
if (round.getRoundNumber() == getNumberRounds()) {
if (isLastRound) {
playerBye.setState(TournamentPlayerState.FINISHED);
} else {
playerBye.setState(TournamentPlayerState.WAITING);

View file

@ -57,7 +57,7 @@ public class SwissPairingMinimalWeightMatching {
// weight of pairings
private final int[][] w;
public SwissPairingMinimalWeightMatching(List<TournamentPlayer> players, List<Round> rounds) {
public SwissPairingMinimalWeightMatching(List<TournamentPlayer> players, List<Round> rounds, boolean isLastRound) {
playersCount = players.size();
swissPlayers = new ArrayList<PlayerInfo>();
@ -147,29 +147,42 @@ public class SwissPairingMinimalWeightMatching {
// calculate weight
// try to pair players with equal scores
w = new int[n][n];
for (int i = 0; i < playersCount; i++) {
PlayerInfo player = swissPlayers.get(i);
for (int p = player.points; p >= 0 ; p--) {
int first = -1;
int last = -1;
for (int j = 0; j < playersCount; j++) {
if (swissPlayers.get(j).points == p) {
if (first < 0) {
first = j;
}
last = j;
}
}
if (first < 0) {
continue;
}
int self = (p == player.points ? i : first - 1);
int diff = 10 * (player.points - p);
for (int j = Math.max(first, i); j <= last; j++) {
w[i][j] = Math.abs(j - (last + first - self)) + diff;
int pointsDiffMultiplier = 10;
if (isLastRound) {
// for the last round, for each unpaired player starting with the first place, pair
// against the highest ranked player they haven't played against
for (int i = 0; i < playersCount; i++) {
for (int j = 0; j < i; j++) {
w[i][j] = Math.abs(i - j) +
pointsDiffMultiplier * Math.abs(swissPlayers.get(i).points - swissPlayers.get(j).points);
w[j][i] = w[i][j];
}
}
} else {
for (int i = 0; i < playersCount; i++) {
PlayerInfo player = swissPlayers.get(i);
for (int p = player.points; p >= 0; p--) {
int first = -1;
int last = -1;
for (int j = 0; j < playersCount; j++) {
if (swissPlayers.get(j).points == p) {
if (first < 0) {
first = j;
}
last = j;
}
}
if (first < 0) {
continue;
}
int self = (p == player.points ? i : first - 1);
int diff = pointsDiffMultiplier * (player.points - p);
for (int j = Math.max(first, i); j <= last; j++) {
w[i][j] = Math.abs(j - (last + first - self)) + diff;
w[j][i] = w[i][j];
}
}
}
}
// avoid pairing players that have played each other already