Fix scores calculation problem: all pairables must be known

This commit is contained in:
Claude Brisson
2024-05-29 10:09:25 +02:00
parent 6dc634df7e
commit d93122a13b
6 changed files with 21 additions and 12 deletions

View File

@@ -40,7 +40,7 @@ fun Tournament<*>.getSortedPairables(round: Int): List<Json.Object> {
it.value.let { pairable -> it.value.let { pairable ->
val mmBase = pairable.mmBase() val mmBase = pairable.mmBase()
val score = roundScore(mmBase + val score = roundScore(mmBase +
(nbW(pairable) ?: 0.0) + // TODO take tournament parameter into account (nbW(pairable) ?: 0.0) +
(1..round).map { round -> (1..round).map { round ->
if (playersPerRound.getOrNull(round - 1)?.contains(pairable.id) == true) 0 else 1 if (playersPerRound.getOrNull(round - 1)?.contains(pairable.id) == true) 0 else 1
}.sum() * pairing.pairingParams.main.mmsValueAbsent) }.sum() * pairing.pairingParams.main.mmsValueAbsent)

View File

@@ -174,7 +174,7 @@ class Swiss(
): Pairing(SWISS, pairingParams, placementParams) { ): Pairing(SWISS, pairingParams, placementParams) {
companion object {} companion object {}
override fun solver(tournament: Tournament<*>, round: Int, pairables: List<Pairable>) = override fun solver(tournament: Tournament<*>, round: Int, pairables: List<Pairable>) =
SwissSolver(round, tournament.rounds, tournament.historyBefore(round), pairables, pairingParams, placementParams, tournament.usedTables(round)) SwissSolver(round, tournament.rounds, tournament.historyBefore(round), pairables, tournament.pairables, pairingParams, placementParams, tournament.usedTables(round))
} }
class MacMahon( class MacMahon(
@@ -202,7 +202,7 @@ class MacMahon(
): Pairing(MAC_MAHON, pairingParams, placementParams) { ): Pairing(MAC_MAHON, pairingParams, placementParams) {
companion object {} companion object {}
override fun solver(tournament: Tournament<*>, round: Int, pairables: List<Pairable>) = override fun solver(tournament: Tournament<*>, round: Int, pairables: List<Pairable>) =
MacMahonSolver(round, tournament.rounds, tournament.historyBefore(round), pairables, pairingParams, placementParams, tournament.usedTables(round), mmFloor, mmBar) MacMahonSolver(round, tournament.rounds, tournament.historyBefore(round), pairables, tournament.pairables, pairingParams, placementParams, tournament.usedTables(round), mmFloor, mmBar)
} }
class RoundRobin( class RoundRobin(

View File

@@ -1,13 +1,13 @@
package org.jeudego.pairgoth.pairing package org.jeudego.pairgoth.pairing
import org.jeudego.pairgoth.model.* import org.jeudego.pairgoth.model.*
import java.util.*
abstract class BasePairingHelper( abstract class BasePairingHelper(
val round: Int, val round: Int,
val totalRounds: Int, val totalRounds: Int,
history: List<List<Game>>, // History of all games played for each round history: List<List<Game>>, // History of all games played for each round
var pairables: List<Pairable>, // All pairables for this round, it may include the bye player var pairables: List<Pairable>, // All pairables for this round, it may include the bye player
val pairablesMap: Map<ID, Pairable>, // Map of all known pairables for this tournament
val pairing: PairingParams, val pairing: PairingParams,
val placement: PlacementParams, val placement: PlacementParams,
) { ) {
@@ -41,10 +41,6 @@ abstract class BasePairingHelper(
pairables.sortedWith(::nameSort).toMutableList() pairables.sortedWith(::nameSort).toMutableList()
} }
protected val pairablesMap by lazy {
pairables.associateBy { it.id }
}
// Generic parameters calculation // Generic parameters calculation
//private val standingScore by lazy { computeStandingScore() } //private val standingScore by lazy { computeStandingScore() }

View File

@@ -11,20 +11,24 @@ import org.jgrapht.alg.matching.blossom.v5.ObjectiveSense
import org.jgrapht.graph.DefaultWeightedEdge import org.jgrapht.graph.DefaultWeightedEdge
import org.jgrapht.graph.SimpleDirectedWeightedGraph import org.jgrapht.graph.SimpleDirectedWeightedGraph
import org.jgrapht.graph.builder.GraphBuilder import org.jgrapht.graph.builder.GraphBuilder
import org.slf4j.LoggerFactory
import java.io.PrintWriter import java.io.PrintWriter
import java.text.DecimalFormat import java.text.DecimalFormat
import java.util.* import java.util.*
import kotlin.math.* import kotlin.math.*
val logger = LoggerFactory.getLogger("debug")
sealed class BaseSolver( sealed class BaseSolver(
round: Int, round: Int,
totalRounds: Int, totalRounds: Int,
history: List<List<Game>>, // History of all games played for each round history: List<List<Game>>, // History of all games played for each round
pairables: List<Pairable>, // All pairables for this round, it may include the bye player pairables: List<Pairable>, // All pairables for this round, it may include the bye player
pairablesMap: Map<ID, Pairable>, // Map of all known pairables in this tournament
pairing: PairingParams, pairing: PairingParams,
placement: PlacementParams, placement: PlacementParams,
val usedTables: BitSet val usedTables: BitSet
) : BasePairingHelper(round, totalRounds, history, pairables, pairing, placement) { ) : BasePairingHelper(round, totalRounds, history, pairables, pairablesMap, pairing, placement) {
companion object { companion object {
val rand = Random(/* seed from properties - TODO */) val rand = Random(/* seed from properties - TODO */)
@@ -85,6 +89,13 @@ sealed class BaseSolver(
pairingSortedPairables.remove(ByePlayer) pairingSortedPairables.remove(ByePlayer)
} }
if (round == 4) {
logger.info("@@@@@ Round 4 @@@@@")
for (p in sortedPairables) {
logger.info("#${p.id} ${p.name} ${scores[p.id]?.first} ${scores[p.id]?.second} ${p.sos}")
}
}
for (i in nameSortedPairables.indices) { for (i in nameSortedPairables.indices) {
for (j in i + 1 until nameSortedPairables.size) { for (j in i + 1 until nameSortedPairables.size) {
val p = nameSortedPairables[i] val p = nameSortedPairables[i]

View File

@@ -10,11 +10,12 @@ class MacMahonSolver(round: Int,
totalRounds: Int, totalRounds: Int,
history: List<List<Game>>, history: List<List<Game>>,
pairables: List<Pairable>, pairables: List<Pairable>,
pairablesMap: Map<ID, Pairable>,
pairingParams: PairingParams, pairingParams: PairingParams,
placementParams: PlacementParams, placementParams: PlacementParams,
usedTables: BitSet, usedTables: BitSet,
private val mmFloor: Int, private val mmBar: Int) : private val mmFloor: Int, private val mmBar: Int) :
BaseSolver(round, totalRounds, history, pairables, pairingParams, placementParams, usedTables) { BaseSolver(round, totalRounds, history, pairables, pairablesMap, pairingParams, placementParams, usedTables) {
override val scores: Map<ID, Pair<Double, Double>> by lazy { override val scores: Map<ID, Pair<Double, Double>> by lazy {
require (mmBar > mmFloor) { "MMFloor is higher than MMBar" } require (mmBar > mmFloor) { "MMFloor is higher than MMBar" }
@@ -22,7 +23,7 @@ class MacMahonSolver(round: Int,
pairablesMap.mapValues { pairablesMap.mapValues {
it.value.let { pairable -> it.value.let { pairable ->
val score = roundScore(pairable.mmBase + val score = roundScore(pairable.mmBase +
pairable.nbW + // TODO take tournament parameter into account pairable.nbW +
pairable.missedRounds(round, pairing) * pairingParams.main.mmsValueAbsent) pairable.missedRounds(round, pairing) * pairingParams.main.mmsValueAbsent)
Pair( Pair(
if (pairingParams.main.sosValueAbsentUseBase) pairable.mmBase if (pairingParams.main.sosValueAbsentUseBase) pairable.mmBase

View File

@@ -7,11 +7,12 @@ class SwissSolver(round: Int,
totalRounds: Int, totalRounds: Int,
history: List<List<Game>>, history: List<List<Game>>,
pairables: List<Pairable>, pairables: List<Pairable>,
pairablesMap: Map<ID, Pairable>,
pairingParams: PairingParams, pairingParams: PairingParams,
placementParams: PlacementParams, placementParams: PlacementParams,
usedTables: BitSet usedTables: BitSet
): ):
BaseSolver(round, totalRounds, history, pairables, pairingParams, placementParams, usedTables) { BaseSolver(round, totalRounds, history, pairables, pairablesMap, pairingParams, placementParams, usedTables) {
// In a Swiss tournament the main criterion is the number of wins and already computed // In a Swiss tournament the main criterion is the number of wins and already computed