Commit 1340937a authored by Alexis Lebis's avatar Alexis Lebis

new mutation

parent adedcb1e
...@@ -232,8 +232,8 @@ bool Course::_duplicataProtection(std::vector<std::pair<Competency,double>> *tea ...@@ -232,8 +232,8 @@ bool Course::_duplicataProtection(std::vector<std::pair<Competency,double>> *tea
bool Course::_lazyEquality(const Course & c) const bool Course::_lazyEquality(const Course & c) const
{ {
return (this->_id == c.id() && return ( (this->_id == c.id() ||
this->_name.compare(c.name()) == 0 && this->_name.compare(c.name()) == 0 ) &&
this->_ects == c.ects() this->_ects == c.ects()
); );
} }
...@@ -298,4 +298,25 @@ int Course::assignID4TMP() ...@@ -298,4 +298,25 @@ int Course::assignID4TMP()
} }
return ++COURSE_TMP_COUNTER; return ++COURSE_TMP_COUNTER;
} }
/** It produces a new vector, which is another view of courses in param, sorted by TF
* Duplicates the behaviour of CSDVP::_makeCoursesSortedByTF() except that it applies to any vector of courses
* size of timeFrames must be equal to the maximal TF value in courses.timeFrames !
*/
std::vector<std::vector<Course>> Course::organiseByTF(std::vector<Course> courses, std::vector<int> timeFrames)
{
std::vector<std::vector<Course>> coursesByTF(timeFrames.size());
int tmpIdx;
for(int i = 0; i < courses.size(); i++)
{
for(int j = 0; j < courses.at(i).timeFrame().size(); j++)
{
tmpIdx = courses.at(i).timeFrame().at(j) - timeFrames.at(0);
coursesByTF.at(tmpIdx).push_back(courses.at(i));
}
}
return coursesByTF;
}
// === END STATIC // === END STATIC
\ No newline at end of file
...@@ -67,6 +67,8 @@ class Course ...@@ -67,6 +67,8 @@ class Course
static Course build(int ects = 0, std::string name = ""); static Course build(int ects = 0, std::string name = "");
static Course buildTMP(int ects = 0, std::string name = ""); static Course buildTMP(int ects = 0, std::string name = "");
static std::vector<std::vector<Course>> organiseByTF(std::vector<Course> courses, std::vector<int> timeFrames);
/// Default constructor. Use Course::build instead ! /// Default constructor. Use Course::build instead !
Course() = default; Course() = default;
...@@ -75,6 +77,7 @@ class Course ...@@ -75,6 +77,7 @@ class Course
const std::string name() const{return this->_name;}; const std::string name() const{return this->_name;};
const int ects() const{return this->_ects;} const int ects() const{return this->_ects;}
const std::vector<Competency> prerequisites() const {return this->_prerequisites;} const std::vector<Competency> prerequisites() const {return this->_prerequisites;}
std::vector<Competency>& unlocked_prerequisites() {return this->_prerequisites;}
const std::vector<int> timeFrame() const {return this->_temporalAvailability;} const std::vector<int> timeFrame() const {return this->_temporalAvailability;}
const std::vector<std::pair<Competency, double>> teachedCompetenciesWeighted() const{return this->_weightedTeached;} const std::vector<std::pair<Competency, double>> teachedCompetenciesWeighted() const{return this->_weightedTeached;}
......
#ifndef SRC_MODEL_EA_MUTATION_H_ #ifndef SRC_MODEL_EA_MUTATION_H_
#define SRC_MODEL_EA_MUTATION_H_ #define SRC_MODEL_EA_MUTATION_H_
#include <algorithm>
#include <eoSwapMutation.h> #include <eoSwapMutation.h>
#include <eoShiftMutation.h> #include <eoShiftMutation.h>
#include "cursus.h" #include "cursus.h"
#include "model/course.h"
#include "model/competency.h"
#include "model/tools.h"
#include "model/magnitude.h"
#include "model/constraints/repetitionConstraints.h" #include "model/constraints/repetitionConstraints.h"
#include "model/exception/competencyEvolvingException.h"
template <class EOT> template <class EOT>
class mutCSDVP: public eoMonOp<EOT> class mutCSDVP: public eoMonOp<EOT>
{ {
...@@ -28,56 +37,265 @@ class mutCSDVP: public eoMonOp<EOT> ...@@ -28,56 +37,265 @@ class mutCSDVP: public eoMonOp<EOT>
} }
} }
/** @version 1.0
virtual bool operator()(EOT& _chrom){ * @author Jérem
bool res=false; */
// virtual bool operator()(EOT& _chrom){
// bool res=false;
// std::pair<bool, double> ctrRes= ctr.integrityCheck(_chrom);
// //Integrity Check AFTER CROSS
// assert(ctrRes.first);
// //_chrom.printOn(std::cout);
// //std::cout << std::endl;
// //On cherche une mutation
// unsigned int i;
// const std::vector<int> TF = pb.timeFrames();
// unsigned int nbTF=TF.size();
// unsigned int sizeTF=_chrom.size()/nbTF;
// const std::vector<Course> catalogue = pb.coursesCatalogue();
// //std::cout << "Catalogue Size: " << catalogue.size() << ", nbTF: " << nbTF << ", sizeTF: " << sizeTF << std::endl;
// //std::cout << "TF min: " << pb.cfg_courseByTFMin() << std::endl;
// std::vector<int> courseID;
// std::vector<int> TFavailabilities;
// for(i=0; i<catalogue.size(); i++)
// courseID.push_back(i);
// //on garde que les cours pas encore choisi
// notin(courseID,_chrom);
// /*
// //std::cout << "id des cours dispos: ";
// for(int i=0; i<courseID.size(); i++)
// std::cout << courseID[i] << " ";
// std::cout << std::endl;
// */
// //on en prend un au hasard dedans
// unsigned int newCourse=eo::rng.random(courseID.size());
// //std::cout << "newCourse: " << courseID[newCourse] << std::endl;
// //on regarde les time frame dispo pour ce cours
// TFavailabilities=catalogue[courseID[newCourse]].timeFrame();
// //on tape au hazard dans une de ces time frame
// unsigned int replaceTF=eo::rng.random(TFavailabilities.size());
// unsigned int oldCourse=eo::rng.random(sizeTF);
// //std::cout << "Try to Replace " << _chrom[((TFavailabilities[replaceTF]-pb.cfg_minimalTimeFrame())*sizeTF) + oldCourse] << " by " << courseID[newCourse] << " in TF: " << TFavailabilities[replaceTF] << std::endl;
// _chrom[((TFavailabilities[replaceTF]-pb.cfg_minimalTimeFrame())*sizeTF) + oldCourse]=courseID[newCourse];
// //std::cout << std::endl << std::endl;
// ctrRes= ctr.integrityCheck(_chrom);
// res=true;
// _chrom.invalidate();
// return res;
// }
/**
* This mutation choose a course randomly, then replace it with a course available in the current TF.
* The course selection is made as follow :
* Select a course (at random) where its prerequisite are respected by the previous assignation
* Otherwise, pick the least constrained course
* Note that even if the select course's prerequisite may be respected, the _chrom is not guaranteed to be a solution, since the previous
* assignement of course could be wrong.
* @author Alex
* @version 2.0
* @todo optimize
*/
virtual bool operator()(EOT& _chrom)
{
// CFG
unsigned int cmptAlert = 0;
unsigned int tresholdAlert = 10;
unsigned int tresholdAbort = 100;
// -----
bool success=false;
std::pair<bool, double> ctrRes= ctr.integrityCheck(_chrom); std::pair<bool, double> ctrRes= ctr.integrityCheck(_chrom);
//Integrity Check AFTER CROSS //Integrity Check AFTER CROSS
assert(ctrRes.first); assert(ctrRes.first);
//_chrom.printOn(std::cout); // Mutation set up
//std::cout << std::endl; unsigned int i;
//On cherche une mutation const std::vector<int> TF = pb.timeFrames();
unsigned int i; unsigned int nbTF=TF.size();
const std::vector<int> TF = pb.timeFrames(); unsigned int sizeTF=_chrom.size()/nbTF;
unsigned int nbTF=TF.size(); const std::vector<Course> catalogue = pb.coursesCatalogue();
unsigned int sizeTF=_chrom.size()/nbTF;
const std::vector<Course> catalogue = pb.coursesCatalogue();
//std::cout << "Catalogue Size: " << catalogue.size() << ", nbTF: " << nbTF << ", sizeTF: " << sizeTF << std::endl;
//std::cout << "TF min: " << pb.cfg_courseByTFMin() << std::endl;
std::vector<int> courseID; std::vector<int> courseID;
std::vector<int> TFavailabilities; std::vector<Course> availableC;
std::vector<std::vector<Course>> sortedC;
std::vector<int> availableTF;
std::vector<Course> coursesOfTF;
std::vector<Competency> statesOfComp;
int rngTF = 0;
int rngCourseToSwap;
int tfPositionOfRngCourse;
std::vector<Course> gfiCourse; //go for it courses : they pass the prereq
Course fbBestCourse; //fb : Fallback
// //we repeat here because mutation may fail if bad pick happens;
// do
// {
for(i=0; i<catalogue.size(); i++) for(i=0; i<catalogue.size(); i++)
courseID.push_back(i); courseID.push_back(i);
//on garde que les cours pas encore choisi
//Keeping only not taken courses
notin(courseID,_chrom); notin(courseID,_chrom);
//Filling availables courses
for(i = 0; i < courseID.size(); i++)
availableC.push_back(catalogue.at(courseID.at(i)));
/* // Sorting courses by TF
//std::cout << "id des cours dispos: "; sortedC = Course::organiseByTF(availableC, pb.timeFrames());
for(int i=0; i<courseID.size(); i++) for(i = 0; i < sortedC.size(); i++)
std::cout << courseID[i] << " "; if(sortedC.at(i).size() > 0)
std::cout << std::endl; availableTF.push_back(i);
*/
//Defining which course should be mutated (i.e. swapped with another non taken)
//on en prend un au hasard dedans rngCourseToSwap = eo::rng.random(_chrom.size());
unsigned int newCourse=eo::rng.random(courseID.size());
//std::cout << "newCourse: " << courseID[newCourse] << std::endl;
//on regarde les time frame dispo pour ce cours
TFavailabilities=catalogue[courseID[newCourse]].timeFrame();
//on tape au hazard dans une de ces time frame
unsigned int replaceTF=eo::rng.random(TFavailabilities.size());
unsigned int oldCourse=eo::rng.random(sizeTF);
//std::cout << "Try to Replace " << _chrom[((TFavailabilities[replaceTF]-pb.cfg_minimalTimeFrame())*sizeTF) + oldCourse] << " by " << courseID[newCourse] << " in TF: " << TFavailabilities[replaceTF] << std::endl;
_chrom[((TFavailabilities[replaceTF]-pb.cfg_minimalTimeFrame())*sizeTF) + oldCourse]=courseID[newCourse];
//std::cout << std::endl << std::endl;
ctrRes= ctr.integrityCheck(_chrom); tfPositionOfRngCourse = rngCourseToSwap / sizeTF;
res=true; coursesOfTF = sortedC.at(tfPositionOfRngCourse);
_chrom.invalidate();
if(coursesOfTF.size() == 0) //No mutation is possible !
{
std::random_shuffle(courseID.begin(), courseID.end());
_chrom[rngCourseToSwap] = courseID.at(0);
_chrom.invalidate();
return false; //No mutation is possible !
}
//Defining the status of competencies mastery until the specified TF
statesOfComp = _getCompStatusAtTF(pb.coursesCatalogue(), _chrom, tfPositionOfRngCourse, sizeTF);
//Taking the best course OR the one with the less of prereq
gfiCourse = _getOKCourse(coursesOfTF, statesOfComp);
if(gfiCourse.size() > 0)
{
std::random_shuffle(gfiCourse.begin(), gfiCourse.end());
_chrom[rngCourseToSwap] = pb.mapCourseToPosition(gfiCourse.at(0));
}
else //least constraint courses
{
fbBestCourse = coursesOfTF.at(0);
for(i = 1; i < coursesOfTF.size(); i++)
{
if(fbBestCourse.prerequisites().size() > coursesOfTF.at(i).prerequisites().size())
fbBestCourse = coursesOfTF.at(i);
}
_chrom[rngCourseToSwap] = pb.mapCourseToPosition(fbBestCourse);
}
// if(!success)
// {
// cmptAlert++;
// if(cmptAlert % tresholdAlert == 0)
// std::cout << "INFO! Several mutation do not success currently" << std::endl;
// if(cmptAlert >= tresholdAbort)
// {
// std::cout << "WARNING! Max mutation reroll reached. We crash the program." << std::endl;
// assert(false);
// }
// }
// } while (!success);
_chrom.invalidate();
return false;
}
/** _getCompStatusAtTF returns the status of the magnitude of all the competencies sawn in all the timeframes below TF.
*/
std::vector<Competency> _getCompStatusAtTF(const std::vector<Course>& catalogue, std::vector<int>& _chrom, int TF, int nbCbyTF)
{
std::vector<Competency> compStatus;
std::vector<Competency> prereqs;
Course tmpCourse = Course::buildTMP();
Course currentCourse;
Competency tmpComp;
bool addStatus = false;
int pos=0;
for(int i = 0; i < _chrom.size() && (i / nbCbyTF < TF); i++)
{
currentCourse = catalogue.at(_chrom.at(i));
for(int j = 0; j < currentCourse.teachedCompetenciesWeighted().size(); j++)
{
tmpComp = currentCourse.teachedCompetenciesWeighted().at(j).first;
addStatus = tmpCourse.addPrerequisite(tmpComp);
if(!addStatus) // comp already exist, then lets evolve it instead
{
prereqs = tmpCourse.prerequisites();
std::pair<int, Competency> fiv= findInVector(prereqs, tmpComp);
pos = fiv.first;
try
{
Magnitude mag = currentCourse.teachedCompetenciesWeighted().at(j).first.c_magnitude();
tmpCourse.unlocked_prerequisites().at(pos).evolveTowards(mag);
}
catch(CompetencyEvolvingException & e)
{
//Should has NTD here
//auto rebased
}
}
}
}
compStatus = tmpCourse.prerequisites();
return compStatus;
}
std::vector<Course> _getOKCourse(std::vector<Course> availableC, std::vector<Competency> state)
{
std::vector<Course> res;
bool stop = false;
bool found = false;
bool isPrereqOK = true;
unsigned int j = 0;
unsigned int itState = 0;
Competency checkCmp;
for(int i = 0; i < availableC.size(); i++)
{
isPrereqOK = true;
for(j = 0; j < availableC.at(i).prerequisites().size() && isPrereqOK; j++)
{
checkCmp = availableC.at(i).prerequisites().at(j);
stop = false;
found = false;
for(itState = 0; itState < state.size() && !stop; itState++)
{
if(checkCmp == state.at(itState))
{
if(checkCmp.c_magnitude().value() > state.at(itState).c_magnitude().value())
{ stop = true; found = false; }
else
{ stop = true; found = true; }
}
}
if(found)
isPrereqOK = true;
else
isPrereqOK = false;
}
if(isPrereqOK)
res.push_back(availableC.at(i));
}
return res; return res;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment