"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cast_de_nrw_schule_svws_core_kursblockung_KursblockungAlgorithmusKMatching = exports.KursblockungAlgorithmusKMatching = void 0;
const KursblockungStatic_1 = require("../../core/kursblockung/KursblockungStatic");
const KursblockungAlgorithmusK_1 = require("../../core/kursblockung/KursblockungAlgorithmusK");
const System_1 = require("../../java/lang/System");
class KursblockungAlgorithmusKMatching extends KursblockungAlgorithmusK_1.KursblockungAlgorithmusK {
    static MAX_RUNDEN_IN_FOLGE_OHNE_VERBESSERUNG = 2000;
    schuelerAlle;
    /**
     * Im Konstruktor kann die Klasse die jeweiligen Datenstrukturen aufbauen. Kurse
     * dürfen in diese Methode noch nicht auf Schienen verteilt werden.
     *
     * @param pLogger Logger für Benutzerhinweise, Warnungen und Fehler.
     * @param pDynDat Die dynamischen Blockungsdaten.
     */
    constructor(pLogger, pDynDat) {
        super(pLogger, pDynDat);
        this.schuelerAlle = this.dynDaten.gibSchuelerArray(false);
    }
    /**
     * Der Algorithmus entfernt zunächst alle SuS aus ihren Kursen. Anschließend
     * werden die Kurse zufällig verteilt. Anschließend verändert der Algorithmus
     * die Lage eines zufälligen Kurses. Falls sich die Bewertung verschlechter,
     * wird die Veränderung rückgängig gemacht.
     */
    berechne(pMaxTimeMillis) {
        if (this.dynDaten.gibKurseDieFreiSindAnzahl() === 0) {
            return;
        }
        let timeStart = System_1.System.currentTimeMillis();
        this.dynDaten.aktionSchuelerAusAllenKursenEntfernen();
        this.dynDaten.aktionKurseFreieZufaelligVerteilen();
        this.dynDaten.aktionZustandSpeichernK();
        let countKeineVerbesserung = 0;
        while (System_1.System.currentTimeMillis() - timeStart < pMaxTimeMillis) {
            if (this.berechneSchritt()) {
                countKeineVerbesserung = 0;
            }
            else {
                countKeineVerbesserung++;
                if (countKeineVerbesserung === KursblockungAlgorithmusKMatching.MAX_RUNDEN_IN_FOLGE_OHNE_VERBESSERUNG) {
                    break;
                }
            }
        }
    }
    /**
     * Die Lage einiger Kurse wird verändert. Falls sich die Bewertung
     * verschlechter, wird die Veränderung rückgängig gemacht.
     */
    berechneSchritt() {
        let maxChanges = 1;
        while (Math.random() < 0.5) {
            maxChanges++;
        }
        for (let changes = 0; changes < maxChanges; changes++) {
            this.dynDaten.aktionSchuelerAusAllenKursenEntfernen();
            this.dynDaten.aktionKursFreienEinenZufaelligVerteilen();
            this.verteileSuS();
            if (this.dynDaten.gibBewertungJetztBesserAlsK() > 0) {
                this.dynDaten.aktionZustandSpeichernK();
                return true;
            }
        }
        this.dynDaten.aktionZustandLadenK();
        return false;
    }
    /**
     * Verteilt die SuS. Multikurse werden zufällig verteilt. Alle anderen Kurse mit
     * Hilfe eines Matching-Algorithmus.
     */
    verteileSuS() {
        let perm = KursblockungStatic_1.KursblockungStatic.gibPermutation(this.schuelerAlle.length);
        for (let p = 0; p < perm.length; p++) {
            let i = perm[p];
            let schueler = this.schuelerAlle[i];
            schueler.aktionKurseZufaelligVerteilen(true);
            schueler.aktionKurseMitBipartiteMatchingVerteilen();
        }
    }
    isTranspiledInstanceOf(name) {
        return ['de.nrw.schule.svws.core.kursblockung.KursblockungAlgorithmusK', 'de.nrw.schule.svws.core.kursblockung.KursblockungAlgorithmusKMatching'].includes(name);
    }
}
exports.KursblockungAlgorithmusKMatching = KursblockungAlgorithmusKMatching;
function cast_de_nrw_schule_svws_core_kursblockung_KursblockungAlgorithmusKMatching(obj) {
    return obj;
}
exports.cast_de_nrw_schule_svws_core_kursblockung_KursblockungAlgorithmusKMatching = cast_de_nrw_schule_svws_core_kursblockung_KursblockungAlgorithmusKMatching;
//# sourceMappingURL=KursblockungAlgorithmusKMatching.js.map