Back to index

fet  5.18.0
Public Member Functions | Public Attributes
ConstraintBasicCompulsoryTime Class Reference

This class comprises all the basic compulsory constraints (constraints which must be fulfilled for any timetable) - the time allocation part. More...

#include <timeconstraint.h>

Inheritance diagram for ConstraintBasicCompulsoryTime:
Inheritance graph
[legend]
Collaboration diagram for ConstraintBasicCompulsoryTime:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ConstraintBasicCompulsoryTime ()
 ConstraintBasicCompulsoryTime (double wp)
bool computeInternalStructure (QWidget *parent, Rules &r)
 Computes the internal structure for this constraint.
bool hasInactiveActivities (Rules &r)
QString getXmlDescription (Rules &r)
 Returns an XML description of this constraint.
QString getDescription (Rules &r)
 Returns a small description string for this constraint.
QString getDetailedDescription (Rules &r)
 Returns a detailed description string for this constraint.
double fitness (Solution &c, Rules &r, QList< double > &cl, QList< QString > &dl, QString *conflictsString=NULL)
 The function that calculates the fitness of a solution, according to this constraint.
bool isRelatedToActivity (Rules &r, Activity *a)
 Returns true if this constraint is related to this activity.
bool isRelatedToTeacher (Teacher *t)
 Returns true if this constraint is related to this teacher.
bool isRelatedToSubject (Subject *s)
 Returns true if this constraint is related to this subject.
bool isRelatedToActivityTag (ActivityTag *s)
 Returns true if this constraint is related to this activity tag.
bool isRelatedToStudentsSet (Rules &r, StudentsSet *s)
 Returns true if this constraint is related to this students set.
bool hasWrongDayOrHour (Rules &r)
bool canRepairWrongDayOrHour (Rules &r)
bool repairWrongDayOrHour (Rules &r)

Public Attributes

double weightPercentage
 The percentage weight of this constraint, 100% compulsory, 0% non-compulsory.
bool active
QString comments
int type
 Specifies the type of this constraint (using the above constants).

Detailed Description

This class comprises all the basic compulsory constraints (constraints which must be fulfilled for any timetable) - the time allocation part.

Definition at line 244 of file timeconstraint.h.


Constructor & Destructor Documentation

Definition at line 138 of file timeconstraint.cpp.

Definition at line 144 of file timeconstraint.cpp.


Member Function Documentation

Implements TimeConstraint.

Definition at line 492 of file timeconstraint.cpp.

{
       Q_UNUSED(r);
       assert(0);
       
       return true;
}
bool ConstraintBasicCompulsoryTime::computeInternalStructure ( QWidget *  parent,
Rules r 
) [virtual]

Computes the internal structure for this constraint.

It returns false if the constraint is an activity related one and it depends on only inactive activities.

Implements TimeConstraint.

Definition at line 149 of file timeconstraint.cpp.

{
       Q_UNUSED(parent);
       Q_UNUSED(r);
       
       return true;
}
double ConstraintBasicCompulsoryTime::fitness ( Solution c,
Rules r,
QList< double > &  cl,
QList< QString > &  dl,
QString *  conflictsString = NULL 
) [virtual]

The function that calculates the fitness of a solution, according to this constraint.

We need the rules to compute this fitness factor. If conflictsString!=NULL, it will be initialized with a text explaining where this restriction is broken.

Implements TimeConstraint.

