KursblockungDynSchueler.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.cast_de_nrw_schule_svws_core_kursblockung_KursblockungDynSchueler = exports.KursblockungDynSchueler = void 0;
  4. const JavaObject_1 = require("../../java/lang/JavaObject");
  5. const KursblockungStatic_1 = require("../../core/kursblockung/KursblockungStatic");
  6. const KursblockungMatrix_1 = require("../../core/kursblockung/KursblockungMatrix");
  7. const System_1 = require("../../java/lang/System");
  8. const KursblockungOutputFachwahlZuKurs_1 = require("../../core/data/kursblockung/KursblockungOutputFachwahlZuKurs");
  9. class KursblockungDynSchueler extends JavaObject_1.JavaObject {
  10. representation;
  11. fachartArr;
  12. fachartZuGUI;
  13. fachartZuKurs;
  14. fachartZuKursSaveS;
  15. fachartZuKursSaveK;
  16. statistik;
  17. nichtwahlen = 0;
  18. schieneBelegt;
  19. static dummy = new KursblockungMatrix_1.KursblockungMatrix(0, 0);
  20. matrix;
  21. /**
  22. * Im Konstruktor wird {@code pSchueler} in ein Objekt dieser Klasse
  23. * umgewandelt.
  24. *
  25. * @param pStatistik Referenz um die Nichtwahlen mitzuteilen.
  26. * @param pSchueler Die Schüler-Daten von der GUI/DB.
  27. * @param pSchienenAnzahl Wir benötigt, um {@link #schieneBelegt} zu
  28. * initialisieren.
  29. */
  30. constructor(pSchueler, pStatistik, pSchienenAnzahl) {
  31. super();
  32. this.representation = pSchueler.representation;
  33. this.statistik = pStatistik;
  34. this.fachartArr = Array(0).fill(null);
  35. this.fachartZuGUI = Array(0).fill(0);
  36. this.fachartZuKurs = Array(0).fill(null);
  37. this.fachartZuKursSaveS = Array(0).fill(null);
  38. this.fachartZuKursSaveK = Array(0).fill(null);
  39. this.nichtwahlen = 0;
  40. this.schieneBelegt = Array(pSchienenAnzahl).fill(false);
  41. this.matrix = KursblockungDynSchueler.dummy;
  42. }
  43. toString() {
  44. return this.representation;
  45. }
  46. /**
  47. * Eine String-Darstellung des Schülers. Beinhaltet meistens den Vornamen, den
  48. * Nachnamen, das Geburtsdatum und das Geschlecht.
  49. *
  50. * @return Eine String-Darstellung des Schülers.
  51. */
  52. gibRepresentation() {
  53. return this.representation;
  54. }
  55. /**
  56. * Liefert die aktuelle Anzahl an Nichtwahlen.
  57. *
  58. * @return Die aktuelle Anzahl an Nichtwahlen.
  59. */
  60. gibNichtwahlen() {
  61. return this.nichtwahlen;
  62. }
  63. /**
  64. * Liefert ein Array aller Facherten (= Fachwahlen) des Schülers.
  65. *
  66. * @return Ein Array aller Facherten (= Fachwahlen) des Schülers.
  67. */
  68. gibFacharten() {
  69. return this.fachartArr;
  70. }
  71. /**
  72. * Setzt alle Facharten (=Fachwahlen) des Schülers.
  73. *
  74. * @param pFacharten Die Facharten des Schülers.
  75. * @param pIDs Die zur Fachwahl zugehörige ID der GUI bzw. Datenbank.
  76. */
  77. aktionSetzeFachartenUndIDs(pFacharten, pIDs) {
  78. let nFacharten = pFacharten.length;
  79. this.fachartArr = pFacharten;
  80. this.fachartZuGUI = pIDs;
  81. this.fachartZuKurs = Array(nFacharten).fill(null);
  82. this.fachartZuKursSaveS = Array(nFacharten).fill(null);
  83. this.fachartZuKursSaveK = Array(nFacharten).fill(null);
  84. this.statistik.aktionNichtwahlenVeraendern(nFacharten);
  85. this.nichtwahlen = nFacharten;
  86. for (let i = 1; i < nFacharten; i++) {
  87. for (let j = i; j >= 1; j--) {
  88. let anzL = this.fachartArr[j - 1].gibKurseMax();
  89. let anzR = this.fachartArr[j].gibKurseMax();
  90. if (anzL > anzR) {
  91. let fL = this.fachartArr[j - 1];
  92. let fR = this.fachartArr[j];
  93. let valL = this.fachartZuGUI[j - 1];
  94. let valR = this.fachartZuGUI[j];
  95. this.fachartArr[j - 1] = fR;
  96. this.fachartArr[j] = fL;
  97. this.fachartZuGUI[j - 1] = valR;
  98. this.fachartZuGUI[j] = valL;
  99. }
  100. }
  101. }
  102. this.matrix = new KursblockungMatrix_1.KursblockungMatrix(nFacharten, this.schieneBelegt.length);
  103. }
  104. /**
  105. * Speichert die aktuell belegten Kurse im Zustand S.
  106. */
  107. aktionZustandSpeichernS() {
  108. System_1.System.arraycopy(this.fachartZuKurs, 0, this.fachartZuKursSaveS, 0, this.fachartZuKurs.length);
  109. }
  110. /**
  111. * Speichert die aktuell belegten Kurse im Zustand K.
  112. */
  113. aktionZustandSpeichernK() {
  114. System_1.System.arraycopy(this.fachartZuKurs, 0, this.fachartZuKursSaveK, 0, this.fachartZuKurs.length);
  115. }
  116. /**
  117. * Entfernt zunächst den Schüler aus seinen aktuellen Kursen und setzt ihn dann
  118. * in die Kurse, die zuvor im Zustand S gespeichert wurden.
  119. */
  120. aktionZustandLadenS() {
  121. this.aktionWaehleKurse(this.fachartZuKursSaveS);
  122. }
  123. /**
  124. * Entfernt zunächst den Schüler aus seinen aktuellen Kursen und setzt ihn dann
  125. * in die Kurse, die zuvor im Zustand K gespeichert wurden.
  126. */
  127. aktionZustandLadenK() {
  128. this.aktionWaehleKurse(this.fachartZuKursSaveK);
  129. }
  130. aktionWaehleKurse(wahl) {
  131. this.aktionKurseAlleEntfernen();
  132. for (let i = 0; i < this.fachartZuKurs.length; i++) {
  133. let kurs = wahl[i];
  134. if (kurs !== null) {
  135. this.aktionKursHinzufuegen(i, kurs);
  136. }
  137. }
  138. }
  139. /**
  140. * Entfernt den Schüler aus seinen aktuell zugeordneten Kursen.
  141. */
  142. aktionKurseAlleEntfernen() {
  143. for (let i = 0; i < this.fachartArr.length; i++) {
  144. let kurs = this.fachartZuKurs[i];
  145. if (kurs !== null) {
  146. this.aktionKursEntfernen(i, kurs);
  147. }
  148. }
  149. }
  150. /**
  151. * Geht die Facharten durch (Facharten mit einer kleineren Kursanzahl zuerst)
  152. * und geht dann pro Fachart alle Kurse durch (Kurse mit kleinerer Schüleranzahl
  153. * zuerst). Falls der Kurs wählbar ist, wird der Schüler hinzugefügt und es geht
  154. * weiter mit der nächsten Fachart. Ein Kurs ist wählbar, wenn nicht bereits ein
  155. * Kurs zugeordnet wurde und die Schienen in den der Kurs sind frei sind.<br>
  156. *
  157. * Falls der Paramter {@code pNurMultikurse} TRUE ist, dann werden nur
  158. * Multikurse verteilt.
  159. *
  160. * @param pNurMultikurse Falls TRUE ist, dann werden nur Multikurse verteilt.
  161. */
  162. aktionKurseZufaelligVerteilen(pNurMultikurse) {
  163. let perm = KursblockungStatic_1.KursblockungStatic.gibPermutation(this.fachartArr.length);
  164. for (let p = 0; p < this.fachartArr.length; p++) {
  165. let i = perm[p];
  166. if (this.fachartZuKurs[i] !== null) {
  167. continue;
  168. }
  169. let fachart = this.fachartArr[i];
  170. if (pNurMultikurse) {
  171. if (!fachart.gibHatMultikurs()) {
  172. continue;
  173. }
  174. }
  175. let kurse = fachart.gibKurse();
  176. let perm2 = KursblockungStatic_1.KursblockungStatic.gibPermutation(kurse.length);
  177. for (let p2 = 0; p2 < perm2.length; p2++) {
  178. let i2 = p2;
  179. let kurs = kurse[i2];
  180. let waehlbar = true;
  181. for (let nr of kurs.gibSchienenLage()) {
  182. if (this.schieneBelegt[nr]) {
  183. waehlbar = false;
  184. }
  185. }
  186. if (waehlbar) {
  187. this.aktionKursHinzufuegen(i, kurs);
  188. break;
  189. }
  190. }
  191. }
  192. }
  193. /**
  194. * Verteilt alle Kurse die über genau 1 Schiene gehen mit Hilfe eines Matching
  195. * Algorithmus.
  196. */
  197. aktionKurseMitBipartiteMatchingVerteilen() {
  198. let data = this.matrix.getMatrix();
  199. for (let r = 0; r < this.fachartArr.length; r++) {
  200. for (let c = 0; c < this.schieneBelegt.length; c++) {
  201. data[r][c] = 0;
  202. }
  203. if (this.fachartZuKurs[r] !== null) {
  204. continue;
  205. }
  206. if (this.fachartArr[r].gibHatMultikurs()) {
  207. continue;
  208. }
  209. for (let kurs of this.fachartArr[r].gibKurse()) {
  210. for (let nr of kurs.gibSchienenLage()) {
  211. if (!this.schieneBelegt[nr]) {
  212. data[r][nr] = 1;
  213. }
  214. }
  215. }
  216. }
  217. let r2c = this.matrix.gibMaximalesBipartitesMatching(true);
  218. for (let r = 0; r < this.fachartArr.length; r++) {
  219. if (this.fachartZuKurs[r] !== null) {
  220. continue;
  221. }
  222. let c = r2c[r];
  223. if (c === -1) {
  224. continue;
  225. }
  226. let kursGefunden = null;
  227. for (let kurs of this.fachartArr[r].gibKurse()) {
  228. for (let nr of kurs.gibSchienenLage()) {
  229. if ((nr === c) && (kursGefunden === null)) {
  230. kursGefunden = kurs;
  231. }
  232. }
  233. }
  234. if (kursGefunden !== null)
  235. this.aktionKursHinzufuegen(r, kursGefunden);
  236. }
  237. }
  238. /**
  239. * Erzeugt pro Fachwahl ein Objekt des Typs
  240. * {@link KursblockungOutputFachwahlZuKurs} und fügt es dem Vector
  241. * {@code vFachwahlZuKurs} hinzu. Die GUI kann daraus die
  242. * Schüler-Zu-Kurs-Zuordnungen rekonstruiern.
  243. *
  244. * @param vFachwahlZuKurs Fügt diesem Vector pro Fachwahl ein Objekt des Typs
  245. * {@link KursblockungOutputFachwahlZuKurs} hinzu.
  246. */
  247. aktionOutputsErzeugen(vFachwahlZuKurs) {
  248. for (let i = 0; i < this.fachartArr.length; i++) {
  249. let fachwahlZuKurs = new KursblockungOutputFachwahlZuKurs_1.KursblockungOutputFachwahlZuKurs();
  250. fachwahlZuKurs.fachwahl = this.fachartZuGUI[i];
  251. let tmpKurs = this.fachartZuKurs[i];
  252. fachwahlZuKurs.kurs = (tmpKurs === null) ? -1 : tmpKurs.gibID();
  253. vFachwahlZuKurs.add(fachwahlZuKurs);
  254. }
  255. }
  256. /**
  257. * Liefert TRUE, falls der Schüler mindestens einen Multikurs hat. Ein Multikurs
  258. * ist ein Kurs, der über mehr als eine Schiene geht.
  259. *
  260. * @return TRUE, falls der Schüler mindestens einen Multikurs hat.
  261. */
  262. gibHatMultikurs() {
  263. for (let fachart of this.fachartArr) {
  264. if (fachart.gibHatMultikurs()) {
  265. return true;
  266. }
  267. }
  268. return false;
  269. }
  270. aktionKursHinzufuegen(fachartIndex, kurs) {
  271. kurs.aktionSchuelerHinzufügen();
  272. this.statistik.aktionNichtwahlenVeraendern(-1);
  273. this.nichtwahlen--;
  274. for (let nr of kurs.gibSchienenLage()) {
  275. if (this.schieneBelegt[nr]) {
  276. console.log(JSON.stringify("FEHLER: Schienen-Doppelbelegung! " + this.representation.valueOf()));
  277. }
  278. this.schieneBelegt[nr] = true;
  279. }
  280. this.fachartZuKurs[fachartIndex] = kurs;
  281. }
  282. aktionKursEntfernen(fachartIndex, kurs) {
  283. kurs.aktionSchuelerEntfernen();
  284. this.statistik.aktionNichtwahlenVeraendern(+1);
  285. this.nichtwahlen++;
  286. for (let nr of kurs.gibSchienenLage()) {
  287. if (!this.schieneBelegt[nr]) {
  288. console.log(JSON.stringify("FEHLER: Kurs ist gar nicht in Schiene ! " + this.representation.valueOf()));
  289. }
  290. this.schieneBelegt[nr] = false;
  291. }
  292. this.fachartZuKurs[fachartIndex] = null;
  293. }
  294. isTranspiledInstanceOf(name) {
  295. return ['de.nrw.schule.svws.core.kursblockung.KursblockungDynSchueler'].includes(name);
  296. }
  297. }
  298. exports.KursblockungDynSchueler = KursblockungDynSchueler;
  299. function cast_de_nrw_schule_svws_core_kursblockung_KursblockungDynSchueler(obj) {
  300. return obj;
  301. }
  302. exports.cast_de_nrw_schule_svws_core_kursblockung_KursblockungDynSchueler = cast_de_nrw_schule_svws_core_kursblockung_KursblockungDynSchueler;
  303. //# sourceMappingURL=KursblockungDynSchueler.js.map