Logo Search packages:      
Sourcecode: fet version File versions

int ConstraintBasicCompulsoryTime::fitness ( TimeChromosome c,
Rules r,
QString *  conflictsString = NULL 
) [virtual]

The function that calculates the fitness of a chromosome, 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 141 of file timeconstraint.cpp.

References Rules::daysOfTheWeek, Activity::duration, TimeChromosome::getSubgroupsMatrix(), TimeChromosome::getTeachersMatrix(), Activity::id, Rules::internalActivitiesList, Rules::internalStructureComputed, Rules::internalSubgroupsList, Rules::internalTeachersList, Teacher::name, Rules::nDaysPerWeek, Rules::nHoursPerDay, Rules::nInternalActivities, Rules::nInternalSubgroups, Rules::nInternalTeachers, Activity::nSubgroups, Activity::parity, TimeChromosome::times, and TimeConstraint::weight.

                                                                                               {
      assert(r.internalStructureComputed);

      int teachersConflicts, subgroupsConflicts;

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

            crt_chrom = &c;
            crt_rules = &r;
      }
      else{
            subgroupsConflicts=-1;
            teachersConflicts=-1;
            cout<<"Warning here ***"<<endl;
      }

      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;
                              if(r.internalActivitiesList[i].parity==PARITY_WEEKLY)
                                    tmp=2;
                              else{
                                    assert(r.internalActivitiesList[i].parity==PARITY_BIWEEKLY);
                                    tmp=1;
                              }
                              late += (h+dd-r.nHoursPerDay) * tmp * r.internalActivitiesList[i].nSubgroups;
                              //multiplied with 2 for weekly activities and with the number
                              //of subgroups implied, for seeing the importance of the
                              //activity
                        }
                  }
            }

            //Below, for teachers and students, please remember that 2 means a weekly activity
            //and 1 bi-weekly 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

            //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
                  
      }
      //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){
                              (*conflictsString) += QObject::tr("Time constraint basic compulsory");
                              (*conflictsString) += ": ";
                              (*conflictsString) += QObject::tr(QObject::tr("unallocated activity with id=%1").arg(r.internalActivitiesList[i].id));
                              (*conflictsString) += QObject::tr(QObject::tr(" - this increases the conflicts factor with %1")
                                    .arg(weight * /*r.internalActivitiesList[i].duration*r.internalActivitiesList[i].nSubgroups * */10000));
                              (*conflictsString) += "\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){
                              int tmp;
                              if(r.internalActivitiesList[i].parity==PARITY_WEEKLY)
                                    tmp=2;
                              else{
                                    assert(r.internalActivitiesList[i].parity==PARITY_BIWEEKLY);
                                    tmp=1;
                              }
                              late += (h+dd-r.nHoursPerDay) * tmp * r.internalActivitiesList[i].nSubgroups;
                              //multiplied with 2 for weekly activities and with the number
                              //of subgroups implied, for seeing the importance of the
                              //activity

                              if(conflictsString!=NULL){
                                    (*conflictsString)+=QObject::tr("Time constraint basic compulsory");
                                    (*conflictsString)+=": ";
                                    (*conflictsString)+=QObject::tr("activity with id=%1 is late.")
                                          .arg(r.internalActivitiesList[i].id);
                                    (*conflictsString)+=" ";
                                    (*conflictsString)+=QObject::tr("This increases the conflicts factor with %1")
                                          .arg((h+dd-r.nHoursPerDay)*tmp*r.internalActivitiesList[i].nSubgroups*weight);
                                    (*conflictsString)+="\n";
                              }
                        }
                  }
            }

            //Below, for teachers and students, please remember that 2 means a weekly activity
            //and 1 bi-weekly 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]-2;
                              if(tmp>0){
                                    if(conflictsString!=NULL){
                                          (*conflictsString)+=QObject::tr("Time constraint basic compulsory");
                                          (*conflictsString)+=": ";
                                          (*conflictsString)+=QObject::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(k);
                                          (*conflictsString)+=". ";
                                          (*conflictsString)+=QObject::tr("This increases the conflicts factor with %1")
                                                .arg(tmp*weight);
                                          (*conflictsString)+="\n";
                                    }
                                    nte+=tmp;
                              }
                        }

            //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){
                                    if(conflictsString!=NULL){
                                          *conflictsString+=QObject::tr("Time constraint basic compulsory");
                                          *conflictsString+=": ";
                                          *conflictsString+=QObject::tr("subgroup %1 has more than one allocated activity on day %2, hour %3")
                                                .arg(r.internalSubgroupsList[i]->name)
                                                .arg(r.daysOfTheWeek[j])
                                                .arg(k);
                                          *conflictsString+=". ";
                                          *conflictsString+=QObject::tr("This increases the conflicts factor with %1")
                                                .arg((subgroupsMatrix[i][j][k]-2)*weight);
                                          *conflictsString+="\n";
                                    }
                                    nse += tmp;
                              }
                        }
      }
      
      if(teachersConflicts!=-1 && subgroupsConflicts!=-1){
            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
}


Generated by  Doxygen 1.6.0   Back to index