Definition at line 215 of file timeconstraint.cpp.

                                                                                                                                  {
       assert(r.internalStructureComputed);

       int teachersConflicts, subgroupsConflicts;
       
       assert(weightPercentage==100.0);

       //This constraint fitness calculation routine is called firstly,
       //so we can compute the teacher and subgroups conflicts faster this way.
       if(!c.teachersMatrixReady || !c.subgroupsMatrixReady){
              c.teachersMatrixReady=true;
              c.subgroupsMatrixReady=true;
       
              subgroups_conflicts = subgroupsConflicts = c.getSubgroupsMatrix(r, subgroupsMatrix);
              teachers_conflicts = teachersConflicts = c.getTeachersMatrix(r, teachersMatrix);

              c.changedForMatrixCalculation=false;
       }
       else{
              assert(subgroups_conflicts>=0);
              assert(teachers_conflicts>=0);
              subgroupsConflicts = subgroups_conflicts;
              teachersConflicts = teachers_conflicts;
       }

       int i,dd;

       int unallocated; //unallocated activities
       int late; //late activities
       int nte; //number of teacher exhaustions
       int nse; //number of students exhaustions

       //Part without logging..................................................................
       if(conflictsString==NULL){
              //Unallocated or late activities
              unallocated=0;
              late=0;
              for(i=0; i<r.nInternalActivities; i++){
                     if(c.times[i]==UNALLOCATED_TIME){
                            //Firstly, we consider a big clash each unallocated activity.
                            //Needs to be very a large constant, bigger than any other broken constraint.
                            unallocated += /*r.internalActivitiesList[i].duration * r.internalActivitiesList[i].nSubgroups * */ 10000;
                            //(an unallocated activity for a year is more important than an unallocated activity for a subgroup)
                     }
                     else{
                            //Calculates the number of activities that are scheduled too late (in fact we
                            //calculate a function that increases as the activity is getting late)
                            int h=c.times[i]/r.nDaysPerWeek;
                            dd=r.internalActivitiesList[i].duration;
                            if(h+dd>r.nHoursPerDay){
                                   int tmp;
                                   tmp=1;
                                   late += (h+dd-r.nHoursPerDay) * tmp * r.internalActivitiesList[i].iSubgroupsList.count();
                                   //multiplied with the number
                                   //of subgroups implied, for seeing the importance of the
                                   //activity
                            }
                     }
              }
              
              assert(late==0);

              //Below, for teachers and students, please remember that 2 means a weekly activity
              //and 1 fortnightly one. So, if the matrix teachersMatrix[teacher][day][hour]==2, it is ok.

              //Calculates the number of teachers exhaustion (when he has to teach more than
              //one activity at the same time)
              /*nte=0;
              for(i=0; i<r.nInternalTeachers; i++)
                     for(int j=0; j<r.nDaysPerWeek; j++)
                            for(int k=0; k<r.nHoursPerDay; k++){
                                   int tmp=teachersMatrix[i][j][k]-2;
                                   if(tmp>0)
                                          nte+=tmp;
                            }*/
              nte = teachersConflicts; //faster
              
              assert(nte==0);

              //Calculates the number of subgroups exhaustion (a subgroup cannot attend two
              //activities at the same time)
              /*nse=0;
              for(i=0; i<r.nInternalSubgroups; i++)
                     for(int j=0; j<r.nDaysPerWeek; j++)
                            for(int k=0; k<r.nHoursPerDay; k++){
                                   int tmp=subgroupsMatrix[i][j][k]-2;
                                   if(tmp>0)
                                          nse += tmp;
                            }*/
              nse = subgroupsConflicts; //faster
              
              assert(nse==0);                    
       }
       //part with logging....................................................................
       else{
              //Unallocated or late activities
              unallocated=0;
              late=0;
              for(i=0; i<r.nInternalActivities; i++){
                     if(c.times[i]==UNALLOCATED_TIME){
                            //Firstly, we consider a big clash each unallocated activity.
                            //Needs to be very a large constant, bigger than any other broken constraint.
                            unallocated += /*r.internalActivitiesList[i].duration * r.internalActivitiesList[i].nSubgroups * */ 10000;
                            //(an unallocated activity for a year is more important than an unallocated activity for a subgroup)
                            if(conflictsString!=NULL){
                                   QString s= tr("Time constraint basic compulsory broken: unallocated activity with id=%1 (%2)",
                                          "%2 is the detailed description of activity - teachers, subject, students")
                                          .arg(r.internalActivitiesList[i].id).arg(getActivityDetailedDescription(r, r.internalActivitiesList[i].id));
                                   s+=" - ";
                                   s += tr("this increases the conflicts total by %1")
                                    .arg(CustomFETString::number(weightPercentage/100 * 10000));
                                   //s += "\n";
                                   
                                   dl.append(s);
                                   cl.append(weightPercentage/100 * 10000);

                                   (*conflictsString) += s + "\n";
                            }
                     }
                     else{
                            //Calculates the number of activities that are scheduled too late (in fact we
                            //calculate a function that increases as the activity is getting late)
                            int h=c.times[i]/r.nDaysPerWeek;
                            dd=r.internalActivitiesList[i].duration;
                            if(h+dd>r.nHoursPerDay){
                                   assert(0);    
                            
                                   int tmp;
                                   tmp=1;
                                   late += (h+dd-r.nHoursPerDay) * tmp * r.internalActivitiesList[i].iSubgroupsList.count();
                                   //multiplied with the number
                                   //of subgroups implied, for seeing the importance of the
                                   //activity

                                   if(conflictsString!=NULL){
                                          QString s=tr("Time constraint basic compulsory");
                                          s+=": ";
                                          s+=tr("activity with id=%1 is late.")
                                           .arg(r.internalActivitiesList[i].id);
                                          s+=" ";
                                          s+=tr("This increases the conflicts total by %1")
                                           .arg(CustomFETString::number((h+dd-r.nHoursPerDay)*tmp*r.internalActivitiesList[i].iSubgroupsList.count()*weightPercentage/100));
                                          s+="\n";
                                          
                                          dl.append(s);
                                          cl.append((h+dd-r.nHoursPerDay)*tmp*r.internalActivitiesList[i].iSubgroupsList.count()*weightPercentage/100);

                                          (*conflictsString) += s+"\n";
                                   }
                            }
                     }
              }

              //Below, for teachers and students, please remember that 2 means a weekly activity
              //and 1 fortnightly one. So, if the matrix teachersMatrix[teacher][day][hour]==2,
              //that is ok.

              //Calculates the number of teachers exhaustion (when he has to teach more than
              //one activity at the same time)
              nte=0;
              for(i=0; i<r.nInternalTeachers; i++)
                     for(int j=0; j<r.nDaysPerWeek; j++)
                            for(int k=0; k<r.nHoursPerDay; k++){
                                   int tmp=teachersMatrix[i][j][k]-1;
                                   if(tmp>0){
                                          if(conflictsString!=NULL){
                                                 QString s=tr("Time constraint basic compulsory");
                                                 s+=": ";
                                                 s+=tr("teacher with name %1 has more than one allocated activity on day %2, hour %3")
                                                  .arg(r.internalTeachersList[i]->name)
                                                  .arg(r.daysOfTheWeek[j])
                                                  .arg(r.hoursOfTheDay[k]);
                                                 s+=". ";
                                                 s+=tr("This increases the conflicts total by %1")
                                                  .arg(CustomFETString::number(tmp*weightPercentage/100));
                                          
                                                 (*conflictsString)+= s+"\n";
                                                 
                                                 dl.append(s);
                                                 cl.append(tmp*weightPercentage/100);
                                          }
                                          nte+=tmp;
                                   }
                            }

              assert(nte==0);
              
              //Calculates the number of subgroups exhaustion (a subgroup cannot attend two
              //activities at the same time)
              nse=0;
              for(i=0; i<r.nInternalSubgroups; i++)
                     for(int j=0; j<r.nDaysPerWeek; j++)
                            for(int k=0; k<r.nHoursPerDay; k++){
                                   int tmp=subgroupsMatrix[i][j][k]-1;
                                   if(tmp>0){
                                          if(conflictsString!=NULL){
                                                 QString s=tr("Time constraint basic compulsory");
                                                 s+=": ";
                                                 s+=tr("subgroup %1 has more than one allocated activity on day %2, hour %3")
                                                  .arg(r.internalSubgroupsList[i]->name)
                                                  .arg(r.daysOfTheWeek[j])
                                                  .arg(r.hoursOfTheDay[k]);
                                                 s+=". ";
                                                 s+=tr("This increases the conflicts total by %1")
                                                  .arg(CustomFETString::number((subgroupsMatrix[i][j][k]-1)*weightPercentage/100));
                                                  
                                                 dl.append(s);
                                                 cl.append((subgroupsMatrix[i][j][k]-1)*weightPercentage/100);
                                          
                                                 *conflictsString += s+"\n";
                                          }
                                          nse += tmp;
                                   }
                            }
                     
              assert(nse==0);
       }

       /*if(nte!=teachersConflicts){
              cout<<"nte=="<<nte<<", teachersConflicts=="<<teachersConflicts<<endl;
              cout<<c.getTeachersMatrix(r, teachersMatrix)<<endl;
       }
       if(nse!=subgroupsConflicts){
              cout<<"nse=="<<nse<<", subgroupsConflicts=="<<subgroupsConflicts<<endl;
              cout<<c.getSubgroupsMatrix(r, subgroupsMatrix)<<endl;
       }*/
       
       /*assert(nte==teachersConflicts); //just a check, works only on logged fitness calculation
       assert(nse==subgroupsConflicts);*/

       //return int (ceil ( weight * (unallocated + late + nte + nse) ) ); //conflicts factor
       return weightPercentage/100 * (unallocated + late + nte + nse); //conflicts factor
}

Here is the call graph for this function:

Returns a small description string for this constraint.

Implements TimeConstraint.

Definition at line 176 of file timeconstraint.cpp.

{
       Q_UNUSED(r);

       QString begin=QString("");
       if(!active)
              begin="X - ";
              
       QString end=QString("");
       if(!comments.isEmpty())
              end=", "+tr("C: %1", "Comments").arg(comments);
              
       return begin+tr("Basic compulsory constraints (time)") + ", " + tr("WP:%1\%", "Weight percentage").arg(CustomFETString::number(this->weightPercentage))+end;
}

Here is the call graph for this function:

Returns a detailed description string for this constraint.

Implements TimeConstraint.

Definition at line 191 of file timeconstraint.cpp.

{
       Q_UNUSED(r);

       QString s=tr("These are the basic compulsory constraints (referring to time allocation) for any timetable");
       s+="\n";

       s+=tr("Weight (percentage)=%1\%").arg(CustomFETString::number(this->weightPercentage));s+="\n";
       s+=tr("The basic time constraints try to avoid:");s+="\n";
       s+=QString("- ");s+=tr("teachers assigned to more than one activity simultaneously");s+="\n";
       s+=QString("- ");s+=tr("students assigned to more than one activity simultaneously");s+="\n";
       
       if(!active){
              s+=tr("Active=%1", "Refers to a constraint").arg(yesNoTranslated(active));
              s+="\n";
       }
       if(!comments.isEmpty()){
              s+=tr("Comments=%1").arg(comments);
              s+="\n";
       }

       return s;
}

Here is the call graph for this function:

Returns an XML description of this constraint.

Implements TimeConstraint.

Definition at line 163 of file timeconstraint.cpp.

{
       Q_UNUSED(r);

       QString s = "<ConstraintBasicCompulsoryTime>\n";
       assert(this->weightPercentage==100.0);
       s+="   <Weight_Percentage>"+CustomFETString::number(this->weightPercentage)+"</Weight_Percentage>\n";
       s+="   <Active>"+trueFalse(active)+"</Active>\n";
       s+="   <Comments>"+protect(comments)+"</Comments>\n";
       s+="</ConstraintBasicCompulsoryTime>\n";
       return s;
}

Here is the call graph for this function:

Implements TimeConstraint.

Definition at line 157 of file timeconstraint.cpp.

{
       Q_UNUSED(r);
       return false;
}

Implements TimeConstraint.

Definition at line 486 of file timeconstraint.cpp.

{
       Q_UNUSED(r);
       return false;
}

Returns true if this constraint is related to this activity.

Implements TimeConstraint.

Definition at line 449 of file timeconstraint.cpp.

{
       Q_UNUSED(a);
       Q_UNUSED(r);

       return false;
}

Returns true if this constraint is related to this activity tag.

Implements TimeConstraint.

Definition at line 471 of file timeconstraint.cpp.

{
       Q_UNUSED(s);

       return false;
}

Returns true if this constraint is related to this students set.

Implements TimeConstraint.

Definition at line 478 of file timeconstraint.cpp.

{
       Q_UNUSED(r);
       Q_UNUSED(s);

       return false;
}

Returns true if this constraint is related to this subject.

Implements TimeConstraint.

Definition at line 464 of file timeconstraint.cpp.

{
       Q_UNUSED(s);

       return false;
}

Returns true if this constraint is related to this teacher.

Implements TimeConstraint.

Definition at line 457 of file timeconstraint.cpp.

{
       Q_UNUSED(t);

       return false;
}

Implements TimeConstraint.

Definition at line 500 of file timeconstraint.cpp.

{
       Q_UNUSED(r);
       assert(0); //should check hasWrongDayOrHour, firstly

       return true;
}

Member Data Documentation

bool TimeConstraint::active [inherited]

Definition at line 146 of file timeconstraint.h.

QString TimeConstraint::comments [inherited]

Definition at line 148 of file timeconstraint.h.

int TimeConstraint::type [inherited]

Specifies the type of this constraint (using the above constants).

Definition at line 153 of file timeconstraint.h.

The percentage weight of this constraint, 100% compulsory, 0% non-compulsory.

Definition at line 144 of file timeconstraint.h.


The documentation for this class was generated from the following files: