Commit a9c89e0d authored by Jeremie HUMEAU's avatar Jeremie HUMEAU

Merge branch 'cstr' into 'mut_cross'

# Conflicts:
#   application/main.cpp
parents 62f4c9fb 66b12fec
......@@ -17,6 +17,8 @@
#include <model/constraints/ectsConstraints.h>
#include <model/constraints/repetitionConstraints.h>
#include <model/constraints/professionConstraints.h>
#include <model/constraints/prerequisitesConstraints.h>
#include <model/exception/magnitudeException.h>
#include <model/exception/competencyEvolvingException.h>
......@@ -85,6 +87,14 @@ int main(int argc, char* argv[]){
assert(pb.checkConfig());
job.setRequiredECTS(4 * 6);
Competency tmpC = pb.competencyCatalogue().at(0);
job.addPrerequisite(tmpC);
tmpC = pb.competencyCatalogue().at(1);
job.addPrerequisite(tmpC);
tmpC = Competency::build(0.5,"Wesh");
job.addPrerequisite(tmpC);
tmpC = pb.competencyCatalogue().at(8);
job.addPrerequisite(tmpC);
// ===== END PB CONFIG =====
Cursus c1;
......@@ -116,15 +126,24 @@ int main(int argc, char* argv[]){
eoGenerationalReplacement<Cursus> replace;
eoPop<Cursus> pop;
/**@todo make size of the pb accessible as well as size of an individu*/
int size_of_the_pb = 30;
ConstraintsECTS ctrECTS(pb, job);
ConstraintsRepetition ctrRep(pb, job);
ConstraintsProfession ctrJob(pb, job);
ConstraintsPrerequisites ctrPrq(pb, job);
std::pair<bool,double> res;
for(int i = 0; i < size_of_the_pb; i++)
{
init(c1);
eval(c1);
res = ctrECTS.integrityCheck(c1);
res = ctrRep.integrityCheck(c1);
std::cout << "IND#" << std::to_string(i) << "\nFirst: " << res.first << "\nSecond: " << std::to_string(res.second) << std::endl;
//res = ctrECTS.integrityCheck(c1);
//res = ctrRep.integrityCheck(c1);
//res = ctrJob.integrityCheck(c1);
res = ctrPrq.integrityCheck(c1);
std::cout << "IND#" << std::to_string(i) << "\nFirst: " << res.first << "\nSecond: " << std::to_string((double)res.second) << std::endl;
pop.push_back(c1);
}
//MUTATION TEST
......
......@@ -6,6 +6,8 @@ SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
SET (EXERCICE_SOURCES
ectsConstraints.cpp
repetitionConstraints.cpp
professionConstraints.cpp
prerequisitesConstraints.cpp
)
ADD_LIBRARY(lCstr STATIC ${EXERCICE_SOURCES})
\ No newline at end of file
#include "prerequisitesConstraints.h"
#include <string>
#include <utility>
#include "model/course.h"
#include "model/competency.h"
#include "model/tools.h"
#include "model/exception/competencyEvolvingException.h"
std::pair<bool, double> ConstraintsPrerequisites::integrityCheck(Cursus indiv)
{
int currentTF = 0;
int notFound = 0;
int notRespected = 0;
int score = 0;
int nbPrereq = 0;
//Each comp availble at a specific TF. Decay can be applied between i and i+1
std::vector<std::vector<Competency>> compByTF(this->_pb.timeFrames().size());
Course currentCourse;
Competency currentCompetency;
std::pair<int, int> prereqFound; prereqFound.first = 0; prereqFound.second = 0;
std::pair<int, Competency> alreadyExists;
bool changedTF = false;
std::cout << "=========START========" << std::endl;
for(int i = 0; i < indiv.size() ; i++)
{
if(currentTF != i / this->_pb.cfg_pickedCoursesByTimeFrame())
{
//std::cout << "I've changed of TF" << std::endl;
changedTF = true;
}
else
changedTF = false;
currentTF = i / this->_pb.cfg_pickedCoursesByTimeFrame();
//std::cout << "Current TF: " << std::to_string(currentTF) << std::endl;
//If changedTF is set to true, then we have changed of TF, we need to make available all the Comp in TF-1 here in TF, in addition to the new that'll be discovered in TF
for(int j = 0 ; changedTF && j < compByTF.at(currentTF-1).size(); j++)
{
// HERE, VARIABLE DECAY CAN BE APPLIED!!!!!!!!
compByTF.at(currentTF).push_back(compByTF.at(currentTF-1).at(j));
}
// Then, we explore the current TF for new Comp
currentCourse = this->_pb.coursesCatalogue().at(indiv.at(i));
std::cout << "\t" << currentCourse << std::endl;
//std::cout << "\tPrereq: " << std::to_string(currentCourse.prerequisites().size()) << std::endl;
nbPrereq += currentCourse.prerequisites().size();
for(int j = 0; j < currentCourse.teachedCompetenciesWeighted().size() ; j++)
{
currentCompetency = currentCourse.teachedCompetenciesWeighted().at(j).first;
//Comp already exists in the array ?
alreadyExists = findInVector(compByTF.at(currentTF), currentCompetency);
if(alreadyExists.first >= 0) //Already Exists in the array
{
std::cout << currentCompetency.c_name() << " already exists" <<std::endl;
try
{
compByTF.at(currentTF).at(alreadyExists.first).evolveTowards(currentCompetency.magnitude());
}
catch(CompetencyEvolvingException & e) //if CEE is thrown, then magnitude has been auto rebased
{
//Should has NTD here
//compToAnswer.at(posFound.first) = e.getCompetency();
//std::cout << "INFO:\n(during ConstraintsProfession)\n\n Compentecy evolution throw an exception. Auto rebase. New value is " << e.getCompetency() << std::endl;
//std::cout << "Comp rebased val is" << compByTF.at(currentTF).at(alreadyExists.first) << std::endl;
std::cout << "exception.Rebased";
}
}
else
{
// Check if prerequisites exists in TF-1
if(currentTF > 0)
{
prereqFound = this->_prereqsInPreviousTF(compByTF.at(currentTF-1), currentCourse.prerequisites());
}
else
{
prereqFound = this->_prereqsInPreviousTF(std::vector<Competency>(0), currentCourse.prerequisites());
}
notFound += prereqFound.first;
notRespected += prereqFound.second;
compByTF.at(currentTF).push_back(Competency::build(currentCompetency.c_magnitude().value(), currentCompetency.c_name()));
}
}
}
std::cout << "==EXPLORING COMP BY TF" << std::endl;
for(int i = 0; i < compByTF.size(); i++)
{
std::cout << "TF#" << std::to_string(i) << std::endl;
for(int j = 0; j < compByTF.at(i).size() ; j++)
{
std::cout << compByTF.at(i).at(j) << std::endl;
}
}
bool isOK = ((notFound == 0) && (notRespected == 0));
std::cout << "Not Found: " << std::to_string(notFound) << std::endl;
std::cout << "Not Respected: " << std::to_string(notRespected) << std::endl;
std::cout << "Nb Prereq: " << std::to_string(nbPrereq) << std::endl;
double metric = 1.0 - ( (((double)2 * (double)notFound) + (double)notRespected ) / (2 * (double) nbPrereq) );
std::cout << "Metric: " << std::to_string(metric) << std::endl;
return std::pair<bool, double>(isOK, metric);
}
std::pair<int, int> ConstraintsPrerequisites::_prereqsInPreviousTF(std::vector<Competency> cInTF, std::vector<Competency> prereqs)
{
int notFound = 0;
int notRespected = 0;
bool found = false;
if(cInTF.size() == 0) //if empty, we'll find nothing
return std::pair<int, int>(prereqs.size(), 0);
for(int i = 0; i < prereqs.size(); i++)
{
found = false;
std::cout << "Looking for " << prereqs.at(i) << std::endl;
for(int j = 0 ; j < cInTF.size() && !found; j++)
{
std::cout << "\n\t" << cInTF.at(j) << std::endl;
if(prereqs.at(i)==cInTF.at(j))
{
found = true;
if(prereqs.at(i).c_magnitude().value() > cInTF.at(j).c_magnitude().value())
notRespected++;
}
}
if(!found)
notFound++;
}
std::cout << "NF: " << std::to_string(notFound) << " | NR: " << std::to_string(notRespected) << std::endl;
return std::pair<int, int>(notFound, notRespected);
}
\ No newline at end of file
#ifndef SRC_MODEL_CONSTRAINTS_PREREQUISITES_CONSTRAINTS_H_
#define SRC_MODEL_CONSTRAINTS_PREREQUISITES_CONSTRAINTS_H_
#include <vector>
#include <utility>
#include <eo>
#include "model/problem.h"
#include "model/profession.h"
#include "model/ea/cursus.h"
/**
* This class is used to verify constraints regarding the prerequisites of each courses of an individu (indiv).
* Each prerequisites of each courses must be respected. Note that the position of the courses in the indiv is important,
* since it represents how the courses are dispatched in the timeframes.
* Logically, a course see in TF t DO NOT CONTRIBUTE in the prerequisite for the courses in x < t
*/
class ConstraintsPrerequisites
{
private:
CSDVP _pb;
Profession _job;
/**
* Checks the prerequisites prereqs in the competencies cInTF (generally, the competencies from the previous TF).
* It returns a std::pair, where the first element indicates how many prerequisites HAS NOT BEEN FOUND.
* The second elements indicates how many prerequisites has not enought mastery (BUT EXISTS in cInTF!)
*/
std::pair<int,int> _prereqsInPreviousTF(std::vector<Competency> cInTF, std::vector<Competency> prereqs);
public:
ConstraintsPrerequisites(const CSDVP & csdvp, const Profession & job)
: _pb(csdvp), _job(job) {}
/** Integrity check is used to investigate wheteher or not one indiv respects the constraints represented by THIS.
* Returns a std::pair. First is a boolean set to true when the indiv passes the test and therefore is compilant with the constraint, false otherwise. Second is the associated metric, mostly usable during fitness calcul.
* @todo Decay competency magnitude
*/
std::pair<bool, double> integrityCheck(Cursus indiv);
};
#endif // SRC_MODEL_CONSTRAINTS_PREREQUISITES_CONSTRAINTS_H_
\ No newline at end of file
#include "professionConstraints.h"
#include <string>
#include <utility>
#include "model/course.h"
#include "model/competency.h"
#include "model/tools.h"
#include "model/exception/competencyEvolvingException.h"
std::pair<bool, double> ConstraintsProfession::integrityCheck(Cursus indiv)
{
std::vector<Competency> compToAnswer;
for(int i = 0 ; i < this->_job.prerequisites().size(); i++)
{
std::string name = this->_job.prerequisites().at(i).c_name();
compToAnswer.push_back(Competency::build(0, name)); //same name to exploit the Competency::operator== on name equality
}
Course current;
Competency currentComp;
std::pair<int, Competency> posFound;
for(int i = 0 ; i < indiv.size(); i++)
{
current = this->_pb.coursesCatalogue().at(indiv.at(i));
for(int j = 0 ; j < current.teachedCompetenciesWeighted().size() ; j++)
{
currentComp = current.teachedCompetenciesWeighted().at(j).first;
posFound = findInVector(compToAnswer, currentComp);
if(posFound.first != -1)
{
try
{
compToAnswer.at(posFound.first).evolveTowards(currentComp.magnitude());
}
catch(CompetencyEvolvingException & e) //if CEE is thrown, then magnitude has been auto rebased
{
//Should has NTD here
//compToAnswer.at(posFound.first) = e.getCompetency();
std::cout << "INFO:\n(during ConstraintsProfession)\n\n Compentecy evolution throw an exception. Auto rebase. New value is " << e.getCompetency() << std::endl;
}
}
}
}
//Now that we have evolve all the tmp competency, we compate their mag to the requirement. We count how many is not met to define the metric
int score = 0;
for(int i = 0; i < this->_job.prerequisites().size(); i++)
{
if(compToAnswer.at(i).magnitude().value() < this->_job.prerequisites().at(i).c_magnitude().value())
score++;
}
std::cout << "Score: " << std::to_string(score) << std::endl;
std::cout << "Size: " << std::to_string(compToAnswer.size()) << std::endl;
bool res = score == 0;
return std::pair<bool, double>(res, 1 - ( (double)score / (double)compToAnswer.size()));
}
\ No newline at end of file
#ifndef SRC_MODEL_CONSTRAINTS_PROFESSION_CONSTRAINTS_H_
#define SRC_MODEL_CONSTRAINTS_PROFESSION_CONSTRAINTS_H_
#include <vector>
#include <utility>
#include <eo>
#include "model/problem.h"
#include "model/profession.h"
#include "model/ea/cursus.h"
/**
* This class is used to verify the constraints regarding the profession expected by the student
* It mostly consist in *version 1* to check if all the prerequisites have been answered.
*/
class ConstraintsProfession
{
private:
CSDVP _pb;
Profession _job;
public:
ConstraintsProfession(const CSDVP & csdvp, const Profession & job)
: _pb(csdvp), _job(job) {}
/** Integrity check is used to investigate wheteher or not one indiv respects the constraints represented by THIS.
* Returns a std::pair. First is a boolean set to true when the indiv passes the test and therefore is compilant with the constraint, false otherwise. Second is the associated metric, mostly usable during fitness calcul.
* @todo Decay competency magnitude
*/
std::pair<bool, double> integrityCheck(Cursus indiv);
};
#endif // SRC_MODEL_CONSTRAINTS_PROFESSION_CONSTRAINTS_H_
\ No newline at end of file
......@@ -241,6 +241,19 @@ std::ostream& operator<<(std::ostream& Stream, const Course & c)
tf+=std::to_string(c.timeFrame().at(c.timeFrame().size()-1));
s+="\n\tTimeFrames: ["+tf+"]";
}
s+="\n\tRequirement: [";
for(int i = 0; i < c.prerequisites().size(); i++)
{
s+="" + c.prerequisites().at(i).c_name() + " ; ";
}
s+="]";
s+="\n\tTeaches: [";
for(int i = 0 ; i < c.teachedCompetenciesWeighted().size(); i++)
{
s+= "" + std::to_string(c.teachedCompetenciesWeighted().at(i).second) + "." + c.teachedCompetenciesWeighted().at(i).first.c_name() + " ; ";
}
s+="]";
Stream << s;
return Stream;
}
......
......@@ -179,6 +179,13 @@ int CSDVP::CSDVP_COUNTER = 0;
}
}
}
int CSDVP::mapCourseToPosition(const Course & c)
{
for(int i = 0; i << this->coursesCatalogue().size(); i++)
if(c == this->coursesCatalogue().at(i))
return i;
return -1;
}
// === END FUNC
// === STATIC
......
......@@ -133,6 +133,10 @@ class CSDVP
return this->_timeFrames.size() * this->_pickedCoursesByTimeFrame;
return -1;//if not config
}
/** Maps a course into its position inside the this->courseCatalogue().
* returns the index of the course within the coursesCatalogue [0;size[ ; otherwise return -1 if the course is not found.
*/
int mapCourseToPosition(const Course & c);
///@todo getDecayPolitic
// === MUTATOR
......
......@@ -40,6 +40,17 @@ static bool duplicataFlag(std::vector<T> & toProtect, T & toAdd)
}
template<typename T>
static std::pair<bool,T> getElementById(const std::vector<T> & elem, int idToFind)
{
for(int i = 0; i < elem.size(); i++)
{
if(elem.at(i).id() == idToFind)
return std::pair<bool,T>(true, elem.at(i));
}
return std::pair<bool, T>(false, T());
}
///Not working properly yet, just for debug
// static std::queue<int> RNG_QUEUE;
// /**Init a queue of size s from 0 to s, then shuffle it*/
......
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