📄 timeconstraint.cpp
字号:
int day2=t2%r.nDaysPerWeek; int hour2=t2/r.nDaysPerWeek; int tmp=0; //activity weekly - counts as double if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY && r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tmp = 4 * (abs(day1-day2) + abs(hour1-hour2)); else if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY || r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tmp = 2 * (abs(day1-day2) + abs(hour1-hour2)); else tmp = abs(day1-day2) + abs(hour1-hour2); nbroken+=tmp; } } } } } //with logging else{ nbroken=0; for(int i=1; i<this->_n_activities; i++){ int t1=c.times[this->_activities[i]]; if(t1!=UNALLOCATED_TIME){ int day1=t1%r.nDaysPerWeek; int hour1=t1/r.nDaysPerWeek; for(int j=0; j<i; j++){ int t2=c.times[this->_activities[j]]; if(t2!=UNALLOCATED_TIME){ int day2=t2%r.nDaysPerWeek; int hour2=t2/r.nDaysPerWeek; int tmp=0; //activity weekly - counts as double if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY && r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tmp = 4 * (abs(day1-day2) + abs(hour1-hour2)); else if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY || r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tmp = 2 * (abs(day1-day2) + abs(hour1-hour2)); else tmp = abs(day1-day2) + abs(hour1-hour2); nbroken+=tmp; if(tmp>0 && conflictsString!=NULL){ *conflictsString+=(QObject::tr("Time constraint activities same time broken, because activity with id=%1 is not at the same time with activity with id=%2") .arg(this->activitiesId[i]) .arg(this->activitiesId[j])); *conflictsString+=", "; *conflictsString+=(QObject::tr("conflicts factor increase=%1").arg(tmp*weight)); *conflictsString+="\n"; } } } } } } return int (ceil ( weight * nbroken ) );}bool ConstraintActivitiesSameStartingTime::isRelatedToActivity(Activity* a){ for(int i=0; i<this->n_activities; i++) if(this->activitiesId[i]==a->id) return true; return false;}bool ConstraintActivitiesSameStartingTime::isRelatedToTeacher(Teacher* t){ if(t) ; return false;}bool ConstraintActivitiesSameStartingTime::isRelatedToSubject(Subject* s){ if(s) ; return false;}bool ConstraintActivitiesSameStartingTime::isRelatedToSubjectTag(SubjectTag* s){ if(s) ; return false;}bool ConstraintActivitiesSameStartingTime::isRelatedToStudentsSet(Rules& r, StudentsSet* s){ if(s) ; if(&r) ; return false;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ConstraintActivitiesNotOverlapping::ConstraintActivitiesNotOverlapping() : TimeConstraint(){ type=CONSTRAINT_ACTIVITIES_NOT_OVERLAPPING;}ConstraintActivitiesNotOverlapping::ConstraintActivitiesNotOverlapping(double w, bool c, int nact, const int act[]) : TimeConstraint(w, c) { assert(nact>=2 && nact<=MAX_CONSTRAINT_ACTIVITIES_NOT_OVERLAPPING); this->n_activities=nact; for(int i=0; i<nact; i++) this->activitiesId[i]=act[i]; this->type=CONSTRAINT_ACTIVITIES_NOT_OVERLAPPING;}bool ConstraintActivitiesNotOverlapping::computeInternalStructure(Rules &r){ //compute the indices of the activities, //based on their unique ID for(int j=0; j<n_activities; j++) this->_activities[j]=-1; this->_n_activities=0; for(int i=0; i<this->n_activities; i++){ int j; Activity* act; for(j=0; j<r.nInternalActivities; j++){ act=&r.internalActivitiesList[j]; if(act->id==this->activitiesId[i]){ this->_activities[this->_n_activities++]=j; break; } } } if(this->_n_activities<=1) return false; return true;}void ConstraintActivitiesNotOverlapping::removeUseless(Rules& r){ //remove the activitiesId which no longer exist (used after the deletion of an activity) for(int j=0; j<this->n_activities; j++) this->_activities[j]=-1; for(int i=0; i<this->n_activities; i++){ Activity* act; for(act=r.activitiesList.first(); act; act=r.activitiesList.next()) if(act->id==this->activitiesId[i]) this->_activities[i]=act->id; } int i, j; i=0; for(j=0; j<this->n_activities; j++) if(this->_activities[j]>=0) //valid activity this->activitiesId[i++]=this->_activities[j]; this->n_activities=i;}QString ConstraintActivitiesNotOverlapping::getXmlDescription(Rules& r){ if(&r!=NULL) ; QString s="<ConstraintActivitiesNotOverlapping>\n"; s+=" <Weight>"+QString::number(this->weight)+"</Weight>\n"; s+=" <Compulsory>";s+=yesNo(this->compulsory);s+="</Compulsory>\n"; s+=" <Number_of_Activities>"+QString::number(this->n_activities)+"</Number_of_Activities>\n"; for(int i=0; i<this->n_activities; i++) s+=" <Activity_Id>"+QString::number(this->activitiesId[i])+"</Activity_Id>\n"; s+="</ConstraintActivitiesNotOverlapping>\n"; return s;}QString ConstraintActivitiesNotOverlapping::getDescription(Rules& r){ if(&r!=NULL) ; QString s; s+=QObject::tr("Activities not overlapping");s+=", "; s+=(QObject::tr("W:%1").arg(this->weight));s+=", "; s+=(QObject::tr("C:%1").arg(yesNoTranslated(this->compulsory)));s+=", "; s+=(QObject::tr("NA:%1").arg(this->n_activities));s+=", "; for(int i=0; i<this->n_activities; i++){ s+=(QObject::tr("ID:%1").arg(this->activitiesId[i]));s+=", "; } return s;}QString ConstraintActivitiesNotOverlapping::getDetailedDescription(Rules& r){ if(&r!=NULL) ; QString s=QObject::tr("Time constraint");s+="\n"; s+=QObject::tr("Activities must not overlap");s+="\n"; s+=(QObject::tr("Weight=%1").arg(this->weight));s+="\n"; s+=(QObject::tr("Compulsory=%1").arg(yesNoTranslated(this->compulsory)));s+="\n"; s+=(QObject::tr("Number of activities=%1").arg(this->n_activities));s+="\n"; for(int i=0; i<this->n_activities; i++){ s+=(QObject::tr("Activity with id=%1").arg(this->activitiesId[i]));s+="\n"; } return s;}//critical function here - must be optimized for speedint ConstraintActivitiesNotOverlapping::fitness(TimeChromosome& c, Rules& r, QString* conflictsString){ assert(r.internalStructureComputed); int nbroken; //We do not use the matrices 'subgroupsMatrix' nor 'teachersMatrix'. //sum the overlapping hours for all pairs of activities. //without logging if(conflictsString==NULL){ nbroken=0; for(int i=1; i<this->_n_activities; i++){ int t1=c.times[this->_activities[i]]; if(t1!=UNALLOCATED_TIME){ int day1=t1%r.nDaysPerWeek; int hour1=t1/r.nDaysPerWeek; int duration1=r.internalActivitiesList[this->_activities[i]].duration; for(int j=0; j<i; j++){ int t2=c.times[this->_activities[j]]; if(t2!=UNALLOCATED_TIME){ int day2=t2%r.nDaysPerWeek; int hour2=t2/r.nDaysPerWeek; int duration2=r.internalActivitiesList[this->_activities[j]].duration; //the number of overlapping hours int tt=0; if(day1==day2){ int start=maximu(hour1, hour2); int stop=minimu(hour1+duration1, hour2+duration2); if(stop>start) tt+=stop-start; } //activity weekly - counts as double if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY && r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tt = 4 * tt; else if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY || r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tt = 2 * tt; /*else tt = tt;*/ nbroken+=tt; } } } } } //with logging else{ nbroken=0; for(int i=1; i<this->_n_activities; i++){ int t1=c.times[this->_activities[i]]; if(t1!=UNALLOCATED_TIME){ int day1=t1%r.nDaysPerWeek; int hour1=t1/r.nDaysPerWeek; int duration1=r.internalActivitiesList[this->_activities[i]].duration; for(int j=0; j<i; j++){ int t2=c.times[this->_activities[j]]; if(t2!=UNALLOCATED_TIME){ int day2=t2%r.nDaysPerWeek; int hour2=t2/r.nDaysPerWeek; int duration2=r.internalActivitiesList[this->_activities[j]].duration; //the number of overlapping hours int tt=0; if(day1==day2){ int start=maximu(hour1, hour2); int stop=minimu(hour1+duration1, hour2+duration2); if(stop>start) tt+=stop-start; } //The overlapping hours, considering weekly activities more important than biweekly ones int tmp=tt; //activity weekly - counts as double if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY && r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tmp = 4 * tmp; else if(r.internalActivitiesList[this->_activities[i]].parity==PARITY_WEEKLY || r.internalActivitiesList[this->_activities[j]].parity==PARITY_WEEKLY) tmp = 2 * tmp; /*else tmp = tmp;*/ nbroken+=tmp; if(tt>0 && conflictsString!=NULL){ *conflictsString+=QObject::tr("Time constraint activities not overlapping"); *conflictsString+=" "; *conflictsString+=QObject::tr("broken:"); *conflictsString+=" "; *conflictsString+=(QObject::tr("activity with id=%1 overlaps with activity with id=%2 on a number of %3 periods") .arg(this->activitiesId[i]) .arg(this->activitiesId[j]) .arg(tt)); *conflictsString+=", "; *conflictsString+=(QObject::tr("conflicts factor increase=%1").arg(tmp*weight)); *conflictsString+="\n"; } } } } } } return int (ceil ( weight * nbroken ) );}bool ConstraintActivitiesNotOverlapping::isRelatedToActivity(Activity* a){ for(int i=0; i<this->n_activities; i++) if(this->activitiesId[i]==a->id) return true; return false;}bool ConstraintActivitiesNotOverlapping::isRelatedToTeacher(Teacher* t){ if(t) ; return false;}bool ConstraintActivitiesNotOverlapping::isRelatedToSubject(Subject* s){ if(s) ; return false;}bool ConstraintActivitiesNotOverlapping::isRelatedToSubjectTag(SubjectTag* s){ if(s) ; return false;}bool ConstraintActivitiesNotOverlapping::isRelatedToStudentsSet(Rules& r, StudentsSet* s){ if(s) ; if(&r) ; return false;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ConstraintMinNDaysBetweenActivities::ConstraintMinNDaysBetweenActivities() : TimeConstraint(){ type=CONSTRAINT_MIN_N_DAYS_BETWEEN_ACTIVITIES;}ConstraintMinNDaysBetweenActivities::ConstraintMinNDaysBetweenActivities(double w, bool c, int nact, const int act[], int n) : TimeConstraint(w, c) { assert(nact>=2 && nact<=MAX_CONSTRAINT_MIN_N_DAYS_BETWEEN_ACTIVITIES); this->n_activities=nact; for(int i=0; i<nact; i++) this->activitiesId[i]=act[i]; assert(n>0); this->minDays=n; this->type=CONSTRAINT_MIN_N_DAYS_BETWEEN_ACTIVITIES;}bool ConstraintMinNDaysBetweenActivities::operator==(ConstraintMinNDaysBetweenActivities& c){ if(this->n_activities!=c.n_activities) return false; for(int i=0; i<this->n_activities; i++) if(this->activitiesId[i]!=c.activitiesId[i]) return false; if(this->minDays!=c.minDays) return false; if(this->compulsory!=c.compulsory) return false; if(this->weight!=c.weight) return false; return true;}bool ConstraintMinNDaysBetweenActivities::computeInternalStructure(Rules &r){ //compute the indices of the activities, //based on their unique ID for(int j=0; j<n_activities; j++) this->_activities[j]=-1; this->_n_activities=0; for(int i=0; i<this->n_activities; i++){ int j; Activity* act; for(j=0; j<r.nInternalActivities; j++){ act=&r.internalActivitiesList[j]; if(act->id==this->activitiesId[i]){ this->_activities[this->_n_activities++]=j; break; } } } if(this->_n_activities<=1) return false; return true;}void ConstraintMinNDaysBetweenActivities::removeUseless(Rules& r){ //remove the activitiesId which no longer exist (used after the deletion of an activity)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -