Într-o școală avem trei categorii de profesori: cei care au numai
“ore proprii”, cei angajați și în “cuplaje”, respectiv cei constituiți
și în “tuplaje”. În R123
avem o repartiție
pe zile a tuturor lecțiilor, iar în
TPL
sunt specificate tuplajele asociate
acestei repartiții:
dplyr::glimpse(R123)
#> Rows: 928
#> Columns: 3
#> $ prof <ord> Rl2, En3, En3, Ps1, Is3, Is3, Mt2, Mt2, Mt2, Mt2, Sp2, Sp2, Gg1, …
#> $ cls <chr> "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "1…
#> $ zl <fct> Lu, Jo, Ma, Mi, Vi, Lu, Jo, Ma, Mi, Vi, Lu, Jo, Ma, Mi, Vi, Lu, J…
str(TPL)
#> 'data.frame': 15 obs. of 3 variables:
#> $ prof: chr "Gr3 Gr4" "Gr3 Gr1 Gr4" "Gr3 Gr1 Gr4" "Gr2 Gr3" ...
#> $ cls : chr "10E 10F" "11A 11B 11D" "12A 12B 12D" "11E 11F" ...
#> $ zl : chr "Mi" "Vi Jo" "Lu Ma" "Mi Vi Jo" ...
Profesorii sunt numiți după șablonul: disciplină, abreviată pe două
litere, plus un număr de ordine între cei încadrați pe o aceeași
disciplină; un cuplaj este reprezentat printr-un “profesor
fictiv”, cu numele rezultat prin alipirea codurilor de câte 3 caractere
ale membrilor (iar cei câțiva profesori fictivi apar și ei, între cele
66 niveluri din R123$prof
).
Mai sus, glimpse()
ne-a arătat că Rl2
,
En3
, etc., fac lecțiile la 10A
respectiv în
zilele Lu
, Jo
, Ma
, etc.
"Gr3 Gr4"/"10E 10F"
este un tuplaj, însemnând
că lecțiile “Gr3 10E
” și “Gr4 10F
” trebuie să
fie plasate într-o aceeași zi, anume în ziua Mi
(și apoi,
într-o aceeași oră a zilei), unde “10E
” și
“10F
” au fost formate ad-hoc partiționând după criterii
specifice școlii, ansamblul elevilor celor două clase inițiale.
R123
este un exemplu de repartiție
relativ echilibrată (care ne-a rezultat, plecând de la
încadrarea prof|cls
dintr-o anumită școală, prin https://cran.r-project.org/package=days2lessons); o bună
parte a distribuțiilor individuale (pe profesori și pe clase) a
numărului de ore/zi sunt distribuții omogene (uniforme), dar
există altele care sunt doar cvasi-omogene (cu diferență de
două ore —dar nu mai mult— de la o zi la alta).
Prezentăm (parțial, aici) un set de funcții care depistează și expun în
diverse formate (sau grupări), distribuțiile individuale “defectuoase”,
permițând prin corelare, omogenizarea treptată a acestora.
Să vedem întâi la care clase au rămas distribuții cvasi-omogene (dar aici, listăm doar trei):
Pentru a omogeniza distribuția la clasa 10A
ar trebui să
mutăm o lecție fie din ziua Ma
, fie din ziua
Vi
, în ziua Mi
(ar rezulta 4 zile cu câte 6
ore și o zi cu 7 ore, deci o distribuție omogenă). Să vedem ce lecții
sunt în ziua Vi
la 10A
și nu sunt în
ziua Mi
(evităm să apară la clasă într-o aceeași zi,
două lecții identice):
prof_2days(R123, "10A", "Vi", "Mi")
#> zl
#> prof Lu Ma Mi Jo Vi
#> Is3 2 3 3 4 4
#> In2In1 1 1 0 0 1
#> Tc2 2 3 3 2 3
#> Gr2 5 4 4 5 5
Să lăsăm în pace deocamdată, pe Is3
și pe
Gr2
(distribuția lui Is3
ar deveni omogenă
aducându-i încă o lecție nu în ziua Mi
, ci în ziua
Lu
; iar lecția Gr2 10A
trebuie să rămână
Vi
, fiindcă apare în tuplajul
"Gr2 Gr1"/"10A 10B"/"Vi Jo"
). La Tc2
avem
distribuție omogenă (dacă nu cumva este implicat și în cuplaje); ne
rămâne In2In1
, dar acesta este un cuplaj — să vedem cum ar
fi afectați membrii săi, dacă am muta lecția respectivă din ziua
Vi
în ziua Mi
:
coupled_dis(R123)
#> zl
#> prof Lu Ma Mi Jo Vi
#> In2In1 1 1 0 0 1
#> In2 1 2 2 3 2
#> In2In3 1 1 1 0 0
#> In1 2 3 1 2 2
#> In1In3 0 0 1 1 1
#> Tc2In1 1 0 1 0 1
#> Tc2 2 3 3 2 3
#> In3 2 2 2 2 2
Constatăm că In2
are (singur sau în cuplaj) 3 ore
Mi
și 3 ore Vi
, iar In1
are 3 și
respectiv, 5 ore — distribuții care, după mutarea intenționată, ar
deveni 2/4 și respectiv 4/4 și deocamdată, le putem accepta:
DZ
diferă de R123
numai prin faptul că
In2In1
apare Mi
și nu Vi
; în
DZ
, clasa 10A
a căpătat o distribuție omogenă
a numărului de ore/zi. N-avem dacât să continuăm, operând cam ca mai
sus, dar asupra repartiției curente DZ
, pentru clasele
rămase cu distribuții cvasi-omogene.
Dar pentru a echilibra distribuțiile orare ale celor implicați în
cuplaje este mai bine să folosim funcția coupled_list()
,
care listează matricea distribuțiilor în care este implicat un profesor
care are și ore proprii (pe clase neimplicate în cuplaje):
coupled_list(R123)[["In1"]]
#> zl
#> prof Lu Ma Mi Jo Vi
#> In2In1 1 1 0 0 1
#> In1 2 3 1 2 2
#> In1In3 0 0 1 1 1
#> Tc2In1 1 0 1 0 1
#> Sum 4 4 3 3 5
Pe matricea afișată vedem că pe Vi
, In1
cumulează 5 ore, dintre care două sunt ore proprii; deci (în loc de a
muta cuplajul In2In1
, cum am făcut mai sus) am putea muta
una dintre aceste două ore proprii, din ziua Vi
în ziua
Mi
, ceea ce i-ar omogeniza distribuția cumulată a orelor
sale.
Cândva… lucrând cu atenție și fără grabă,
cls_quasihom(DZ)
va returna NULL
— însemnând
că în acel moment toate clasele au căpătat (în repartiția curentă
DZ
) distribuții omogene pentru numărul de ore/zi; se poate
întâmpla (fiindcă… am lucrat într-adevăr, cu mare atenție, mai și
inspectând una-alta, din când în când), se poate întâmpla ca și
distribuția pe zile a totalului orelor, să fi devenit omogenă:
(da!… este necesară oleacă de inspirație, sau experiență, pentru alegerea unor schimbări succesive de lecții dintr-o zi în alta, care “deodată”, să omogenizeze distribuțiile pe clase și până la urmă și pe totalul orelor)
Să vedem acum care profesori din afara cuplajelor, cu mai mult de câte 8 ore/săptămână, au rămas cu distribuții cvasi-omogene:
Ch1 Ch2 En3 ET1 Fl1 Fz2 Gr1 Gr3 Gr4 Mt1 Mt3 Mz1 Ro2 Ro7 Sp1
Lu 3 5 3 1 4 4 4 5 3 5 4 4 4 4 4
Ma 4 3 4 3 4 3 4 3 4 6 5 2 4 2 4
Mi 3 3 4 2 4 2 3 4 5 4 3 4 3 3 5
Jo 3 4 3 1 4 4 5 3 4 4 5 3 5 3 3
Vi 5 3 5 3 2 4 5 4 5 4 4 4 3 4 5
Ne atrage atenția distribuția lui ET1
: are numai 10 ore,
dar are două zile cu câte o singură oră. Am putea să-i grupăm orele în 4
zile, dacă ora de Lu
și cea de Jo
sunt la
clase diferite:
Fiindcă ținem să nu modificăm distribuțiile, deja omogene,
ale claselor și nici distribuția totalului de ore — căutăm vreun
profesor cu care ET1
să interschimbe lecția de
Lu
(la 8A
) cu cea de Jo
(la
7A
):
8A
apare la Ro4
în ziua Jo
și
nu apare în ziua Lu
; pe de altă parte, mutarea
acestei clase păstrează omogenitatea distribuției orelor lui
Ro4
, încât putem decide să facem interschimbarea
respectivă:
> DZ <- change_day(DZ, "ET1", "8A", "Lu", "Jo")
> DZ <- change_day(DZ, "Ro4", "8A", "Jo", "Lu")
> saveRDS(DZ, "../adjR123.RDS") # salvăm din când în când, repartiția curentă
Pentru încă un exemplu, să încercăm să omogenizăm distribuția
(3 4 3 3 5
) a lui Ch1
:
> cls2prof(DZ, "Ch1")
Ch1
Lu "10A 10C 12A"
Ma "10B 11A 11D 12B"
Mi "10C 10D 11D"
Jo "10A 10D 9C"
Vi "10B 10C 10D 11D 9C"
Trebuie să căutăm profesori cu care Ch1
să interschimbe
o clasă din ziua Vi
într-una dintre zilele Lu
,
Mi
sau Jo
, fără a deteriora alte distribuții
individuale. prof_swap(DZ, "Ch1", "Vi", "Jo")
ne arată
între altele, distribuția cvasi-omogenă (4 4 3 5 3
):
Putem muta clasa 10B
de pe Jo
pe
Vi
la Ro2
și de pe Vi
pe
Jo
la Ch1
, folosind iarăși
change_day()
; ca urmare, devin omogene ambele distribuții
(și la Ch1
și la Ro2
).
La fel, folosind succesiv cls2prof()
,
prof_swap()
și apoi, după ce facem alegerile potrivite,
change_day()
— omogenizăm pe rând și distribuțiile
cvasi-omogene rămase profesorilor din afara tuplajelor.
În final, prof_bad_dis()
ne-a dat:
Exceptând ET1
(căruia mai sus, am voit să-i plasăm orele
în 4 zile), cei 4 profesori rămași cu distribuții cvasi-omogene sunt
membri ai unor tuplaje și preferăm să nu le modificăm distribuțiile
(trebuie păstrată ziua alocată din start pentru fiecare clasă care este
implicată în tuplaje, deci la cei 4 profesori am putea muta într-o altă
zi numai clase ale lor care nu sunt printre cele existente în tuplaje —
ceea ce necesită o analiză care probabil că nu este prea grea, dar de
care ne putem și lipsi).
Trebuie totuși să verificăm dacă, tot mutând lecții pe alte zile, am
reușit să păstrăm în repartiția curentă DZ
, alocările pe
zile existente în setul inițial ‘R123’ pentru tuplaje: invocarea
keep_toupled(DZ, TPL)
ar trebui să returneze
TRUE
.
De altfel, putem vizualiza (în format TSV) întreaga repartizare pe zile
a lecțiilor vreunui subset de profesori, folosind funcția
tidy2tsv()
; de exemplu, chiar pentru cei din tuplaje:
library(dplyr, warn.conflicts = FALSE)
Tpl_prof <- TPL %>% pull(prof) %>% unique() %>%
sapply(function(P) strsplit(P, " ")[[1]]) %>%
unlist() %>% unique()
DZ %>% filter(prof %in% Tpl_prof) %>%
tidy2tsv() %>% select(1:5) # câte coloane încap aici...
#> prof Lu Ma Mi Jo
#> 1 Ds1 11F 7A 9E 9C 11E 8B 10A 5A 6A 8A 10B 12E 6B 7B 9A
#> 2 Gr1 6A 12B 10D 9B 6B 12B 10D 9B 6B 12F 10E 6A 9D 11B 10B 12F
#> 3 Gr2 8A 8B 9E 10C 9A 8A 9E 10C 9A 5B 11E 9E 12E 5A 5B 11E 10A 12E
#> 4 Gr3 11C 12C 7B 12A 9F 11C 12A 9F 7A 10E 11F 9F 7B 11A 11F
#> 5 Gr4 10E 10F 12D 10E 10F 7A 12D 10F 7A 7B 10F 10F 10E 5A 9C 11D
#> 6 Mz1 12F 6B 8B 9D 5A 10C 6A 8A 9E 10D 5B 7A 9B
Putem verifica astfel, direct, că am respectat repartizarea pe zile
din ‘TPL’; vedem de exemplu, că Gr3
, Gr1
și
Gr4
intră la 12A
, 12B
, respectiv
12D
în zilele Lu
și Ma
, iar
Ds1
și Mz1
intră la 9A
și
9B
în ziua Jo
(exact cum precizează ‘TPL’).
Putem observa că la Mz1
am putea muta 12F
(sau
6B
, sau 8B
, aflate și ele în afara tuplajelor)
din ziua Lu
în ziua Ma
— ceea ce ar omogeniza
distribuția respectivă (la fel ne putem gândi să omogenizăm
distribuțiile celorlalți profesori din tuplaje, folosind iarăși
prof_swap()
și change_day()
).
În final… probabil că putem fi mulțumiți: repartiția pe zile din
DZ
este omogenă și pe clase și pe profesori — exceptând
unii membri ai cuplajelor și tuplajelor existente, pentru care a rămas
totuși acceptabilă, fiind cvasi-omogenă (iar numărul total de lecții din
DZ are o distribuție uniformă pe zile); desigur, ar mai fi de analizat
și poate de corectat, distribuțiile celor cu mai puțin de 8
ore/săptămână (acestea pot fi depistate prin
prof_bad_dis(DZ, at_least = 1)
).
Desigur, pentru aceasta ne-au fost necesare vreo două sesiuni de lucru
în consola R, cam de câte o “oră” bună… Pentru o eventuală edificare, am
adăugat în pachet și repartizarea finală
DZ
; dar bineînțeles că dacă am lua-o de la
capăt, procedând cam cum am arătat mai sus asupra repartiției inițiale
‘R123’, am ajunge la o a doua repartiție DZ
, probabil “mai
bună” ca prima (am profita desigur, de experiența primeia).