[1] V.Bazon - De la seturi de date și limbajul R, la orare școlare (Google Books)
[2] Împachetarea alocării pe ore a lecțiilor zilei (I) (... și (II))
Două dintre pachetele demarate în [2] și puse la punct între timp, sunt fiecare "on its way to CRAN": hours2lessons (Title: Alocă pe Ore Lecțiile Zilei) și refitgaps (Title: Reduce the Number of Holes in the School Timetable); al treilea, "days2lessons" (Distributes Teachers Lessons On Days in a Balanced Manner) este încă în curs de verificare și aprobare. Mai este de trimis pachetul spysetlessons
(Explore and Interactively Adjust a Daily Distribution of Lessons), pe care tocmai l-am finalizat.
Ar fi de subliniat faptul ne-uzual că în "vignette" și linii-comentariu am folosit limba română; dar Google Translate dă o traducere neașteptat de bună, în engleză.
Împreună, aceste 4 pachete R asigură obținerea unui orar echilibrat, cu un număr de ferestre cât se poate de mic, pentru o școală cu un singur schimb.
Aici ne propunem să "cizelăm" repartiția pe zile rezultată în [3], folosind pachetul spysetlessons
; pentru funcțiile dintr-un pachet este interzisă scrierea pe discul utilizatorului, sau în sesiunea de lucru a acestuia — așa că am considerat (și exportat) o gamă de funcții "spy_
" care produc anumite subseturi de date și o funcție "set_
" care permite utilizatorului să modifice repartiția curentă (de unde… numele pachetului).
Funcțiile respective sunt inspirate din [1] (unde interacționau însă, cu utilizatorul…).
În [3] am considerat o școală imaginară, cu câte 8 clase pe fiecare nivel 5-12 (cu câte 25-32 de ore/săptămână); am ales 17 discipline (după "planul-cadru de învățământ"), pe care am încadrat după un anumit algoritm (dar fără cuplaje sau tuplaje) în total 95 de profesori, fiecare cu câte 16-22 de ore/săptămână.
În R1.RDS
am obținut (am zice acum, prin pachetul days2lessons
) o repartizare pe zile a celor 1876 de lecții, în care numărul de ore/zi are o distribuție omogenă pe fiecare clasă, dar în general cvasi-omogenă, pe profesori.
Arătăm mai departe, cum putem folosi pachetul spysetlessons
pentru a omogeniza distribuțiile care au rămas numai cvasi-omogene.
library(spysetlessons) R1 <- readDRS("~/24dec/ORARE/R1.RDS") dplyr::glimpse(R1) Rows: 1,876 Columns: 3 $ prof <ord> Fi1, Fi1, Fi1, Ro1, Ro1, Ro1, Ds1, Mz1, Ge1, Sp1, Sp1, Fr1, Fr1, … $ cls <chr> "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "1… $ zl <fct> Mi, Lu, Ma, Vi, Jo, Mi, Lu, Ma, Vi, Jo, Mi, Lu, Ma, Vi, Jo, Mi, L…
Citim afișarea de mai sus astfel: cele 3 lecții la 10A
ale lui Fi1
au fost plasate în zilele Mi
, Lu
și Ma
; cele 3 lecții la 10A
ale lui Ro1
au fost plasate în zilele Vi
, Jo
și Mi
; ș.a.m.d.
Dar să vedem distribuția pe zile a lecțiilor lui Fi1
:
> spy_cls_prof(R1, "Fi1") Fi1 Lu "10A 10G 8C 9G" Ma "10A 11G 6A 9A 9G" Mi "10A 10G 11G 7E" Jo "10G 11G 6A 9A 9G" Vi "7E 8C 9A"
Deci Fi1
are distribuția cvasi-omogenă (4 5 4 5 3); dacă vrem să nu modificăm distribuția pe zile a totalului de 1876 lecții, ar trebui să căutăm vreun profesor cu care Fi1
să interschimbe o lecție dintr-o zi în care are 5 ore (Ma
sau Jo
), cu una din ziua Vi
, în care are numai 3 ore. De observat că la Fi1
clasa 9A
(și numai aceasta) nu poate fi dusă din ziua Ma
în ziua Vi
(fiindcă atunci, Vi
ar intra de două ori la 9A
).
> spy_swaps(R1, "Fi1", "Ma", "Vi") [[1]] Ro1 Lu "11E 5A 6E 8A 9E" Ma "5A 8A 9E" Mi "10A 11E 6E 8A 9E" Jo "10A 5A 6E 9E" Vi "10A 11E 5A 6E 8A" [[2]] ## ... alți câțiva profesori, cu care se poate interschimba o lecție
spy_swaps()
ne-a afișat toți profesorii care Vi
au ore la măcar o clasă dintre cele repartizate Ma
lui Fi1
(și în plus, au Ma
cel mult tot atâtea ore ca Vi
); dintre aceștia, alegem chiar primul, Ro1
(care și el, are o distribuție cvasi-omogenă) și facem interschimbarea între zilele Ma
și Vi
, a clasei 10A
, la cei doi profesori:
> DZ <- set_day(R1, "Fi1", "10A", "Ma", "Vi") > DZ <- set_day(DZ, "Ro1", "10A", "Vi", "Ma")
Acum, în repartizarea curentă DZ
, ambii profesori au distribuții omogene.
Să vedem care profesori, au rămas cu distribuții cvasi-omogene:
> Bad <- spy_bad_distrib(DZ)
str(Bad)
ne arată că avem 68 de cazuri; primele 16 sunt:
> Bad[1:16] Bi1 Bi2 Bi3 Bi4 Ch1 Ch2 Ch3 Ch4 En1 En3 En4 En5 En6 En9 Fi2 Fi3 Lu 4 3 3 4 4 3 3 4 5 5 3 5 4 4 3 5 Ma 5 3 3 5 5 3 5 3 4 4 3 4 5 3 4 3 Mi 3 4 5 3 3 5 3 5 4 5 5 3 3 5 3 5 Jo 4 5 4 3 4 4 4 5 3 3 4 3 3 4 4 4 Vi 3 4 4 4 4 4 4 3 5 5 5 3 4 4 5 3
N-avem decât să folosim spy_cls_prof()
și spy_swaps()
pentru a alege câte o interschimbare potrivită de lecții și apoi set_day()
pentru a face interschimbarea respectivă (și încă sunt mari șanse, câtă vreme avem multe distribuții cvasi-omogene, să putem omogeniza câte două); de exemplu:
> P <- names(Bad[1]) # Bi1 > spy_cls_prof(DZ, P) Bi1 Lu "10A 12G 7C 7H" Ma "11C 12A 6A 6F 8E" Mi "10A 12G 6F" Jo "10F 11C 6A 9B" Vi "7C 7H 9B" > spy_swaps(DZ, P, "Ma", "Vi") [[5]] # pe lângă alți câțiva Mt11 Lu "11C 5B 9C" Ma "5B 6E 7H" Mi "5B 6E 7H 9C" Jo "11C 6E 7H 9C" Vi "11C 5B 6E 7H 9C" > DZ <- set_day(DZ, P, "11C", "Ma", "Vi") > DZ <- set_day(DZ, "Mt11", "11C", "Vi", "Ma")
Desigur, la un moment dat trebuie să vedem cum este distribuit pe zile, totalul orelor:
> addmargins(table(DZ[c('cls', 'zl')]))["Sum", ] Lu Ma Mi Jo Vi Sum 376 376 375 374 375 1876
Dacă vrem neapărat ca distribuția globală să fie omogenă, ar trebui să mutăm o oră din primele două zile, în ziua Jo
; dintre cei cu distribuții cvasi-omogene, între alții, Bi4
are distribuția potrivită (4 5 3 3 4), pentru o mutare Ma
-->Jo
:
> spy_cls_prof(DZ,"Bi4") Bi4 Lu "10D 5B 6D 8C" Ma "10D 11G 5G 7A 7F" Mi "11G 7F 8H" Jo "12D 5E 7A" Vi "11A 12D 6D 9E"
Numai că este "potrivită" numai la prima vedere: inspectând distribuțiile claselor, prin spy_cls_distrib()
, constatăm că făcând mutarea respectivă, am deteriora distribuția clasei respective (de exemplu, clasa 10D
are câte 6 ore/zi, deci nu putem muta o lecție a ei dintr-o zi în alta, decât dacă aducem în loc una din ziua în care am mutat-o); iar 7A
nu poate fi mutată și din motivul că ar căpăta două ore de "Biologie" în aceeași zi (deci omogenizarea distribuției lui Bi4
ar trebui făcută "normal", prin interschimbare cu un alt profesor, folosind spy_swaps()
).
Dar n-a fost greu să găsim o clasă (11E
cu 6 și 5 ore în cele două zile) și un profesor (Fr6
) cu oră la acea clasă în ziua Ma
(nu și în ziua
> spy_cls_prof(DZ,"Fr6") Fr6 Lu "10F 12D 5C 7H" Ma "11E 5C 7A 7H 8F" Mi "10F 6B 8F" Jo "10F 7A 9E" Vi "11E 12D 6B 9E" > spy_cls_distrib(DZ, "11E") Lu Ma Mi Jo Vi 6 6 6 5 6 > DZ <- set_day(DZ, "Fr6", "11E", "Ma", "Jo")
Aducând la Fr6
ora la 11E
de Ma
în ziua Jo
, distribuția lui Fr6
devine omogenă, distribuția clasei 11E
rămâne omogenă, iar distribuția globală ajunge și ea, să fie omogenă.
Lucrând ca mai sus (dar în principiu, fâcând numai interschimbări, prin spy_swaps()
, pentru a nu mai afecta distribuția globală), ajungem, probabil în vreo "oră" bună de lucru, să omogenizăm toate distribuțiile care au mai rămas cvasi-omogene. Bineînțeles că în final, salvăm repartizarea DZ
obținută, urmând să folosim mai departe, pe rând, pachetele hours2lessons
pentru a monta orele 1:7 pe lecțiile fiecărei zile și refitgaps
, pentru a reduce numărul total de ferestre apărute pe orarele zilelor.
vezi Cărţile mele (de programare)