Вы находитесь на странице: 1из 27

This is an idea of how the code for perfect students max gaps per day should loo

k (so, if you add a code like that, the constraint


students max gaps per day becomes perfect and does not need those warnings in th
e program). But this code is unstable and may contain critical bugs.
Also, it is old and in the meantime, important changes might have been made to t
he official generate.cpp.
Very much care must be taken for hidden bugs and much testing is needed. Any bug
would be critical and some input files might become impossible to solve.
I prefer current stability, that is why I don't try to add this code.
-----------------
WARNING: this code is old and unstable/may contain critical bugs. It is not part
of official FET sources, it is just given as a model/inspiration source.
Copyright (C) 2009 Liviu Lalescu, licensed under GNU GPL v2 or later.
CODE BY Liviu Lalescu, 2009, modified from generate.cpp. Unstable code, it is gi
ven only as a sample. This is an idea of how the code should look like
so that the constraint students max gaps per day is perfect (so warnings about u
sing this type of not perfect constraint in FET can be removed).
-----------------
If you want to add this code into FET, you will need to modify it and replace th
e official stable code in generate.cpp. Care must be taken, because this
code is old and in the meantime, important changes might have been done in the o
fficial FET generate.cpp.
////////////////////////////////////////////////////////////////////////////////
/////////////
//not breaking students early max beginnings at second hour
//WARNING: the generate subroutine for students early max beginn
ings at second hour was modified in the official FET,
//because of a bug found. The code below (in this subroutine - e
arly max beginnings) is old, uncorrected yet (buggy),
//and must be corrected, by inspecting the official (corrected)
generate.cpp and making the necessary changes here.
//The bug is seen if generating on a locked file allowing more t
han 0 max beginnings at second hour (for instance, generate once
//for Romania/Pedagogic-High-School-Tg-Mures/2007-2008_sem1-d.fe
t, then lock the timetable and generate again.
//The generation will get stuck).
okstudentsearlymaxbeginningsatsecondhour=true;
foreach(int sbg, act->iSubgroupsList)
if(!skipRandom(subgroupsEarlyMaxBeginningsAtSecondHourPe
rcentage[sbg])){
//preliminary check
int _nHours=0;
int _nFirstGaps=0;
int _nGaps=0;
int _nIllegalGaps=0;
for(int d2=0; d2<gt.rules.nDaysPerWeek; d2++){
_nHours+=newSubgroupsDayNHours[sbg][d2];
int _tmp=0;
if(newSubgroupsDayNFirstGaps[sbg][d2]>=1
){
_nFirstGaps++;
if(newSubgroupsDayNFirstGaps[sbg
][d2]>=2){
_nIllegalGaps++;
_tmp+=newSubgroupsDayNFi
rstGaps[sbg][d2]-2;
_tmp++;
_nFirstGaps--; //bug fix
in FET-5.9.1
}
}
_tmp+=newSubgroupsDayNGaps[sbg][d2];
if(subgroupsMaxGapsPerDayMaxGaps[sbg]>=0
&& _tmp>subgroupsMaxGapsPerDayMaxGaps[sbg]){
_nHours += _tmp-subgroupsMaxGaps
PerDayMaxGaps[sbg];
_nGaps += subgroupsMaxGapsPerDay
MaxGaps[sbg];
}
else
_nGaps += _tmp;
}
int _nHoursGaps=0;
if(subgroupsMaxGapsPerWeekPercentage[sbg]>=0){
assert(subgroupsMaxGapsPerWeekPercentage
[sbg]==100);
if(_nGaps>subgroupsMaxGapsPerWeekMaxGaps
[sbg])
_nHoursGaps=_nGaps-subgroupsMaxG
apsPerWeekMaxGaps[sbg];
}
//TODO
if(_nHours + _nFirstGaps + _nHoursGaps + _nIlleg
alGaps > nHoursPerSubgroup[sbg] + subgroupsEarlyMaxBeginningsAtSecondHourMaxBegi
nnings[sbg]
|| _nIllegalGaps+_nHours+_nHoursGaps>nHoursPer
Subgroup[sbg]){
if(level>=LEVEL_STOP_CONFLICTS_CALCULATI
ON){
okstudentsearlymaxbeginningsatse
condhour=false;
goto impossiblestudentsearlymaxb
eginningsatsecondhour;
}
getSbgTimetable(sbg, conflActivities[new
time]);
sbgGetNHoursGaps(sbg);
for(;;){
int nHours=0;
int nFirstGaps=0;
int nGaps=0;
int nIllegalGaps=0;
for(int d2=0; d2<gt.rules.nDaysP
erWeek; d2++){
int tmp=0;
nHours+=sbgDayNHours[d2]
;
if(sbgDayNFirstGaps[d2]>
=1){
nFirstGaps++;
if(sbgDayNFirstG
aps[d2]>=2){
nIllegal
Gaps++;
tmp+=sbg
DayNFirstGaps[d2]-2;
tmp++;
nFirstGa
ps--;
}
}
tmp+=sbgDayNGaps[d2];
if(subgroupsMaxGapsPerDa
yMaxGaps[sbg]>=0 && tmp>subgroupsMaxGapsPerDayMaxGaps[sbg]){
nHours += tmp-su
bgroupsMaxGapsPerDayMaxGaps[sbg];
nGaps += subgrou
psMaxGapsPerDayMaxGaps[sbg];
}
else
nGaps += tmp;
}
int nHoursGaps=0;
if(subgroupsMaxGapsPerWeekPercen
tage[sbg]>=0){
assert(subgroupsMaxGapsP
erWeekPercentage[sbg]==100);
if(nGaps>subgroupsMaxGap
sPerWeekMaxGaps[sbg])
nHoursGaps=nGaps
-subgroupsMaxGapsPerWeekMaxGaps[sbg];
}
int ai2=-1;
//TODO
if(nHours + nFirstGaps + nHoursG
aps + nIllegalGaps > nHoursPerSubgroup[sbg] + subgroupsEarlyMaxBeginningsAtSecon
dHourMaxBeginnings[sbg]
|| nIllegalGaps+nHours+nHoursG
aps>nHoursPerSubgroup[sbg]){
//remove an activity
bool k=subgroupRemoveAnA
ctivityFromEnd(sbg, level, ai, conflActivities[newtime], nConflActivities[newtim
e], ai2);
assert(conflActivities[n
ewtime].count()==nConflActivities[newtime]);
if(!k){
bool kk;
if(subgroupsEarl
yMaxBeginningsAtSecondHourMaxBeginnings[sbg]==0 &&
(subgroupsMaxGa
psPerWeekMaxGaps[sbg]==0 || subgroupsMaxGapsPerDayMaxGaps[sbg]==0))
kk=false
;
else
kk=subgr
oupRemoveAnActivityFromBegin(sbg, level, ai, conflActivities[newtime], nConflAct
ivities[newtime], ai2);
assert(conflActi
vities[newtime].count()==nConflActivities[newtime]);
if(!kk){
if(level
==0){
//cout<<"WARNING - maybe bug - file "<<__FILE__<<" line "<<__LINE__<<endl;
//assert(0);
}
okstuden
tsearlymaxbeginningsatsecondhour=false;
goto imp
ossiblestudentsearlymaxbeginningsatsecondhour;
}
}
}
else{ //OK
break;
}
assert(ai2>=0);
removeAi2FromSbgTimetable(ai2);
updateSbgNHoursGaps(sbg, c.times
[ai2]%gt.rules.nDaysPerWeek);
}
}
}
impossiblestudentsearlymaxbeginningsatsecondhour:
if(!okstudentsearlymaxbeginningsatsecondhour){
if(updateSubgroups || updateTeachers)
removeAiFromNewTimetable(ai, act, d, h);
//removeConflActivities(conflActivities[newtime], nConfl
Activities[newtime], act, newtime);
nConflActivities[newtime]=MAX_ACTIVITIES;
continue;
}
////////////////////////////END students early max beginnings at
second hour
////////////////////////////////////////////////////////////////////////////////
/////////////
//not breaking students max gaps per week
okstudentsmaxgapsperweek=true;
foreach(int sbg, act->iSubgroupsList)
if(!skipRandom(subgroupsMaxGapsPerWeekPercentage[sbg])){
//TODO
//if(!skipRandom(subgroupsMaxGapsPerWeekPercentage[sbg])
){
//assert(subgroupsMaxGapsPerWeekPercentage[sbg]=
=100);
//preliminary test
int _nHours=0;
int _nGaps=0;
int _nFirstGaps=0;
int _nIllegalGaps=0;
for(int d2=0; d2<gt.rules.nDaysPerWeek; d2++){
_nHours+=newSubgroupsDayNHours[sbg][d2];
_nGaps+=newSubgroupsDayNGaps[sbg][d2];
if(subgroupsEarlyMaxBeginningsAtSecondHo
urPercentage[sbg]>=0 && newSubgroupsDayNFirstGaps[sbg][d2]>0){
_nFirstGaps++;
if(newSubgroupsDayNFirstGaps[sbg
][d2]>1){
_nIllegalGaps++;
_nGaps+=newSubgroupsDayN
FirstGaps[sbg][d2]-2;
}
}
//else
// _nFirstGaps+=newSubgroupsDayNFir
stGaps[sbg][d2];
}
int _nFirstHours=0;
if(subgroupsEarlyMaxBeginningsAtSecondHourPercen
tage[sbg]>=0){
assert(subgroupsEarlyMaxBeginningsAtSeco
ndHourPercentage[sbg]==100);
if(_nFirstGaps>subgroupsEarlyMaxBeginnin
gsAtSecondHourMaxBeginnings[sbg]){
_nFirstHours=_nFirstGaps-subgrou
psEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg];
////////begin added 23 feb 2009
if(_nIllegalGaps>_nFirstHours){
_nIllegalGaps-=_nFirstHo
urs;
_nGaps+=_nFirstHours;
}
else{
_nGaps+=_nIllegalGaps;
_nIllegalGaps=0;
}
////////end added 23 feb 2009
}
}
if((_nGaps+_nHours+_nIllegalGaps+_nFirstHours >
subgroupsMaxGapsPerWeekMaxGaps[sbg] + nHoursPerSubgroup[sbg]) ||
(_nHours+_nIllegalGaps+_nFirstHours > nHoursPer
Subgroup[sbg])){
if(level>=LEVEL_STOP_CONFLICTS_CALCULATI
ON){
okstudentsmaxgapsperweek=false;
goto impossiblestudentsmaxgapspe
rweek;
}
getSbgTimetable(sbg, conflActivities[new
time]);
sbgGetNHoursGaps(sbg);
for(;;){
int nHours=0;
int nGaps=0;
int nFirstGaps=0;
int nIllegalGaps=0;
for(int d2=0; d2<gt.rules.nDaysP
erWeek; d2++){
nHours+=sbgDayNHours[d2]
;
nGaps+=sbgDayNGaps[d2];
if(subgroupsEarlyMaxBegi
nningsAtSecondHourPercentage[sbg]>=0 && sbgDayNFirstGaps[d2]>0){
nFirstGaps++;
if(sbgDayNFirstG
aps[d2]>1){
nIllegal
Gaps++;
nGaps+=s
bgDayNFirstGaps[d2]-2;
}
}
//else
// nFirstGaps+=sbgD
ayNFirstGaps[d2];
}
int ai2=-1;
int nFirstHours=0;
if(subgroupsEarlyMaxBeginningsAt
SecondHourPercentage[sbg]>=0){
assert(subgroupsEarlyMax
BeginningsAtSecondHourPercentage[sbg]==100);
if(nFirstGaps>subgroupsE
arlyMaxBeginningsAtSecondHourMaxBeginnings[sbg]){
nFirstHours=nFir
stGaps-subgroupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg];
////////begin ad
ded 23 feb 2009
if(nIllegalGaps>
nFirstHours){
nIllegal
Gaps-=nFirstHours;
nGaps+=n
FirstHours;
}
else{
nGaps+=n
IllegalGaps;
nIllegal
Gaps=0;
}
////////end adde
d 23 feb 2009
}
}
if((nGaps+nHours+nIllegalGaps+nF
irstHours > subgroupsMaxGapsPerWeekMaxGaps[sbg] + nHoursPerSubgroup[sbg]) ||
(nHours+nIllegalGaps+nFirstHour
s > nHoursPerSubgroup[sbg])){
if(subgroupsEarlyMaxBegi
nningsAtSecondHourPercentage[sbg]>=0){
//remove an acti
vity
bool k=subgroupR
emoveAnActivityFromEnd(sbg, level, ai, conflActivities[newtime], nConflActivitie
s[newtime], ai2);
assert(conflActi
vities[newtime].count()==nConflActivities[newtime]);
if(!k){
bool kk;
if(subgr
oupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg]==0 &&
(subgro
upsMaxGapsPerWeekMaxGaps[sbg]==0 || subgroupsMaxGapsPerDayMaxGaps[sbg]==0))
kk=false;
else
kk=subgroupRemoveAnActivityFromBegin(sbg, level, ai, conflActivities[newtime], n
ConflActivities[newtime], ai2);
assert(c
onflActivities[newtime].count()==nConflActivities[newtime]);
if(!kk){
if(level==0){
cout<<"WARNING - mb - file "<<__FILE__<<" line "<<__LINE__<<endl;
//assert(0);
}
okstudentsmaxgapsperweek=false;
goto impossiblestudentsmaxgapsperweek;
}
}
}
else{
//remove an acti
vity
bool k=subgroupR
emoveAnActivityFromBeginOrEnd(sbg, level, ai, conflActivities[newtime], nConflAc
tivities[newtime], ai2);
assert(conflActi
vities[newtime].count()==nConflActivities[newtime]);
if(!k){
if(level
==0){
cout<<"WARNING - mb - file "<<__FILE__<<" line "<<__LINE__<<endl;
//assert(0);
}
okstuden
tsmaxgapsperweek=false;
goto imp
ossiblestudentsmaxgapsperweek;
}
}
}
else{ //OK
break;
}
assert(ai2>=0);
removeAi2FromSbgTimetable(ai2);
updateSbgNHoursGaps(sbg, c.times
[ai2]%gt.rules.nDaysPerWeek);
}
}
}
impossiblestudentsmaxgapsperweek:
if(!okstudentsmaxgapsperweek){
if(updateSubgroups || updateTeachers)
removeAiFromNewTimetable(ai, act, d, h);
//removeConflActivities(conflActivities[newtime], nConfl
Activities[newtime], act, newtime);
nConflActivities[newtime]=MAX_ACTIVITIES;
continue;
}
////////////////////////////END students max gaps per week
////////////////////////////////////////////////////////////////////////////////
/////////////
//not causing more than subgroupsMaxGapsPerDay students gaps
//TODO: improve, check
okstudentsmaxgapsperday=true;
foreach(int sbg, act->iSubgroupsList)
if(!skipRandom(subgroupsMaxGapsPerDayPercentage[sbg])){
assert(subgroupsMaxGapsPerDayPercentage[sbg]==10
0);
//preliminary test
int _total=0;
int _remnf=subgroupsEarlyMaxBeginningsAtSecondHo
urMaxBeginnings[sbg];
bool _haveMaxBegs=(subgroupsEarlyMaxBeginningsAt
SecondHourPercentage[sbg]>=0);
for(int d2=0; d2<gt.rules.nDaysPerWeek; d2++){
_total+=newSubgroupsDayNHours[sbg][d2];
int _g=newSubgroupsDayNGaps[sbg][d2];
if(_haveMaxBegs){
int _fg=newSubgroupsDayNFirstGap
s[sbg][d2];
if(_fg==0){
if(_g>subgroupsMaxGapsPe
rDayMaxGaps[sbg])
_total+=_g-subgr
oupsMaxGapsPerDayMaxGaps[sbg];
}
else if(_fg==1){
if(_remnf>0)
_remnf--;
else
_total++;
if(_g>subgroupsMaxGapsPe
rDayMaxGaps[sbg])
_total+=_g-subgr
oupsMaxGapsPerDayMaxGaps[sbg];
}
else if(_fg>=2){
if(_g + _fg - 1 <= subgr
oupsMaxGapsPerDayMaxGaps[sbg])
_total++;
else{
if(_remnf>0)
_remnf--
;
else
_total++
;
_total++;
assert(_g + _fg
- 2 >= subgroupsMaxGapsPerDayMaxGaps[sbg]);
_total+=(_g + _f
g - 2 - subgroupsMaxGapsPerDayMaxGaps[sbg]);
}
}
else
assert(0);
}
else{
if(_g > subgroupsMaxGapsPerDayMa
xGaps[sbg])
_total+=_g-subgroupsMaxG
apsPerDayMaxGaps[sbg];
}
}
if(_total<=nHoursPerSubgroup[sbg]) //OK
continue;
if(level>=LEVEL_STOP_CONFLICTS_CALCULATION){
okstudentsmaxgapsperday=false;
goto impossiblestudentsmaxgapsperday;
}
getSbgTimetable(sbg, conflActivities[newtime]);
sbgGetNHoursGaps(sbg);
for(;;){
int total=0;
int remnf=subgroupsEarlyMaxBeginningsAtS
econdHourMaxBeginnings[sbg];
bool haveMaxBegs=(subgroupsEarlyMaxBegin
ningsAtSecondHourPercentage[sbg]>=0);
for(int d2=0; d2<gt.rules.nDaysPerWeek;
d2++){
total+=sbgDayNHours[d2];
int g=sbgDayNGaps[d2];
if(haveMaxBegs){
int fg=sbgDayNFirstGaps[
d2];
if(fg==0){
if(g>subgroupsMa
xGapsPerDayMaxGaps[sbg])
total+=g
-subgroupsMaxGapsPerDayMaxGaps[sbg];
}
else if(fg==1){
if(remnf>0)
remnf--;
else
total++;
if(g>subgroupsMa
xGapsPerDayMaxGaps[sbg])
total+=g
-subgroupsMaxGapsPerDayMaxGaps[sbg];
}
else if(fg>=2){
if(g + fg - 1 <=
subgroupsMaxGapsPerDayMaxGaps[sbg])
total++;
else{
if(remnf
>0)
remnf--;
else
total++;
total++;
assert(g
+ fg - 2 >= subgroupsMaxGapsPerDayMaxGaps[sbg]);
total+=(
g + fg - 2 - subgroupsMaxGapsPerDayMaxGaps[sbg]);
}
}
else
assert(0);
}
else{
if(g > subgroupsMaxGapsP
erDayMaxGaps[sbg])
total+=g-subgrou
psMaxGapsPerDayMaxGaps[sbg];
}
}
if(total<=nHoursPerSubgroup[sbg]) //OK
break;
//remove an activity from the beginning
or from the end of a day
//following code is identical to maxgaps
perweek
//remove an activity
int ai2=-1;
if(subgroupsEarlyMaxBeginningsAtSecondHo
urPercentage[sbg]>=0){
bool k=subgroupRemoveAnActivityF
romEnd(sbg, level, ai, conflActivities[newtime], nConflActivities[newtime], ai2)
;
assert(conflActivities[newtime].
count()==nConflActivities[newtime]);
if(!k){
bool kk;
if(subgroupsEarlyMaxBegi
nningsAtSecondHourMaxBeginnings[sbg]==0 &&
(subgroupsMaxGapsPerWee
kMaxGaps[sbg]==0 || subgroupsMaxGapsPerDayMaxGaps[sbg]==0))
kk=false;
else
kk=subgroupRemov
eAnActivityFromBegin(sbg, level, ai, conflActivities[newtime], nConflActivities[
newtime], ai2);
assert(conflActivities[n
ewtime].count()==nConflActivities[newtime]);
if(!kk){
if(level==0){
cout<<"W
ARNING - mb - file "<<__FILE__<<" line "<<__LINE__<<endl;
//assert
(0);
}
okstudentsmaxgap
sperday=false;
goto impossibles
tudentsmaxgapsperday;
}
}
}
else{
bool k=subgroupRemoveAnActivityF
romBeginOrEnd(sbg, level, ai, conflActivities[newtime], nConflActivities[newtime
], ai2);
assert(conflActivities[newtime].
count()==nConflActivities[newtime]);
if(!k){
if(level==0){
cout<<"WARNING -
mb - file "<<__FILE__<<" line "<<__LINE__<<endl;
//assert(0);
}
okstudentsmaxgapsperday=
false;
goto impossiblestudentsm
axgapsperday;
}
}
assert(ai2>=0);
removeAi2FromSbgTimetable(ai2);
updateSbgNHoursGaps(sbg, c.times[ai2]%gt
.rules.nDaysPerWeek);
}
}
impossiblestudentsmaxgapsperday:
if(!okstudentsmaxgapsperday){
if(updateSubgroups || updateTeachers)
removeAiFromNewTimetable(ai, act, d, h);
//removeConflActivities(conflActivities[newtime], nConfl
Activities[newtime], act, newtime);
nConflActivities[newtime]=MAX_ACTIVITIES;
continue;
}
////////////////////////////END max gaps per day
////////////////////////////////////////////////////////////////////////////////
/////////////
//to be put after max gaps and early!!! because of an assert
//allowed from students max hours daily
okstudentsmaxhoursdaily=true;
foreach(int sbg, act->iSubgroupsList){
for(int count=0; count<2; count++){
int limitHoursDaily;
double percentage;
if(count==0){
limitHoursDaily=subgroupsMaxHoursDailyMa
xHours1[sbg];
percentage=subgroupsMaxHoursDailyPercent
ages1[sbg];
}
else{
limitHoursDaily=subgroupsMaxHoursDailyMa
xHours2[sbg];
percentage=subgroupsMaxHoursDailyPercent
ages2[sbg];
}
//if(fixedTimeActivity[ai] && percentage<100.0)
//added on 21 Feb 2009 in FET 5.9.1 to solve bug of impossible timetables (for f
ixed timetables)
// continue;
bool increased;
if(subgroupsEarlyMaxBeginningsAtSecondHourPercen
tage[sbg]>=0){
if(subgroupsMaxGapsPerWeekPercentage[sbg
]>=0 || subgroupsMaxGapsPerDayPercentage[sbg]>=0){
//both
if(oldSubgroupsDayNHours[sbg][d]
+oldSubgroupsDayNGaps[sbg][d]+oldSubgroupsDayNFirstGaps[sbg][d]<
newSubgroupsDayNHours[sbg][d]+
newSubgroupsDayNGaps[sbg][d]+newSubgroupsDayNFirstGaps[sbg][d]
|| oldSubgroupsDayNHours[sbg][
d]<newSubgroupsDayNHours[sbg][d])
increased=true;
else
increased=false;
}
else{
//only at beginning
if(oldSubgroupsDayNHours[sbg][d]
+oldSubgroupsDayNFirstGaps[sbg][d]<
newSubgroupsDayNHours[sbg][d]+
newSubgroupsDayNFirstGaps[sbg][d]
|| oldSubgroupsDayNHours[sbg][
d]<newSubgroupsDayNHours[sbg][d])
increased=true;
else
increased=false;
}
}
else{
if(subgroupsMaxGapsPerWeekPercentage[sbg
]>=0 || subgroupsMaxGapsPerDayPercentage[sbg]>=0){
//only max gaps
if(oldSubgroupsDayNHours[sbg][d]
+oldSubgroupsDayNGaps[sbg][d]<
newSubgroupsDayNHours[sbg][d]+
newSubgroupsDayNGaps[sbg][d]
|| oldSubgroupsDayNHours[sbg][
d]<newSubgroupsDayNHours[sbg][d])
increased=true;
else
increased=false;
}
else{
//none
if(oldSubgroupsDayNHours[sbg][d]
<newSubgroupsDayNHours[sbg][d])
increased=true;
else
increased=false;
}
}
if(limitHoursDaily>=0 && !skipRandom(percentage)
&& increased){
if(limitHoursDaily<act->duration){
okstudentsmaxhoursdaily=false;
goto impossiblestudentsmaxhoursd
aily;
}
if(subgroupsEarlyMaxBeginningsAtSecondHo
urMaxBeginnings[sbg]==0 && (subgroupsMaxGapsPerWeekMaxGaps[sbg]==0 || subgroupsM
axGapsPerDayMaxGaps[sbg]==0)){
if(newSubgroupsDayNHours[sbg][d]
+newSubgroupsDayNGaps[sbg][d]+newSubgroupsDayNFirstGaps[sbg][d] > limitHoursDail
y){
okstudentsmaxhoursdaily=
false;
goto impossiblestudentsm
axhoursdaily;
}
else //OK
continue;
}
//////////////////////////new
bool _ok;
if(newSubgroupsDayNHours[sbg][d]>limitHo
ursDaily){
_ok=false; //trivially
}
//basically, see that the gaps are enoug
h
else{
if(subgroupsEarlyMaxBeginningsAt
SecondHourPercentage[sbg]>=0){
if(subgroupsMaxGapsPerWe
ekPercentage[sbg]>=0){
//both
int rg=subgroups
MaxGapsPerWeekMaxGaps[sbg]+subgroupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[
sbg];
int lateBeginnin
gs=0;
for(int d2=0; d2
<gt.rules.nDaysPerWeek; d2++){
if(d2!=d
){
int g=limitHoursDaily-newSubgroupsDayNHours[sbg][d2];
if(g<0) //?????? theoretically good, practically not so OK (seemed to slow down
generation for a sample from my80s
g=0; //
g=newSubgroupsDayNFirstGaps[sbg][d2]+newSubgroupsDayNGaps[sbg][d2]-g;
if(g>0)
rg-=g;
if(newSubgroupsDayNFirstGaps[sbg][d2]==1 && newSubgroupsDayNHours[sbg][d2]>=limi
tHoursDaily)
lateBeginnings++;
}
}
if(rg<0)
rg=0;
int addedHours=0
;
int firstGaps=ne
wSubgroupsDayNFirstGaps[sbg][d];
int gaps=newSubg
roupsDayNGaps[sbg][d];
if(newSubgroupsD
ayNFirstGaps[sbg][d]==0){
addedHou
rs=0;
///first
Gaps=0??
}
else if(newSubgr
oupsDayNFirstGaps[sbg][d]==1){
if(subgr
oupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg]>lateBeginnings){
addedHours=0;
///firstGaps=1??
}
else{
addedHours=1;
firstGaps=0;
}
}
else{
assert(n
ewSubgroupsDayNFirstGaps[sbg][d]>=2);
addedHou
rs=1;
if(subgr
oupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg]>lateBeginnings){
firstGaps=1;
gaps+=newSubgroupsDayNFirstGaps[sbg][d]-2;
}
else{
firstGaps=0;
gaps+=newSubgroupsDayNFirstGaps[sbg][d]-1;
}
}
if(subgroupsMaxG
apsPerDayMaxGaps[sbg]>=0){
if(gaps>
subgroupsMaxGapsPerDayMaxGaps[sbg]){
addedHours+=gaps-subgroupsMaxGapsPerDayMaxGaps[sbg];
gaps=subgroupsMaxGapsPerDayMaxGaps[sbg];
}
}
if(gaps+firstGap
s>rg)
addedHou
rs+=gaps+firstGaps-rg;
if(addedHours+ne
wSubgroupsDayNHours[sbg][d] > limitHoursDaily){
_ok=fals
e;
}
else
_ok=true
;
}
else{
//only max begin
nings
int lateBeginnin
gs=0;
for(int d2=0; d2
<gt.rules.nDaysPerWeek; d2++)
if(d!=d2
)
if(newSubgroupsDayNHours[sbg][d2]>=limitHoursDaily && newSubgroupsDayNFirstGaps[
sbg][d2]==1)
lateBeginnings++;
int fg=0, ah=0,
g=newSubgroupsDayNGaps[sbg][d]; //first gaps, added hours, gaps
if(newSubgroupsD
ayNFirstGaps[sbg][d]==0){
fg=0;
ah=0;
}
else if(newSubgr
oupsDayNFirstGaps[sbg][d]==1){
fg=1;
ah=0;
if(lateB
eginnings>=subgroupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg]){
ah+=fg;
}
}
else if(newSubgr
oupsDayNFirstGaps[sbg][d]>=2){
if(lateB
eginnings>=subgroupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg]){
fg=0;
ah=1;
g+=newSubgroupsDayNFirstGaps[sbg][d]-1;
}
else{
fg=1;
ah=1;
g+=newSubgroupsDayNFirstGaps[sbg][d]-2;
}
}
if(subgroupsMaxG
apsPerDayMaxGaps[sbg]>=0){
if(g>sub
groupsMaxGapsPerDayMaxGaps[sbg])
ah+=g-subgroupsMaxGapsPerDayMaxGaps[sbg];
}
if(ah+newSubgrou
psDayNHours[sbg][d]>limitHoursDaily){
_ok=fals
e;
}
else{
_ok=true
;
}
}
}
else{
if(subgroupsMaxGapsPerWe
ekPercentage[sbg]>=0){
//only max gaps
int rg=subgroups
MaxGapsPerWeekMaxGaps[sbg];
for(int d2=0; d2
<gt.rules.nDaysPerWeek; d2++){
if(d2!=d
){
int g=limitHoursDaily-newSubgroupsDayNHours[sbg][d2];
if(g<0) //???
g=0; //
g=newSubgroupsDayNGaps[sbg][d2]-g;
if(g>0)
rg-=g;
}
}
if(rg<0)
rg=0;
if(subgroupsMaxG
apsPerDayMaxGaps[sbg]>=0)
if(rg>su
bgroupsMaxGapsPerDayMaxGaps[sbg])
rg=subgroupsMaxGapsPerDayMaxGaps[sbg];
int hg=newSubgro
upsDayNGaps[sbg][d]-rg;
if(hg<0)
hg=0;
if(hg+newSubgrou
psDayNHours[sbg][d] > limitHoursDaily){
_ok=fals
e;
}
else
_ok=true
;
}
else{
//none
_ok=true;
}
}
}
/////////////////////////////
//preliminary test
if(_ok){
continue;
}
if(level>=LEVEL_STOP_CONFLICTS_CALCULATI
ON){
okstudentsmaxhoursdaily=false;
goto impossiblestudentsmaxhoursd
aily;
}
getSbgTimetable(sbg, conflActivities[new
time]);
sbgGetNHoursGaps(sbg);
bool canTakeFromBegin=(subgroupsEarlyMax
BeginningsAtSecondHourMaxBeginnings[sbg]!=0); //-1 or >0
bool canTakeFromEnd=true;
bool canTakeFromAnywhere=(subgroupsMaxGa
psPerWeekMaxGaps[sbg]==-1);
for(;;){
//////////////////////////new
bool ok;
if(sbgDayNHours[d]>limitHoursDai
ly){
ok=false;
}
else{
if(subgroupsEarlyMaxBegi
nningsAtSecondHourPercentage[sbg]>=0){
if(subgroupsMaxG
apsPerWeekPercentage[sbg]>=0){
//both
........
..
}
else{
//only e
arly beginnings
........
..
}
}
else{
if(subgroupsMaxG
apsPerWeekPercentage[sbg]>=0){
//only m
ax gaps
........
..
}
else{
//none
ok=true;
}
}
}
/////////////////////////////
if(ok){
break;
}
int ai2=-1;
bool kk=false;
if(canTakeFromEnd)
kk=subgroupRemoveAnActiv
ityFromEndCertainDay(sbg, d, level, ai, conflActivities[newtime], nConflActiviti
es[newtime], ai2);
assert(conflActivities[newtime].
count()==nConflActivities[newtime]);
if(!kk){
canTakeFromEnd=false;
bool k=false;
if(canTakeFromBegin){
k=subgroupRemove
AnActivityFromBeginCertainDay(sbg, d, level, ai, conflActivities[newtime], nConf
lActivities[newtime], ai2);
if(subgroupsEarl
yMaxBeginningsAtSecondHourMaxBeginnings[sbg]>0)
canTakeF
romBegin=false;
}
assert(conflActivities[n
ewtime].count()==nConflActivities[newtime]);
if(!k){
canTakeFromBegin
=false;
bool ka=false;
if(canTakeFromAn
ywhere)
ka=subgr
oupRemoveAnActivityFromAnywhereCertainDay(sbg, d, level, ai, conflActivities[new
time], nConflActivities[newtime], ai2);
assert(conflActi
vities[newtime].count()==nConflActivities[newtime]);
if(!ka){
if(level
==0){
//cout<<"WARNING - file "<<__FILE__<<" line "<<__LINE__<<endl;
//assert(0);
}
okstuden
tsmaxhoursdaily=false;
goto imp
ossiblestudentsmaxhoursdaily;
}
}
}
assert(ai2>=0);
removeAi2FromSbgTimetable(ai2);
updateSbgNHoursGaps(sbg, c.times
[ai2]%gt.rules.nDaysPerWeek);
}
}
}
}
impossiblestudentsmaxhoursdaily:
if(!okstudentsmaxhoursdaily){
if(updateSubgroups || updateTeachers)
removeAiFromNewTimetable(ai, act, d, h);
//removeConflActivities(conflActivities[newtime], nConfl
Activities[newtime], act, newtime);
nConflActivities[newtime]=MAX_ACTIVITIES;
continue;
}
////////////////////////////////////////////////////////////////////////////////
/////////////
/////////begin students min hours daily
okstudentsminhoursdaily=true;
foreach(int sbg, act->iSubgroupsList){
if(subgroupsMinHoursDailyMinHours[sbg]>=0){
assert(subgroupsMinHoursDailyPercentages[sbg]==1
00);
bool skip=skipRandom(subgroupsMinHoursDailyPerce
ntages[sbg]);
if(!skip){
//preliminary test
bool _ok;
if(subgroupsEarlyMaxBeginningsAtSecondHo
urPercentage[sbg]>=0){
if(subgroupsMaxGapsPerWeekPercen
tage[sbg]>=0){
//both limitations
int nFirstGaps=0;
int nGaps=0;
int totalH=0;
for(int d2=0; d2<gt.rule
s.nDaysPerWeek; d2++){
int nGapsDay=0;
int nIllegalGaps
Day=0;
int nFirstGapsDa
y=0;
if(newSubgroupsD
ayNFirstGaps[sbg][d2]>0){
nFirstGa
psDay++;
if(newSu
bgroupsDayNFirstGaps[sbg][d2]>1){
nIllegalGapsDay++;
nGapsDay+=newSubgroupsDayNFirstGaps[sbg][d2]-2;
}
}
nGapsDay+=newSub
groupsDayNGaps[sbg][d2];
////////BELOW IS
WRONG, for example min 4 hours daily, a 4 hours day, with only last hour occupi
ed
if(1 || newSubgr
oupsDayNHours[sbg][d2]>0){
if(newSu
bgroupsDayNHours[sbg][d2]+nIllegalGapsDay<subgroupsMinHoursDailyMinHours[sbg]){
nGapsDay-=subgroupsMinHoursDailyMinHours[sbg]-newSubgroupsDayNHours[sbg][d2]-nIl
legalGapsDay;
totalH+=subgroupsMinHoursDailyMinHours[sbg];
//(*)
}
else
totalH+=newSubgroupsDayNHours[sbg][d2]+nIllegalGapsDay;
}
if(subgroupsMaxG
apsPerDayMaxGaps[sbg]>=0 && subgroupsMaxGapsPerDayMaxGaps[sbg]<nGapsDay){ //need
to correct this. if gaps is lower than allowed gaps per day,
//then if it was
(*) above, then apply correction: probably add this: if nFirstGapsDay>0 && nGap
sDay<0 -> nGapsDay++, nFirstGapsDay-- (**)
totalH+=
nGapsDay-subgroupsMaxGapsPerDayMaxGaps[sbg];
nGapsDay
=subgroupsMaxGapsPerDayMaxGaps[sbg];
}
if(nFirstGapsDay
>0)
nFirstGa
ps+=nFirstGapsDay;
if(nGapsDay>0)
nGaps+=n
GapsDay;
}
if((nGaps+totalH+nFirstG
aps <= nHoursPerSubgroup[sbg]
+subgroupsEarlyMaxBegi
nningsAtSecondHourMaxBeginnings[sbg]+subgroupsMaxGapsPerWeekMaxGaps[sbg])
&& (totalH <= nHoursPe
rSubgroup[sbg]))
_ok=true;
else
_ok=false;
}
else{
//only first gaps limita
tion
int remG=0, totalH=0;
for(int d2=0; d2<gt.rule
s.nDaysPerWeek; d2++){
int remGDay=0;
if(1 || newSubgr
oupsDayNHours[sbg][d2]>0){
if(newSu
bgroupsDayNHours[sbg][d2]<subgroupsMinHoursDailyMinHours[sbg]){
if(subgroupsMaxGapsPerDayMaxGaps[sbg]<0){
remGDay=0;
totalH+=subgroupsMinHoursDailyMinHours[sbg];
}
else{
if(newSubgroupsDayNGaps[sbg][d2]+newSubgroupsDayNFirstGaps[sbg][d2]-1
> subgroupsMaxGapsPerDayMaxGaps[sbg]){
remGDay=1;
totalH+=subgroupsMinHoursDailyMinHours[sbg]+
newSubgroupsDayNGaps[sbg][d2]+newSubgroupsDayNFirstGaps[sbg][d2]-2-
subgroupsMaxGapsPerDayMaxGaps[sbg];
}
else{
remGDay=0;
totalH+=subgroupsMinHoursDailyMinHours[sbg];
}
}
}
else{
int gaps=newSubgroupsDayNGaps[sbg][d2];
totalH+=newSubgroupsDayNHours[sbg][d2];
if(newSubgroupsDayNFirstGaps[sbg][d2]==0)
remGDay=0;
else if(newSubgroupsDayNFirstGaps[sbg][d2]==1)
remGDay=1;
else if(newSubgroupsDayNFirstGaps[sbg][d2]>=2){
if(subgroupsMaxGapsPerDayMaxGaps[sbg]<0){
remGDay=0;
totalH++;
}
else{
if(gaps+newSubgroupsDayNFirstGaps[sbg][d2]-1 >
subgroupsMaxGapsPerDayMaxGaps[sbg]){
remGDay=1;
totalH++;
gaps+=newSubgroupsDayNFirstGaps[sbg][d2]-2;
}
else{
remGDay=0;
totalH++;
gaps+=newSubgroupsDayNFirstGaps[sbg][d2]-1;
}
}
}
if(subgroupsMaxGapsPerDayMaxGaps[sbg]>=0 && gaps>subgroupsMaxGapsPerDayMaxGaps[s
bg])
totalH+=gaps-subgroupsMaxGapsPerDayMaxGaps[sbg];
}
}
if(remGDay>0)
remG+=re
mGDay;
}
if((remG+totalH <= nHour
sPerSubgroup[sbg]+subgroupsEarlyMaxBeginningsAtSecondHourMaxBeginnings[sbg])
&& (totalH <= nHoursPe
rSubgroup[sbg]))
_ok=true;
else
_ok=false;
}
}
else{
if(subgroupsMaxGapsPerWeekPercen
tage[sbg]>=0){
//only max gaps per week
limitation
int nGaps=0;
int totalH=0;
for(int d2=0; d2<gt.rule
s.nDaysPerWeek; d2++){
int nGapsDay=0;
nGapsDay+=newSub
groupsDayNGaps[sbg][d2];
if(1 || newSubgr
oupsDayNHours[sbg][d2]>0){
if(newSu
bgroupsDayNHours[sbg][d2]<subgroupsMinHoursDailyMinHours[sbg]){
nGapsDay-=subgroupsMinHoursDailyMinHours[sbg]-newSubgroupsDayNHours[sbg][d2];
totalH+=subgroupsMinHoursDailyMinHours[sbg];
}
else
totalH+=newSubgroupsDayNHours[sbg][d2];
}
if(subgroupsMaxG
apsPerDayMaxGaps[sbg]>=0 && subgroupsMaxGapsPerDayMaxGaps[sbg]<nGapsDay){
totalH+=
nGapsDay-subgroupsMaxGapsPerDayMaxGaps[sbg];
nGapsDay
=subgroupsMaxGapsPerDayMaxGaps[sbg];
}
if(nGapsDay>0)
nGaps+=n
GapsDay;
}
if((nGaps+totalH <= nHou
rsPerSubgroup[sbg]+subgroupsMaxGapsPerWeekMaxGaps[sbg])
&& (totalH <= nHoursPe
rSubgroup[sbg]))
_ok=true;
else
_ok=false;
}
else{
//no limitation
int totalH=0;
for(int d2=0; d2<gt.rule
s.nDaysPerWeek; d2++){
if(1 || newSubgr
oupsDayNHours[sbg][d2]>0){
if(newSu
bgroupsDayNHours[sbg][d2]<subgroupsMinHoursDailyMinHours[sbg])
totalH+=subgroupsMinHoursDailyMinHours[sbg];
else
totalH+=newSubgroupsDayNHours[sbg][d2];
}
}
if(totalH <= nHoursPerSu
bgroup[sbg])
_ok=true;
else
_ok=false;
}
}
if(_ok)
continue;
if(level>=LEVEL_STOP_CONFLICTS_CALCULATI
ON){
okstudentsminhoursdaily=false;
goto impossiblestudentsminhoursd
aily;
}
getSbgTimetable(sbg, conflActivities[new
time]);
sbgGetNHoursGaps(sbg);
for(;;){
bool ok;
////////////////////////////
if(subgroupsEarlyMaxBeginningsAt
SecondHourPercentage[sbg]>=0){
if(subgroupsMaxGapsPerWe
ekPercentage[sbg]>=0){
//both limitatio
ns
........
}
else{
//only first gap
s limitation
........
}
}
else{
if(subgroupsMaxGapsPerWe
ekPercentage[sbg]>=0){
//only max gaps
per week limitation
........
}
else{
//no limitation
...........
}
}
////////////////////////////
if(ok)
break; //ok
int ai2=-1;
bool kk=subgroupRemoveAnActivity
FromEnd(sbg, level, ai, conflActivities[newtime], nConflActivities[newtime], ai2
);
assert(conflActivities[newtime].
count()==nConflActivities[newtime]);
if(!kk){
bool k=subgroupRemoveAnA
ctivityFromBegin(sbg, level, ai, conflActivities[newtime], nConflActivities[newt
ime], ai2);
assert(conflActivities[n
ewtime].count()==nConflActivities[newtime]);
if(!k){
bool ka=subgroup
RemoveAnActivityFromAnywhere(sbg, level, ai, conflActivities[newtime], nConflAct
ivities[newtime], ai2);
assert(conflActi
vities[newtime].count()==nConflActivities[newtime]);
if(!ka){
if(level
==0){
/*cout<<"d=="<<d<<", h=="<<h<<", ai=="<<ai<<endl;
for(int h2=0; h2<gt.rules.nHoursPerDay; h2++){
for(int d2=0; d2<gt.rules.nDaysPerWeek; d2++)
cout<<"\t"<<sbgTimetable[d2][h2];
cout<<endl;
}*/
//cout<<"WARNING - unlikely situation - file "<<__FILE__<<" line "<<__LINE__<<en
dl;
//assert(0);
}
okstuden
tsminhoursdaily=false;
goto imp
ossiblestudentsminhoursdaily;
}
}
}
assert(ai2>=0);
removeAi2FromSbgTimetable(ai2);
updateSbgNHoursGaps(sbg, c.times
[ai2]%gt.rules.nDaysPerWeek);
}
}
}
}
impossiblestudentsminhoursdaily:
if(!okstudentsminhoursdaily){
if(updateSubgroups || updateTeachers)
removeAiFromNewTimetable(ai, act, d, h);
//removeConflActivities(conflActivities[newtime], nConfl
Activities[newtime], act, newtime);
nConflActivities[newtime]=MAX_ACTIVITIES;
continue;
}
/////////end students(s) min hours daily

Вам также может понравиться