Commit 136dfac7 authored by Jeremie HUMEAU's avatar Jeremie HUMEAU

Merge branch 'ctsr_prereq' into 'cstr'

Ctsr prereq

See merge request !3
parents f42d9a7a 65e17ceb
......@@ -16,6 +16,8 @@ paradiseoPath> mkdir build && cd build && cmake ../ && make
2. Correctly link CEAO to your paradiseo install (Optional: **iff** you manually build Paradiseo)
Make sure that a folder cmake/module exists with a FindParadiseo.cmake file. It will be used to find your paradiseo install. Check e1124a07 for example.
Next, you need to locate your paradiseo install while invoking cmake, in order to have the library availables while building CEAO.
To do so, invoke cmake with the following option:
......
......@@ -8,6 +8,7 @@
#include <model/problem.h>
#include <model/profession.h>
#include <model/magnitude.h>
#include <model/tools.h>
#include <model/ea/cursus.h>
#include <model/ea/initializer.h>
......@@ -67,8 +68,8 @@ int main(int argc, char* argv[]){
CSDVP pb;
Profession job;
// ===== PB CONFIG ZONE =====
pb.set_cfg_quantityCourses(15);
pb.set_cfg_quantityCompetencies(15);
pb.set_cfg_quantityCourses(10);
pb.set_cfg_quantityCompetencies(5);
pb.set_cfg_minimalTimeFrames(1);
pb.set_cfg_maximalTimeFrames(6); //Just "Licence"
pb.set_cfg_ectsMin(1);
......@@ -80,7 +81,7 @@ int main(int argc, char* argv[]){
pb.set_cfg_minimalCompetencyByCourse(1);
pb.set_cfg_maximalCompetencyByCourse(3);
pb.set_cfg_minimalPrerequisiteByCourse(0);
pb.set_cfg_maximalPrerequisiteByCourse(2);
pb.set_cfg_maximalPrerequisiteByCourse(1);
pb.set_cfg_pickedCoursesByTimeFrame(2);
......@@ -136,11 +137,25 @@ int main(int argc, char* argv[]){
{
init(c1);
eval(c1);
//res = ctrECTS.integrityCheck(c1);
res = ctrECTS.integrityCheck(c1);
std::cout << "ECTS Metric" << std::to_string(res.second) << std::endl;
//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;
std::cout << "IND#" << std::to_string(i) << "\nFirst: " << res.first << "\nSecond: " << std::to_string((double)res.second) << std::endl;
if(res.first)
{
std::cout << "*************** OK PREREQ !! ***********" << std::endl;
}
else
{
std::cout << "$$$$$$$$$$$$$$$$ NON OK PREREQ !! $$$$$$$$$$$$$$$$$$$" << std::endl;
}
for(int i = 0 ; i < c1.size(); i++)
{
std::cout << pb.coursesCatalogue().at(c1.at(i)) << std::endl;
}
pop.push_back(c1);
}
//MUTATION TEST
......
......@@ -2,11 +2,14 @@
#include "competency.h"
#include "magnitude.h"
#include "tools.h"
#include "exception/magnitudeException.h"
#include "exception/competencyEvolvingException.h"
#include "exception/idOverflowException.h"
int Competency::COMPETENCY_COUNTER = 0;
int Competency::COMPETENCY_TMP_COUNTER = ID_RANGE_FOR_OBJECT + 1;
// === FACTORY
......@@ -37,6 +40,24 @@ Competency Competency::build(double d = 0, std::string name)
}
}
Competency Competency::buildTMP(double d, std::string name)
{
int id = Competency::assignID4TMP();
if(name.empty())
name = "Competency#"+std::to_string(id);
try
{
Magnitude m = Magnitude::build(d);
return Competency(id, m, name);
}
catch(MagnitudeException & e)
{
e.getMagnitude().rebase();
throw CompetencyEvolvingException(new Competency(id, e.getMagnitude(), name));
}
}
// === CONSTRUCTOR
Competency::Competency(int id, Magnitude m, std::string s)
......@@ -49,9 +70,21 @@ Competency::Competency(int id, Magnitude m, std::string s)
int Competency::assignID()
{
if(Competency::COMPETENCY_COUNTER + 1 > ID_RANGE_FOR_OBJECT)
throw idOverflowException("assignID()@Competency.cpp");
return ++Competency::COMPETENCY_COUNTER;
}
int Competency::assignID4TMP()
{
if(Competency::COMPETENCY_TMP_COUNTER + 1 > ID_RANGE_FOR_TEMPORARY_OBJECT)
{
std::cout << "INFO: COMPETENCY_TMP_COUNTER was about to overflow: restored to ID_RANGE_OBJECT + 1" << std::endl;
COMPETENCY_TMP_COUNTER = ID_RANGE_FOR_OBJECT + 1;
}
return ++Competency::COMPETENCY_TMP_COUNTER;
}
// === FUNCTION
void Competency::evolveTowards(Magnitude & m)
......
......@@ -24,10 +24,15 @@ class Competency
//STATIC
static int COMPETENCY_COUNTER;
static int COMPETENCY_TMP_COUNTER;
static int assignID();
static int assignID4TMP();//Called by the tmp builder
public:
static Competency build(Magnitude &, std::string s = "");
static Competency build(double, std::string = "");
///This builder should be used for TMP element
static Competency buildTMP(double, std::string);
Competency() = default;
// === FUNCTION
......
......@@ -18,7 +18,11 @@ std::pair<bool, double> ConstraintsECTS::integrityCheck(Cursus indiv)
if(tmpECTS >= this->_job.requiredECTS())
isCheckOK = true;
//std::cout << "Required: " << std::to_string(this->_job.requiredECTS());
double metric = (double)tmpECTS / this->_job.requiredECTS();
double metric;
if(tmpECTS > this->_job.requiredECTS())
metric = 1;
else
metric = (double)tmpECTS / this->_job.requiredECTS();
return std::pair<bool, double>(isCheckOK, metric);
}
\ No newline at end of file
......@@ -55,6 +55,22 @@ std::pair<bool, double> ConstraintsPrerequisites::integrityCheck(Cursus indiv)
//std::cout << "\tPrereq: " << std::to_string(currentCourse.prerequisites().size()) << std::endl;
nbPrereq += currentCourse.prerequisites().size();
//Handling prereq
// 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;
// Handling teached comp
for(int j = 0; j < currentCourse.teachedCompetenciesWeighted().size() ; j++)
{
currentCompetency = currentCourse.teachedCompetenciesWeighted().at(j).first;
......@@ -80,20 +96,7 @@ std::pair<bool, double> ConstraintsPrerequisites::integrityCheck(Cursus indiv)
}
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()));
compByTF.at(currentTF).push_back(Competency::buildTMP(currentCompetency.c_magnitude().value(), currentCompetency.c_name()));
}
}
}
......@@ -109,11 +112,24 @@ std::pair<bool, double> ConstraintsPrerequisites::integrityCheck(Cursus indiv)
}
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;
std::cout << "========== PREREQ CSTR RES ==========" << std::endl;
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 = 0;
if(nbPrereq > 0)
{
metric = 1.0 - ( (((double)2 * (double)notFound) + (double)notRespected ) / (2 * (double) nbPrereq) );
}
else //can't divide by 0
{
if(isOK)
metric = 1;
else
metric = 0;
}
std::cout << "Metric: " << std::to_string(metric) << std::endl;
std::cout << "====================" << std::endl;
return std::pair<bool, double>(isOK, metric);
}
......@@ -148,4 +164,4 @@ std::pair<int, int> ConstraintsPrerequisites::_prereqsInPreviousTF(std::vector<C
}
//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
......@@ -16,7 +16,7 @@ std::pair<bool, double> ConstraintsProfession::integrityCheck(Cursus indiv)
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
compToAnswer.push_back(Competency::buildTMP(0, name)); //same name to exploit the Competency::operator== on name equality
}
Course current;
......
......@@ -11,8 +11,10 @@
#include "exception/courseECTSException.h"
#include "exception/courseTemporalFrameException.h"
#include "exception/notImplementedException.h"
#include "exception/idOverflowException.h"
int Course::COURSE_COUNTER = 0;
int Course::COURSE_TMP_COUNTER = ID_RANGE_FOR_OBJECT + 1;
// === FACTORY
Course Course::build(int ects, std::string name)
......@@ -27,6 +29,19 @@ Course Course::build(int ects, std::string name)
else
return Course(id, ects, name);
}
Course Course::buildTMP(int ects, std::string name)
{
int id = Course::assignID4TMP();
if(name.empty())
name = "Course#"+std::to_string(id);
if(ects < 0)
throw CourseECTSException(new Course(id, ects, name));
else
return Course(id, ects, name);
}
// === END FACTORY
// === CONSTRUCTOR
......@@ -245,13 +260,13 @@ std::ostream& operator<<(std::ostream& Stream, const Course & c)
s+="\n\tRequirement: [";
for(int i = 0; i < c.prerequisites().size(); i++)
{
s+="" + c.prerequisites().at(i).c_name() + " ; ";
s+="" + c.prerequisites().at(i).c_name()+ "("+ std::to_string(c.prerequisites().at(i).c_magnitude().value()) + ") ; ";
}
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+= "" + c.teachedCompetenciesWeighted().at(i).first.c_name() + "("+ std::to_string(c.teachedCompetenciesWeighted().at(i).first.c_magnitude().value())+") ; ";
}
s+="]";
Stream << s;
......@@ -269,6 +284,18 @@ bool Course::operator==(const Course & c) const
/// Course counter
int Course::assignID()
{
if(Course::COURSE_COUNTER + 1 > ID_RANGE_FOR_OBJECT)
throw idOverflowException("assignID()@Course.cpp");
return ++Course::COURSE_COUNTER;
}
int Course::assignID4TMP()
{
if(Course::COURSE_TMP_COUNTER + 1 > ID_RANGE_FOR_TEMPORARY_OBJECT)
{
std::cout << "INFO: COURSE_TMP_COUNTER was about to overflow: restored to ID_RANGE_OBJECT + 1" << std::endl;
COURSE_TMP_COUNTER = ID_RANGE_FOR_OBJECT + 1;
}
return ++COURSE_TMP_COUNTER;
}
// === END STATIC
\ No newline at end of file
......@@ -55,13 +55,17 @@ class Course
// Static
static int COURSE_COUNTER;
static int COURSE_TMP_COUNTER;
static int assignID();
static int assignID4TMP();
// Constructor
//Course();
Course(int id, int ects, std::string name);
public:
static Course build(int ects = 0, std::string name = "");
static Course buildTMP(int ects = 0, std::string name = "");
/// Default constructor. Use Course::build instead !
Course() = default;
......
#ifndef SRD_MODEL_EXCEPTION_ID_OVERFLOW_EXCEPTION_H_
#define SRD_MODEL_EXCEPTION_ID_OVERFLOW_EXCEPTION_H_
#include <exception>
#include <string>
class idOverflowException : public std::exception
{
private:
std::string _msg;
public:
idOverflowException(std::string buildInfo) throw()
{
this->_msg = "The id of an object has overflow the maximal value. Where: "+buildInfo;
}
virtual const char* what() const throw()
{
return this->_msg.c_str();
}
};
#endif //SRD_MODEL_EXCEPTION_ID_OVERFLOW_EXCEPTION_H_
\ No newline at end of file
......@@ -362,7 +362,9 @@ int CSDVP::CSDVP_COUNTER = 0;
{
tmpComp = queue.front();
queue.pop();queue.push(tmpComp);
teachedComp = std::pair<Competency,double>(tmpComp, 1.0);
magVal = pb.cfg_magnitudeMin().value() + ( (double)rand()/RAND_MAX) * ( pb.cfg_magnitudeMax().value() - pb.cfg_magnitudeMin().value()) ;
Competency cpt = Competency::build(magVal,tmpComp.c_name());
teachedComp = std::pair<Competency,double>(cpt, 1.0);
pb.unlocked_coursesCatalogue().at(i).addTeachedComp(teachedComp);
}
}
......@@ -381,8 +383,12 @@ int CSDVP::CSDVP_COUNTER = 0;
for(int j = 0; j < x; j++)
{
tmpComp = queue.front();
queue.pop(); queue.push(tmpComp);
pb.unlocked_coursesCatalogue().at(i).addPrerequisite(tmpComp);
queue.pop();
//we change mag value for prereq
magVal = pb.cfg_magnitudeMin().value() + ( (double)rand()/RAND_MAX) * ( pb.cfg_magnitudeMax().value() - pb.cfg_magnitudeMin().value()) ;
Competency cpt = Competency::build(magVal,tmpComp.c_name());
pb.unlocked_coursesCatalogue().at(i).addPrerequisite(cpt);
queue.push(tmpComp);
}
}
......
......@@ -55,7 +55,7 @@ class CSDVP
std::vector<int> _timeFrames; // Time frames stocks the VALUE, not the index
std::vector<Course> _availableCourses;
std::vector<std::vector<Course>> _coursesSortedByTF; //sorted by standard index. e.g. TF[4;6] -> [0]=4; [1]=5 ; [2] = 6
std::vector<Competency> _availableCompentecies;
std::vector<Competency> _availableCompentecies; //The competency's magnitude should not be used here.
///@todo implements a decay politics
//DecayPolitics
......@@ -122,6 +122,9 @@ class CSDVP
const std::vector<int> & timeFrames() const{return this->_timeFrames;}
const std::vector<Course> & coursesCatalogue() const{return this->_availableCourses;}
/**CompetencyCatalogue should be used to know which competency exists in the current pb. However, it should not
* be used to know the magnitude of each comp in the pb, since these mag changes accordingly to the courses (and if it is teached or a prereq)
*/
const std::vector<Competency> & competencyCatalogue() const{return this->_availableCompentecies;}
const std::vector<std::vector<Course>> & coursesSortedByTF() const {return this->_coursesSortedByTF;}
std::vector<int> & unlocked_timeFrames(){return this->_timeFrames;}
......
......@@ -6,6 +6,10 @@
#include <algorithm>
#include <queue>
#include <random>
#include <limits>
static const int ID_RANGE_FOR_OBJECT = 10000;
static const int ID_RANGE_FOR_TEMPORARY_OBJECT = std::numeric_limits<int>::max();
template<typename T>
/** Searches into vec the element findMe. The class T must have T() defined ( T()=default; is OK) */
......
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