Commit 1f148554 authored by Alexis Lebis's avatar Alexis Lebis

Merge branch 'csdvpImplem' into 'master'

CSDVP model implemented in C++

See merge request !1
parents e1124a07 3a8291e5
correction/
build/
howto.pdf
\ No newline at end of file
howto.pdf
.vscode/
\ No newline at end of file
......@@ -5,11 +5,11 @@
cmake_minimum_required(VERSION 2.6)
# Here define your project name
project(QUEEN)
project(CEAO)
# Here define the name and the version of your package
set(PACKAGE_NAME "QUEEN" CACHE STRING "Package name" FORCE)
set(PACKAGE_VERSION "2.0" CACHE STRING "aPackage version" FORCE)
set(PACKAGE_NAME "CEAO" CACHE STRING "Package name" FORCE)
set(PACKAGE_VERSION "1.0" CACHE STRING "aPackage version" FORCE)
# regular expression checking
......
......@@ -4,9 +4,9 @@ Constraint Satisfaction Decaying Variables Problem (CSDVP) optimization through
## Dependencies and configuration
1. CEAO project depends on the C++ [http://paradiseo.gforge.inria.fr/index.php?](Paradiseo Framework).
1. CEAO project depends on the C++ [Paradiseo Framework](http://paradiseo.gforge.inria.fr/index.php?).
Therefore, you must [http://paradiseo.gforge.inria.fr/index.php?n=Download.Download](download and install) it.
Therefore, you must [download and install](http://paradiseo.gforge.inria.fr/index.php?n=Download.Download) it.
If you cloned the Paradiseo's repository, do not forget to build it:
......@@ -14,7 +14,7 @@ If you cloned the Paradiseo's repository, do not forget to build it:
paradiseoPath> mkdir build && cd build && cmake ../ && make
```
2. Correctly link CEAO to your paradiseo install (Optional, iff you manualy build Paradiseo)
2. Correctly link CEAO to your paradiseo install (Optional: **iff** you manually build Paradiseo)
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:
......
......@@ -4,13 +4,23 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
# 2) Define targets: executable and dependencies
ADD_EXECUTABLE(solveQueen main.cpp)
ADD_EXECUTABLE(ceao main.cpp)
ADD_EXECUTABLE(ceao_competency ceao_competency.cpp)
ADD_EXECUTABLE(ceao_course ceao_course.cpp)
ADD_EXECUTABLE(ceao_profession ceao_profession.cpp)
ADD_EXECUTABLE(ceao_csdvp ceao_csdvp.cpp)
ADD_EXECUTABLE(tryInit tryInit.cpp)
ADD_EXECUTABLE(tryMutation tryMutation.cpp)
ADD_EXECUTABLE(tryCrossover tryCrossover.cpp)
ADD_EXECUTABLE(tryEval tryEval.cpp)
ADD_DEPENDENCIES(solveQueen lQueen)
ADD_DEPENDENCIES(ceao lQueen lModel)
ADD_DEPENDENCIES(ceao_competency lQueen lModel)
ADD_DEPENDENCIES(ceao_course lQueen lModel)
ADD_DEPENDENCIES(ceao_profession lQueen lModel)
ADD_DEPENDENCIES(ceao_csdvp lQueen lModel)
ADD_DEPENDENCIES(tryInit lQueen)
ADD_DEPENDENCIES(tryMutation lQueen)
ADD_DEPENDENCIES(tryCrossover lQueen)
......@@ -18,7 +28,12 @@ ADD_DEPENDENCIES(tryEval lQueen)
# 3) Link the librairies for your executable
TARGET_LINK_LIBRARIES(solveQueen ${PARADISEO_LIBRARIES} lQueen)
TARGET_LINK_LIBRARIES(ceao ${PARADISEO_LIBRARIES} lQueen lModel)
TARGET_LINK_LIBRARIES(ceao_competency ${PARADISEO_LIBRARIES} lQueen lModel)
TARGET_LINK_LIBRARIES(ceao_course ${PARADISEO_LIBRARIES} lQueen lModel)
TARGET_LINK_LIBRARIES(ceao_profession ${PARADISEO_LIBRARIES} lQueen lModel)
TARGET_LINK_LIBRARIES(ceao_csdvp ${PARADISEO_LIBRARIES} lQueen lModel)
TARGET_LINK_LIBRARIES(tryInit ${PARADISEO_LIBRARIES} lQueen)
TARGET_LINK_LIBRARIES(tryMutation ${PARADISEO_LIBRARIES} lQueen)
TARGET_LINK_LIBRARIES(tryCrossover ${PARADISEO_LIBRARIES} lQueen)
......
#include <eo>
#include <iostream>
#include <string>
#include <cassert>
#include "model/magnitude.h"
#include "model/competency.h"
#include "model/exception/magnitudeException.h"
#include "model/exception/competencyEvolvingException.h"
int main(int argc, char* argv[])
{
Magnitude m = Magnitude::build(0.7);
Competency c = Competency::build(0.5, "");
Competency c2 = Competency::build(m,"");
Competency c3 = Competency::build(0.5);
assert(c3.name().compare("Competency#"+std::to_string(c3.id())) == 0);
std::cout << "Default naming ok" << std::endl;
std::cout << std::to_string(c.c_magnitude().value()) << std::endl ;
std::cout << c2.competencyValue() << std::endl;
c.evolveTowards(0.2);
std::cout << c << std::endl;
c.evolveTowards(-0.2);
std::cout << c << std::endl;
c.evolveTowards(-0.3);
std::cout << c << std::endl;
c.evolveTowards(m);
std::cout << c << std::endl;
try
{
c.evolveTowards(2);
}
catch(CompetencyEvolvingException & e)
{
std::cout << e.what() << std::endl;
e.getCompetency().setName("Oeuf!");
std::cout << e.getCompetency() << std::endl;
std::cout << c << std::endl;
}
c.evolveTowards(-0.5);
std::cout << c << std::endl;
assert( c == c);
std::cout << "c == c OK" << std::endl ;
std::cout << "renaming c2 as c.name()" << std::endl;
c2.setName(c.name());
assert( c == c2);
std::cout << "c == c2 OK" << std::endl ;
assert ( !(c == c3) );
std::cout << "c != c3 OK" << std::endl;
return EXIT_SUCCESS;
}
\ No newline at end of file
#include <eo>
#include <iostream>
#include <string>
#include <cassert>
#include <utility>
#include <vector>
#include "model/course.h"
#include "model/competency.h"
#include "model/exception/courseECTSException.h"
#include "model/exception/courseTemporalFrameException.h"
#include "model/exception/competencyEvolvingException.h"
int main(int argc, char* argv[])
{
Course c = Course::build();
std::cout << c << std::endl;
assert(c.prerequisites().size() == 0);
std::cout << "Length of prereq: " << c.prerequisites().size() << std::endl;
c = Course::build();
std::cout << c << std::endl;
assert(c.prerequisites().size() == 0);
std::cout << "Length of prereq still : " << c.prerequisites().size() << " after redefining." << std::endl;
c = Course::build(5);
assert(c.ects() == 5);
std::cout << "C's ects is equal to five" << std::endl;
c = Course::build(7,"Testdel'oeuf");
std::cout << c << std::endl;
assert(c.ects() == 7 && (c.name().compare("Testdel'oeuf") == 0) );
std::cout << "Comp constructor ok" << std::endl;
try
{
c = Course::build(-1, "lol");
}
catch(CourseECTSException & e)
{
assert(e.getCourse().ects() == -1);
std::cout << "Last ects set correctly taken into account" << std::endl;
std::cout << e.what() << std::endl;
std::cout << c << std::endl;
}
Competency comp1 = Competency::build(0.2);
Competency comp2 = Competency::build(0.4);
Competency comp3 = Competency::build(0.7);
c.addPrerequisite(comp1);
assert(c.prerequisites().size() == 1);
assert(c.prerequisites().at(0) == comp1 );
std::cout << "Prereq add OK" << std::endl;
c.addPrerequisite(comp2);
Competency * ptr_c = c.rmPrerequisite(comp1);
assert(ptr_c != NULL);
assert(c.prerequisites().size() == 1);
assert(c.prerequisites().at(0) == comp2);
std::cout << "Prereq rm 1/2 OK" << std::endl ;
c.addPrerequisite(comp1);
ptr_c = c.rmPrerequisite(comp3);
assert(ptr_c == NULL);
assert(c.prerequisites().size() == 2);
assert(c.prerequisites().at(0) == comp2 );
assert(c.prerequisites().at(1) == comp1);
std::cout << "Prereq rm 2/2 OK" << std::endl ;
c.addTemporalFrame(0);
c.addTemporalFrame(2);
assert(c.timeFrame().size() == 2);
c.addTemporalFrame(2);
assert(c.timeFrame().size() == 2);
std::cout << "_temporalAvailability is protected against duplicate" << std::endl;
try{
c.addTemporalFrame(-2);
}
catch(CourseTemporalFrameException & e)
{
std::cout << e.what() << std::endl;
assert(e.getTime() == -2);
assert(c.timeFrame().size() == 2);
std::cout << "Excepetion handling ok" << std::endl;
}
int * ptr_time = c.rmTemporalFrameValue(2);
assert(ptr_time != NULL && c.timeFrame().size()==1);
std::cout << "Temporal rm by value 1/2 ok" << std::endl;;
ptr_time = c.rmTemporalFrameValue(2);
assert(ptr_time == NULL && c.timeFrame().size() == 1);
std::cout << "Temp rm by val 2/2 ok" << std::endl;
c.addTemporalFrame(7);
ptr_time = c.rmTemporalFrameIndex(1);
assert(ptr_time != NULL && *ptr_time == 7);
assert(c.timeFrame().size()==1 && c.timeFrame().at(0) == 0);
std::cout << "Temporal rm by index ok" << std::endl;
c.addTemporalFrame(7);
try{
ptr_time = c.rmTemporalFrameIndex(2);
assert(false);
}
catch(std::out_of_range & e)
{
assert(true);
}
std::pair<Competency,double> p1, p2, p3;
p1.first = comp1; p1.second = 0.5;
p2.first = comp2; p2.second = 0.3;
p3.first = comp3; p3.second = 0.7;
c.addTeachedComp(p1);
assert(c.teachedCompetenciesWeighted().size() == 1);
assert(c.teachedCompetenciesWeighted().at(0).first == comp1 );
std::cout << "Add new comp to teached ok" << std::endl;
c.addTeachedComp(p2); c.addTeachedComp(p3);
assert(c.teachedCompetenciesWeighted().size() == 3);
std::pair<Competency, double> * ptr_p;
ptr_p = c.rmTeachedComp(comp3);
assert(ptr_p != NULL);
assert(ptr_p->first == comp3);
assert(c.teachedCompetenciesWeighted().size() == 2);
std::cout << "RM teached comp ok" << std::endl;
assert(c == c);
std::cout << "Equality ok" << std::endl;
Course c2;
assert( !(c == c2) );
std::cout << "Not equal ok" << std::endl;
return EXIT_SUCCESS;
}
\ No newline at end of file
#include <eo>
#include <iostream>
#include <string>
#include <cassert>
#include <utility>
#include <vector>
#include "model/problem.h"
#include "model/course.h"
#include "model/competency.h"
#include "model/tools.h"
#include "model/exception/csdvpOverlapingBoundaryException.h"
int main(int argc, char* argv[])
{
CSDVP pb;
assert(pb.id() == 1);
assert(pb.seed() == -1);
assert(pb.cfg_quantityCompetencies() == -1);
std::cout << "CSDVP constructor OK" << std::endl;
assert(pb.checkConfig() == false);
std::cout << "OK! CSDVP shoukd not be config yet here" << std::endl;
CSDVP::generateProblem(pb, CSDVP::GenerationType::RANDOM, 7777);
assert(pb.seed() == 7777);
assert(pb.checkConfig() == false);
CSDVP::generateProblem(pb, CSDVP::GenerationType::RANDOM, -1);
assert(pb.seed() == -1);
assert(pb.checkConfig() == false);
std::cout << "generateProblem does not trigger generation if pb is not config" << std::endl;
pb.set_cfg_quantityCompetencies(50);
assert(pb.cfg_quantityCompetencies() == 50);
assert(pb.checkConfig() == false);
pb.set_cfg_quantityCourses(25);
assert(pb.cfg_quantityCourses() == 25);
assert(pb.checkConfig() == false);
pb.set_cfg_minimalTimeFrames(5);
assert(pb.cfg_minimalTimeFrame() == 5);
assert(pb.checkConfig() == false);
pb.set_cfg_maximalTimeFrames(10);
assert(pb.cfg_maximalTimeFrame() == 10);
assert(pb.checkConfig() == false);
pb.set_cfg_ectsMin(3);
assert(pb.cfg_ectsMin() == 3);
assert(pb.checkConfig() == false);
pb.set_cfg_ectsMax(5);
assert(pb.cfg_ectsMax() == 5);
assert(pb.checkConfig() == false);
pb.set_cfg_courseByTFMin(5);
assert(pb.cfg_courseByTFMin() == 5);
assert(pb.checkConfig() == false);
pb.set_cfg_courseByTFMax(8);
assert(pb.cfg_courseByTFMax() == 8);
assert(pb.checkConfig() == false);
pb.set_cfg_minimalMagnitude(0.2);
pb.set_cfg_maximalMagnitude(0.5);
assert(pb.cfg_magnitudeMin().value() == 0.2);
assert(pb.cfg_magnitudeMax().value() == 0.5);
assert(pb.checkConfig() == false );
std::cout << "Config ok -- excepting seed" << std::endl;
pb.set_cfg_courseByTFMin(9);
try
{
CSDVP::generateProblem(pb, CSDVP::GenerationType::RANDOM, 7777);
}
catch(CSDVPOverlapingBoundariesException & e)
{
std::cout << "Overlaping protection 1/2 OK" << std::endl;
}
pb.set_cfg_courseByTFMin(4);
pb.set_cfg_ectsMax(2);
try
{
CSDVP::generateProblem(pb, CSDVP::GenerationType::RANDOM, 7777);
}
catch(CSDVPOverlapingBoundariesException & e)
{
std::cout << "Overlaping protection 2/2 OK" << std::endl;
}
pb.set_cfg_ectsMax(5);
pb.addTimeFrame(2);
pb.addTimeFrame(5);
assert(pb.timeFrames().size() == 2);
pb.addTimeFrame(5);
assert(pb.timeFrames().size() == 2);
std::cout << "duplicata protection TF ok" << std::endl;
Course c = Course::build();
Course c2 = Course::build();
assert( ! (c == c2) );
pb.addCourseToCatalogue(c);
pb.addCourseToCatalogue(c2);
assert(pb.coursesCatalogue().size() == 2);
pb.addCourseToCatalogue(c);
assert(pb.coursesCatalogue().size() == 2);
std::cout << "duplicata protection for course ok" << std::endl;
Competency comp1 = Competency::build(0.5);
Competency comp2 = Competency::build(0.7);
assert(!(comp1 == comp2));
pb.addCompetencyToCatalogue(comp1);
pb.addCompetencyToCatalogue(comp2);
assert(pb.competencyCatalogue().size() == 2);
pb.addCompetencyToCatalogue(comp1);
assert(pb.competencyCatalogue().size() == 2);
std::cout << "duplicata protection for competency ok" << std::endl;
std::cout << pb << std::endl;
pb.set_cfg_minimalCompetencyByCourse(1);
pb.set_cfg_maximalCompetencyByCourse(5);
pb.set_cfg_minimalPrerequisiteByCourse(0);
pb.set_cfg_maximalPrerequisiteByCourse(2);
CSDVP::generateProblem(pb, CSDVP::GenerationType::RANDOM, 7777);
assert(pb.checkConfig());
std::cout << "CSDVP has been correctly configurated" << std::endl;
assert(pb.timeFrames().at(0) == pb.cfg_minimalTimeFrame());
assert(pb.timeFrames().at(1) == pb.cfg_minimalTimeFrame()+1);
assert(pb.timeFrames().at(pb.timeFrames().size()-1) == pb.cfg_maximalTimeFrame());
std::cout << "TimeFrames vector correctly init" << std::endl;
assert(pb.coursesCatalogue().size() > 0);
for(int i = 0; i < pb.coursesCatalogue().size(); i++)
assert(pb.coursesCatalogue().at(i).timeFrame().size() > 0);
std::cout << "Course catalogue randomized on TF OK." << std::endl;
std::cout << "Displaying size ("+std::to_string(pb.coursesCatalogue().size())+")/ 2 and -1 and +1 course" << std::endl;
std::cout << pb.coursesCatalogue().at(pb.coursesCatalogue().size()/2 - 1) << std::endl;
std::cout << pb.coursesCatalogue().at(pb.coursesCatalogue().size()/2) << std::endl;
std::cout << pb.coursesCatalogue().at(pb.coursesCatalogue().size()/2 + 1) << std::endl;
int counter;
std::cout << "Cheking Time Frames integrity..." << std::endl;
for(int i = 0; i < pb.timeFrames().size(); i++)
{
counter = 0;
for(int j = 0; j < pb.coursesCatalogue().size(); j++)
{
for(int k = 0; k < pb.coursesCatalogue().at(j).timeFrame().size(); k++)
{
if(pb.coursesCatalogue().at(j).timeFrame().at(k) == pb.timeFrames().at(i))
counter++;
assert(counter <= pb.cfg_courseByTFMax());
}
}
assert(counter >= pb.cfg_courseByTFMin());
}
std::cout << "TF Integrity is OK!" << std::endl;
assert(pb.competencyCatalogue().size() == pb.cfg_quantityCompetencies());
// for(int i = 0; i < pb.coursesCatalogue().size(); i++)
// {
// std::cout << pb.coursesCatalogue().at(i).name() << "\n\tPrereq: " + std::to_string(pb.coursesCatalogue().at(i).prerequisites().size()) << std::endl;
// if(pb.coursesCatalogue().at(i).prerequisites().size() > 0)
// std::cout << "Competency 0" << pb.coursesCatalogue().at(i).prerequisites().at(0) << std::endl;
// std::cout << "\n\tTeach: "+ std::to_string(pb.coursesCatalogue().at(i).teachedCompetenciesWeighted().size()) << std::endl;
// }
for(int i = 0; i < pb.competencyCatalogue().size() ; i++)
{
assert(pb.competencyCatalogue().at(i).c_magnitude().value() >= pb.cfg_magnitudeMin().value());
assert(pb.competencyCatalogue().at(i).c_magnitude().value() <= pb.cfg_magnitudeMax().value());
}
std::cout << "Magnitudes OK" << std::endl;
//CHECK QTE COMP IN RANGE OK
for(int i = 0 ; i < pb.coursesCatalogue().size(); i++)
{
assert(pb.coursesCatalogue().at(i).prerequisites().size() >= pb.cfg_prerequisiteByCourseMin());
assert(pb.coursesCatalogue().at(i).prerequisites().size() <= pb.cfg_prerequisiteByCourseMax());
assert(pb.coursesCatalogue().at(i).teachedCompetenciesWeighted().size() >= pb.cfg_competencyByCourseMin());
assert(pb.coursesCatalogue().at(i).teachedCompetenciesWeighted().size() <= pb.cfg_competencyByCourseMax());
}
std::cout << "Courses prerequistes ok!" << std::endl;
std::cout << "Courses teached comp ok!" << std::endl;
std::cout << "CSDVP HAS BEEN CORRECTLY GENERATED!" << std::endl;
return EXIT_SUCCESS;
}
\ No newline at end of file
#include <eo>
#include <iostream>
#include <string>
#include <cassert>
#include <utility>
#include <vector>
#include "model/profession.h"
#include "model/competency.h"
int main(int argc, char* argv[])
{
Competency c1 = Competency::build(0.5);
Competency c2 = Competency::build(0.7);
Competency c3 = Competency::build(0.21);
Profession p1;
Profession p2("NameTest");
std::vector<Competency> vC;
vC.push_back(c1); vC.push_back(c2);
Profession p3(vC);
assert(p1.prerequisites().size() == 0);
assert(p1.name().compare("Profession#1") == 0);
assert(p2.name().compare("NameTest") == 0);
assert(p3.prerequisites().size() == 2);
assert(p3.prerequisites().at(0) == c1);
std::cout << "Profession constructors OK" << std::endl;
p2.setPrerequisites(vC);
assert(p2.prerequisites().size() == 2);
assert(p2.prerequisites().at(0) == c1);
bool state;
state=p2.addPrerequisite(c3);
assert(state);
assert(p2.prerequisites().size() == 3);
assert(p2.prerequisites().at(2) == c3);
state=p2.addPrerequisite(c3);
assert(!state);
assert(p2.prerequisites().size() == 3);
assert(p2.prerequisites().at(2) == c3);
std::cout << p2 << std::endl;
std::cout << p3 << std::endl;
c3.evolveTowards(0.4);
std::cout << c3 << std::endl;
std::cout << p2.prerequisites().at(2) << std::endl;
p2.unlocked_prerequisites().at(2).evolveTowards(0.3);
std::cout << c3 << std::endl;
std::cout << p2.prerequisites().at(2) << std::endl;
return EXIT_SUCCESS;
}
\ No newline at end of file
......@@ -5,8 +5,48 @@
#include <queenCrossover.h>
#include <queenEval.h>
#include <model/magnitude.h>
#include <model/competency.h>
#include <model/exception/magnitudeException.h>
#include <model/exception/competencyEvolvingException.h>
int main(int argc, char* argv[]){
// ================================ TEST ZONE ===========================================
Magnitude m = Magnitude::build(0.5);
Magnitude n = Magnitude::build(0.3);
Magnitude o = Magnitude::build(0.2);
o = m;
std::cout << "Magnitude" << o.value() << std::endl;
std::cout << "Magnitude" << m.value() << std::endl;
m += n;
std::cout << "New magnitude is " << m.value() << std::endl;
try{
std::cout << "After addition mag is : " << (m + m).value() << std::endl;
}
catch(MagnitudeException & e)
{
std::cout << "\nEXCEPTION CATCH !\n";
std::cout << "Memory adr of m is : " << &m << std::endl;
std::cout << "Memory adr of e is : " << &e.getMagnitude() << std::endl;
e.getMagnitude().rebase();
std::cout << "REBASE! New magnitude value is" << e.getMagnitude().rebase() << std::endl;
std::cout << "Accessing magnitude value : " << e.getMagnitude().value() << std::endl;
std::cout << "magnitude value of M : " << m.value() << std::endl;
m = e.getMagnitude();
std::cout << "before end catch" << m.value() << std::endl;
}
std::cout << "Inspect m value:" << m.value() << std::endl;
// ================================= END TEST ZONE =====================================
//Define a QUEEN -> 1 line
QUEEN s1;
......
......@@ -7,4 +7,7 @@ SET (EXERCICE_SOURCES
queenEval.cpp
)
ADD_LIBRARY(lQueen STATIC ${EXERCICE_SOURCES})
\ No newline at end of file
ADD_LIBRARY(lQueen STATIC ${EXERCICE_SOURCES})
add_subdirectory(model)
\ No newline at end of file
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/model)
include_directories(${PARADISEO_INCLUDE_DIR})
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
SET (EXERCICE_SOURCES
magnitude.cpp
competency.cpp
course.cpp
profession.cpp
problem.cpp
)
ADD_LIBRARY(lModel STATIC ${EXERCICE_SOURCES})
add_subdirectory(exception)
add_subdirectory(scale)
\ No newline at end of file
#include <iostream>
#include "competency.h"
#include "magnitude.h"
#include "exception/magnitudeException.h"
#include "exception/competencyEvolvingException.h"
int Competency::COMPETENCY_COUNTER = 0;
// === FACTORY
Competency Competency::build(Magnitude & m, std::string name)
{
int id = Competency::assignID();
if(name.empty())
name = "Competency#"+std::to_string(id);
return Competency(id, m, name);
}
Competency Competency::build(double d = 0, std::string name)
{
int id = Competency::assignID();
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)
: _id(id), _m(m), _name(s)
{
}
// === STATIC
int Competency::assignID()
{
return ++Competency::COMPETENCY_COUNTER;
}
// === FUNCTION
void Competency::evolveTowards(Magnitude & m)
{
try
{
this->_m+= m;
}
catch(MagnitudeException & e)
{
e.getMagnitude().rebase();
this->_m = e.getMagnitude();
throw CompetencyEvolvingException(this);
}
}
void Competency::evolveTowards(double d)
{
try
{
this->_m += d;
}
catch(MagnitudeException & e)
{
e.getMagnitude().rebase();
this->_m = e.getMagnitude();
throw CompetencyEvolvingException(this);
}
}
const double Competency::competencyValue() const
{
return this->_m.value();
}
// === OPERATOR
std::ostream& operator<<(std::ostream& Stream, const Competency & c)
{
std::string s = "Competency\n\tid:"+std::to_string(c.id())+"\n\tname:"+c.c_name()+"\n\tvalue:"+std::to_string(c.competencyValue());
Stream << s ;
return Stream;
}
bool Competency::operator==(const Competency & c) const
{
return ( this->_id == c.id() || ( this->_name.compare(c.c_name()) == 0 ) );
}
\ No newline at end of file
#ifndef SRC_COMPETENCY_H_
#define SRC_COMPETENCY_H_
#include <string>
#include "magnitude.h"
/**
* Represents the notion of a competency (a.k.a. "non operationalisable" skill).
*
* A compentecy C always exists, at any moment, with a magnitude (or mastery) m in [0;1].
* @author alexis.lebis
* @version 1
*/
class Competency
{
private:
Magnitude _m;
std::string _name;
int _id;
//Constructor
Competency(int, Magnitude, std::string);
//STATIC
static int COMPETENCY_COUNTER;
static int assignID();
public:
static Competency build(Magnitude &, std::string s = "");
static Competency build(double, std::string = "");
Competency() = default;
// === FUNCTION
/** evolveTowards allows the competency to increase or decrease according to the value passed in parameter (either in Magnitude._value or double). It represents the competency evolving towards a specfic state, here represented by this->_m.value() + m.value().
* Use it instead of manipuling directly a Magnitude, since it'll handle MagnitudeException
*
* @throw CompetencyEvolvingException Exception containing this
*/
void evolveTowards(Magnitude & m);
/** evolveTowards allows the competency to increase or decrease according to the value passed in parameter (either in Magnitude._value or double). It represents the competency evolving towards a specfic state, here represented by this->_m.value() + d.
* Use it instead of manipuling directly a Magnitude, since it'll handle MagnitudeException
*
* @throw CompetencyEvolvingException Exception containing this
*/
void evolveTowards(double d);
// === GETTER
///Retrieves the magnitude/mastery value of the competency
const double competencyValue() const;
///Retrieves the magnitude of the compentecy
const Magnitude c_magnitude() const {return this->_m;}
Magnitude & magnitude(){return this->_m;}
///Retrieves the name of the competency
const std::string c_name() const {return this->_name;}
std::string & name() {return this->_name;}
const int id() const {return this->_id;}
// === SETTER
void setMagnitude(Magnitude & m){this->_m = m;}
void setName(std::string s){this->_name = s;}
// === OPERATOR
/// A competency is equal to another iff their id are the same, or their name
bool operator==(const Competency & c) const;
};
// === OPERATOR
std::ostream & operator<<(std::ostream& Stream, const Competency & c);
#endif // SRC_COMPETENCY_H_
\ No newline at end of file
#include <iostream>
#include <utility>
#include <algorithm>
#include <iterator>
#include <stdexcept>
#include "course.h"
#include "competency.h"
#include "tools.h"
#include "exception/courseECTSException.h"
#include "exception/courseTemporalFrameException.h"
#include "exception/notImplementedException.h"
int Course::COURSE_COUNTER = 0;
// === FACTORY
Course Course::build(int ects, std::string name)
{
int id = Course::assignID();
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
Course::Course(int id, int ects, std::string name)
: _id(id), _ects(ects), _name(name)
{}
// === END CONSTRUCTOR
// === GETTER
//cf. course.h
// === END GETTER
// === MUTATOR
// SETTER
void Course::setECTS(int ects)
{
this->_ects = ects;
if(this->_ects < 0)
throw CourseECTSException(this);
}
void Course::setName(std::string name)
{
if(name.empty())
name = "Course#"+std::to_string(this->_id);
this->_name = name;
}
void Course::setAvailabilities(std::vector<int> & times)
{this->_temporalAvailability = times;}
void Course::setPrerequisites(std::vector<Competency> & prereqs)
{this->_prerequisites = prereqs;}
void Course::setTeachedComps(std::vector<std::pair<Competency,double>> & wComps)
{this->_weightedTeached = wComps;}
// ADDER
bool Course::addTeachedComp(std::pair<Competency,double> & wComp)
{
if( _duplicataProtection(&(this->_weightedTeached), wComp.first))
return false;
this->_weightedTeached.push_back(wComp);
return true;
}
bool Course::addPrerequisite(Competency & prereq)
{
if( duplicataFlag((this->_prerequisites), prereq) )
return false;
this->_prerequisites.push_back(prereq);
return true;
}
bool Course::addTemporalFrame(int time)
{
if(time < 0)
throw CourseTemporalFrameException(this, time);
if( duplicataFlag((this->_temporalAvailability), time) )
return false;
this->_temporalAvailability.push_back(time);
return true;
}
// DELETER
Competency * Course::rmPrerequisite(Competency prereq)
{
std::vector<Competency>::iterator it =
std::find(
this->_prerequisites.begin(),
this->_prerequisites.end(),
prereq
);
if(it == this->_prerequisites.end())
return NULL;
int index = std::distance(this->_prerequisites.begin(), it);
Competency * c = &(this->_prerequisites.at(index));
this->_prerequisites.erase(this->_prerequisites.begin()+index);
return c;
}
std::pair<Competency,double> * Course::rmTeachedComp(Competency teached)
{
if(this->_weightedTeached.size()==0)
return NULL;
std::vector<std::pair<Competency, double>>::iterator it = this->_weightedTeached.begin();
int index = 0;
Competency current = this->_weightedTeached.at(index).first;
while(it != this->_weightedTeached.end() && !( this->_weightedTeached.at(index).first == teached) )
{
index=std::distance(this->_weightedTeached.begin(), it);
current = this->_weightedTeached.at(index).first;
it++;
}
if(it == this->_weightedTeached.end() && !( this->_weightedTeached.at(index).first == teached))
return NULL;
std::pair<Competency, double> * ptr_pair = &(this->_weightedTeached.at(index));
this->_weightedTeached.erase(this->_weightedTeached.begin()+index);
return ptr_pair;
}
int * Course::rmTemporalFrameIndex(int index)
{
int *ptr_time = & (this->_temporalAvailability.at(index)) ;
this->_temporalAvailability.erase(this->_temporalAvailability.begin()+index);
return ptr_time;
}
int * Course::rmTemporalFrameValue(int value)
{
std::vector<int>::iterator it =
std::find(
this->_temporalAvailability.begin(),
this->_temporalAvailability.end(),
value
);
if(it == this->_temporalAvailability.end())
return NULL;
int index = std::distance(this->_temporalAvailability.begin(), it);
int * ptr_time = &(this->_temporalAvailability.at(index));
this->_temporalAvailability.erase(this->_temporalAvailability.begin()+index);
return ptr_time;
}
// === END MUTATOR
// === FUNC
/// @deprecated
// bool Course::_duplicataProtection(std::vector<int> * timeFrame, int time)
// {
// std::vector<int>::iterator it = std::find( timeFrame->begin(), timeFrame->end(), time);
// return it != timeFrame->end();
// }
/// @deprecated
// bool Course::_duplicataProtection(std::vector<Competency> * prereq, Competency c)
// {
// std::vector<Competency>::iterator it = std::find( prereq->begin(), prereq->end(), c);
// return it != prereq->end();
// }
bool Course::_duplicataProtection(std::vector<std::pair<Competency,double>> *teached, Competency c)
{
if(teached->size() == 0)
return false;
std::vector<std::pair<Competency, double>>::iterator it = teached->begin();
int index = 0;
Competency current = teached->at(index).first;
while(it != teached->end() && !( teached->at(index).first == c) )
{
index=std::distance(teached->begin(), it);
current = teached->at(index).first;
it++;
}
return ( it != teached->end() && !( teached->at(index).first == c) );
}
// template<typename T>
// std::pair<int, T> Course::findInVector(const std::vector<T> & vec, const T & findMe)
// {
// std::pair<int, T> res;
// typename std::vector<T>::iterator it = std::find( vec.begin(), vec.end(), findMe);
// if(it == vec.end())
// {
// res.first = -1;
// res.second; //NTD, -1 SHOULD BE USED TO DETECT THAT NOTHING HAS BEEN FOUND
// }
// else
// {
// res.first = std::distance(vec.begin(), it);
// res.second = vec.at(res.first);
// }
// return res;
// }
bool Course::_lazyEquality(const Course & c) const
{
return (this->_id == c.id() &&
this->_name.compare(c.name()) == 0 &&
this->_ects == c.ects()
);
}
///@todo
bool Course::_fullEquality(const Course & c) const
{
throw NotImplementedException("Course::_fullEquality");
}
// === OPERATOR
std::ostream& operator<<(std::ostream& Stream, const Course & c)
{
std::string s = "Course\n\tid:"+std::to_string(c.id())+"\n\tname:"+c.name()+"\n\tECTS: "+std::to_string(c.ects());
std::string tf;
if(c.timeFrame().size() > 0)
{
for(int i = 0; i < c.timeFrame().size()-1; i++)
tf+=std::to_string(c.timeFrame().at(i))+" ; ";
tf+=std::to_string(c.timeFrame().at(c.timeFrame().size()-1));
s+="\n\tTimeFrames: ["+tf+"]";
}
Stream << s;
return Stream;
}
bool Course::operator==(const Course & c) const
{
return _lazyEquality(c);
}
// === END OPERATOR
// === STATIC
/// Course counter
int Course::assignID()
{
return ++Course::COURSE_COUNTER;
}
// === END STATIC
\ No newline at end of file
#ifndef SRC_COURSE_H_
#define SRC_COURSE_H_
#include <vector>
#include <utility>
#include "competency.h"
/**
* Represents a course in an academic structure.
*
* Based on a non exhaustive WiP standard from APACHES project. It includes several element of a french course teached in universities.
* This representation is subject to change.
*
* @author alexis.lebis
* @version 1
*/
class Course
{
private:
// === COMPETENCIES RELATED
std::vector<Competency> _prerequisites;
/** weightTeached represents how a compentency i is teached. This means that a competency i is transfered to a student with a weight w (a double). A course has a vector of competency, each one with a specific weight.
*/
std::vector<std::pair<Competency,double>> _weightedTeached;
// std::vector<Competency> teached;
// std::vector<double> diffusionWeight;
// === OTHER
/// European Credit Transfer and Accumulation System
int _ects;
/** Timeframe availablity of a course.
* @note For now, it discretiez time into semester
* @version 1.0
*/
std::vector<int> _temporalAvailability;
std::string _name;
int _id;
// === FUNC
/// _duplicataProtection returns true if the value (2nd param) searched into (1st param) is found
/// @deprecated
bool _duplicataProtection(std::vector<int> *, int);
/// @deprecated
bool _duplicataProtection(std::vector<Competency> *, Competency);
bool _duplicataProtection(std::vector<std::pair<Competency,double>> *, Competency);
/** Only check equality on id, etcs and name. It should be sufficient in the majority of case */
bool _lazyEquality (const Course & c) const;
/** Full check equality on id, ects, name, timeframes, prerequisites, compentencies*/
bool _fullEquality(const Course & c) const;
// Static
static int COURSE_COUNTER;
static int assignID();
// Constructor
//Course();
Course(int id, int ects, std::string name);
public:
static Course build(int ects = 0, std::string name = "");
/// Default constructor. Use Course::build instead !
Course() = default;
// === GETTER
const int id() const{return this->_id;};
const std::string name() const{return this->_name;};
const int ects() const{return this->_ects;}
const std::vector<Competency> prerequisites() const {return this->_prerequisites;}
const std::vector<int> timeFrame() const {return this->_temporalAvailability;}
const std::vector<std::pair<Competency, double>> teachedCompetenciesWeighted() const{return this->_weightedTeached;}
// === MUTATOR
// SETTER
void setECTS(int ects);
void setName(std::string);
void setAvailabilities(std::vector<int>&);
void setPrerequisites(std::vector<Competency>&);
void setTeachedComps(std::vector<std::pair<Competency,double>>&);
// ADDER
/**Returns true if the element has been inserted. Returns false if the insertion has not been performed to prevent a duplicata*/
bool addTeachedComp(std::pair<Competency,double> &);
bool addPrerequisite(Competency &);
bool addTemporalFrame(int);
// DELETER
/// rmPrerequisite return a pointer to the removed competency from the _prerequisite, or NULL if not found.
Competency * rmPrerequisite(Competency);
/// rmTeachedComp removes the given Competency. It returns a pointer to the std::pair<Competency,double> removed in _weightedTeached, or NULL.
std::pair<Competency,double> * rmTeachedComp(Competency);
/// rmTemporalFrame removes the temporal frame stored at the index. It returns the value or NULL;
int* rmTemporalFrameIndex(int index);
int* rmTemporalFrameValue(int value);
// === FUNC
void fixECTS();
/// _findInVector search the 2nd param inside a vector (1st param). It returns the a pair representing the index of the element, and the ptr of the element, or (-1;NULL) otherwise
// template<typename T>
// static std::pair<int, T> findInVector(const std::vector<T> &, const T &);
// === OPERATOR
/// A course is equal to another iff {(lazy_equality) || (full_equality)
bool operator==(const Course & c) const;
};
// === OPERATOR
std::ostream & operator<<(std::ostream& Stream, const Course & c);
#endif // SRC_COURSE_H_
\ No newline at end of file
// Use to define the decay politics in a CSDVP.
// Potentialy take a Competency & and evolve it towards
\ No newline at end of file
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/exception)
include_directories(${PARADISEO_INCLUDE_DIR})
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
#ifndef SRC_MODEL_EXCEPTION_COMPETENCY_EVOLVING_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_COMPETENCY_EVOLVING_EXCEPTION_H_
#include <exception>
#include <iostream>
#include <string>
#include "../competency.h"
class CompetencyEvolvingException : public std::exception
{
public:
CompetencyEvolvingException(Competency * c)
: _c(c)
{
this->_phrase = "Exception while evolving the competency. Magnitude value was OOB and has been auto-corrected.";
}
virtual const char* what() const throw()
{
return _phrase.c_str();
}
virtual ~CompetencyEvolvingException() throw()
{}
Competency & getCompetency() const {return *(this->_c);}
private:
Competency * _c;
std::string _phrase;
};
#endif // SRC_MODEL_EXCEPTION_COMPETENCY_EVOLVING_EXCEPTION_H_
\ No newline at end of file
#ifndef SRC_MODEL_EXCEPTION_COURSE_ECTS_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_COURSE_ECTS_EXCEPTION_H_
#include <exception>
#include <iostream>
#include <string>
#include "../course.h"
class CourseECTSException : public std::exception
{
private:
Course * _course;
std::string _phrase;
public:
CourseECTSException(Course * c) throw()
: _course(c)
{
this->_phrase = "Exception on ECTS: value ("+std::to_string(c->ects())+") uncorrect. Can it be negative?";
}
virtual const char* what() const throw()
{return _phrase.c_str();}
virtual ~CourseECTSException() throw()
{
//this->_course must not be free by ~this!
}
Course & getCourse() const{return *(this->_course);}
};
#endif // SRC_MODEL_EXCEPTION_COURSE_ECTS_EXCEPTION_H_
\ No newline at end of file
#ifndef SRC_MODEL_EXCEPTION_COURSE_TEMPORAL_FRAME_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_COURSE_TEMPORAL_FRAME_EXCEPTION_H_
#include <exception>
#include <iostream>
#include <string>
#include "../course.h"
class CourseTemporalFrameException : public std::exception
{
private:
Course * _course;
int _time;
std::string _phrase;
public:
CourseTemporalFrameException(Course * c, int time) throw()
: _course(c)
{
this->_phrase = "Exception on time frame: value ("+std::to_string(time)+") is uncorrect. Can it be negative?";
this->_time = time;
}
virtual const char* what() const throw()
{return _phrase.c_str();}
virtual ~CourseTemporalFrameException() throw()
{
//this->_course must not be free by ~this!
}
Course & getCourse() const{return *(this->_course);}
const int getTime() const{return this->_time;}
};
#endif // SRC_MODEL_EXCEPTION_COURSE_TEMPORAL_FRAME_EXCEPTION_H_
\ No newline at end of file
#ifndef SRC_MODEL_EXCEPTION_CSDVP_BADLY_CONFIG_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_CSDVP_BADLY_CONFIG_EXCEPTION_H_
#include <exception>
#include <string>
class CSDVPBadlyConfiguratedException : public std::exception
{
private:
std::string _msg;
public:
CSDVPBadlyConfiguratedException(std::string failedCondDescr) throw()
{
_msg = "The problem is badly configurated and thus, likely to 1) be overconstrained or 2) can't be generated.\nThe failed condition is: "+failedCondDescr;
}
virtual const char* what() const throw()
{
return _msg.c_str();
}
};
#endif //SRC_MODEL_EXCEPTION_CSDVP_BADLY_CONFIG_EXCEPTION_H_
\ No newline at end of file
#ifndef SRC_MODEL_EXCEPTION_CSDVP_OVERLAPING_BOUNDARIES_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_CSDVP_OVERLAPING_BOUNDARIES_EXCEPTION_H_
#include <exception>
#include <iostream>
#include <string>
#include "../problem.h"
class CSDVPOverlapingBoundariesException : public std::exception
{
private:
CSDVP * _csdvp;
std::string _msg;
public:
CSDVPOverlapingBoundariesException(CSDVP * pb) throw()
: _csdvp(pb)
{
this->_msg = "Boundaries of the CSDVP (id:"+std::to_string(pb->id())+") are overlaping.";
}
virtual const char* what() const throw()
{return this->_msg.c_str();}
CSDVP & getCSDVP() {return *(this->_csdvp);}
};
#endif // SRC_MODEL_EXCEPTION_CSDVP_OVERLAPING_BOUNDARIES_EXCEPTION_H_
\ No newline at end of file
#ifndef SRC_EXCEPTION_MAGNITUDE_EXCEPTION_H_
#define SRC_EXCEPTION_MAGNITUDE_EXCEPTION_H_
#include <exception>
#include <string>
#include <iostream>
#include "../magnitude.h"
class MagnitudeException : public std::exception
{
private:
Magnitude * _triedValue;
std::string _phrase;
public:
MagnitudeException(Magnitude * m) throw()
: _triedValue(m)
{
this->_phrase = "Magnitude Exception: value (" + std::to_string(m->value()) + ") is out of bound [0;1].";
}
virtual const char* what() const throw()
{
return _phrase.c_str();
}
virtual ~MagnitudeException() throw()
{
//this->_triedValue must not be freed by ~this !
}
Magnitude & getMagnitude() const {return *(this->_triedValue);}
};
#endif // SRC_EXCEPTION_MAGNITUDE_EXCEPTION_H_
\ No newline at end of file
#ifndef SRC_MODEL_EXCEPTION_NOT_IMPLEMENTED_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_NOT_IMPLEMENTED_EXCEPTION_H_
#include <exception>
#include <string>
class NotImplementedException : public std::exception
{
private:
std::string _msg;
public:
NotImplementedException(std::string funcName)
{
this->_msg = "Function "+funcName+" not yet implemented.";
}
virtual const char* what() const throw()
{
return this->_msg.c_str();
}
};
#endif // SRC_MODEL_EXCEPTION_NOT_IMPLEMENTED_EXCEPTION_H_
\ No newline at end of file
#include <iostream>
#include "magnitude.h"
#include "exception/magnitudeException.h"
// === FACTORY
Magnitude Magnitude::build(double value = 0)
{
bool isInRange = !(_inRange(value));
if( !isInRange )
{
//Magnitude mag(value);
throw MagnitudeException(new Magnitude(value));
}
else
return Magnitude(value);
}
// === CONSTRUCTOR
// Magnitude::Magnitude()
// {
// }
Magnitude::Magnitude(double d)
{
this->_value=d;
}
/* Magnitude::Magnitude(const Magnitude & m)
{
this->_value = m._value;
} */
// === OPERATOR
/**
* @throw MagnitudeException Throw a MagnitudeException if the new value is > 1 or < 0. Note that the this->_value IS set (thus you can use this->rebase() to put _value in good range)
*/
Magnitude & Magnitude::operator+=(const double d)
{
this->_value+=d;
if( Magnitude::_inRange(this->_value) )
{
Magnitude *mag = new Magnitude(*this);
throw MagnitudeException(mag);
}
return *this;
}
/**
* @throw MagnitudeException Throw a MagnitudeException if the new value is > 1 or < 0. Note that the this->_value IS set (thus you can use this->rebase() to put _value in good range)
*/
Magnitude & Magnitude::operator+=(const Magnitude & m)
{
this->_value += m._value;
if( Magnitude::_inRange(this->_value) )
{
Magnitude *mag = new Magnitude(*this);
throw MagnitudeException(mag);
}
return *this;
}
/**
* @throw MagnitudeException Throw a MagnitudeException if the new value is > 1 or < 0. You can catch the new magnitude causing the exception with magnitudeException.getMagnitude() (and thus perform the desired action, like a rebase)
*/
Magnitude operator+(const Magnitude & m, const Magnitude & n)
{
Magnitude mag(m);
mag+= n;
return mag;
}
/**
* @throw MagnitudeException Throw a MagnitudeException if the new value is > 1 or < 0. You can catch the new magnitude causing the exception with magnitudeException.getMagnitude() (and thus perform the desired action, like a rebase)
*/
Magnitude operator+(const Magnitude & m, const double d)
{
Magnitude mag(m);
mag += d;
return mag;
}
bool Magnitude::operator>(const Magnitude & m) const
{
return this->_value > m.value();
}
// === FUNCTION
/** Checks if the value v is in [0;1]. If yes, return 0. Else, if v < 0 return -1, 1 otherwise
*/
int Magnitude::_inRange(double v)
{
return v < 0 ? -1 : v > 1 ? 1 : 0;
}
double Magnitude::value() const {return this->_value;}
/** Set the magnitude value of a competency. Indicates whether or not there is an overflow in
* the given v value (and that it has been automatically corrected)
*/
bool Magnitude::set(double v)
{
int isInRange = _inRange(v);
switch (isInRange)
{
case -1:
this->_value = 0;
break;
case 1:
this->_value = 1;
break;
default:
this->_value = v;
break;
}
return !isInRange;
}
double Magnitude::rebase()
{
if(this->_value < 0)
{
this->_value = 0;
}
else if(this->_value > 1)
{
this->_value = 1;
}
return this->_value;
}
\ No newline at end of file
#ifndef SRC_MAGNITUDE_H_
#define SRC_MAGNITUDE_H_
/** Magnitude represents the mastery of a competency.
*
* It should be used in accordance with a scale
*/
class Magnitude
{
private:
double _value = 0;
//Constructor
Magnitude(double);
// function
static int _inRange(double);
public:
static Magnitude build(double); //factory
Magnitude() = default;
/* Magnitude(const Magnitude & m); */
double rebase(); /// if value is out of range, assign it the nearest value. Usefull when a MagnitudeException is caught
// Operator
Magnitude & operator+=(const Magnitude & m);
Magnitude & operator+=(double const d);
bool operator>(const Magnitude & m) const;
//GETTER
double value() const;
//SETTER
bool set(double v);
};
Magnitude operator+(const Magnitude & m1, const Magnitude & m2);
Magnitude operator+(const Magnitude & m1, double d);
#endif // SRC_MAGNITUDE_H_
\ No newline at end of file
#ifndef SRC_MODEL_PARCOURS_H_
#define SRC_MODEL_PARCOURS_H_
/**
* Represents a cursus of a student. It is equivalent to an individu in a EA.
*/
#endif // SRC_MODEL_PARCOURS_H_
\ No newline at end of file
This diff is collapsed.
#ifndef SRC_PROBLEM_H_
#define SRC_PROBLEM_H_
#include <vector>
#include "course.h"
#include "competency.h"
#include "magnitude.h"
/**
* Model of the CSDVP (Constraint Satisfaction Decaying Variables Problem).
*
* How many compentecies are available, how many courses, etc...
*/
class CSDVP
{
private:
int _id;
/// Seed used to generate the problem
int _seed;
/// Use to determine if CSDVP has been config by the user.
bool _isConfig;
// ----------- CONFIGURATION ATTRIBUTES ----------
// Config attributes are used to generate a problem instance. This way, two differents problems can be generated within the same definition space. Random is made by _seed.
int _quantityAvailableCompetencies;
int _quantityAvailableCourses;
int _minimalTimeFrame;
int _maximalTimeFrame;
/// ECTS values, defining the intervale [_minimal,_maximal] for random
int _minimalECTSValue;
int _maximalECTSValue;
int _minimalCoursesByTimeFrame;
int _maximalCoursesByTimeFrame;
int _minimalCompetencyByCourse;
int _maximalCompetencyByCourse;
int _minimalPrerequisiteByCourse;
int _maximalPrerequisiteByCourse;
Magnitude _minimalMagnitude;
Magnitude _maximalMagnitude;
// ---------- END CONFIGURATION ATTRIBUTES ----------
// ---------- PROBLEM SPECIFIC ATTRIBUTES ----------
// Theses attributes represent the CSDVP
std::vector<int> _timeFrames;
std::vector<Course> _availableCourses;
std::vector<Competency> _availableCompentecies;
///@todo implements a decay politics
//DecayPolitics
// --------- END PROBLEM SPECIFIC ATTRIBUTES ---------
// === STATIC
static int CSDVP_COUNTER;
static int assignID();
static const int RANDOM_MAX_ECTS_VALUE = 10;
static const int RANDOM_MAX_QTE_COMPETENCIES = 50;
static const int RANDOM_MAX_QTE_COURSES = 50;
static const int RANDOM_MAX_TIME_FRAMES = 15;
static const int RANDOM_MAX_COURSE_TIME_FRAMES = 10;
// --------- GENERATION RELATED FUNCTION ---------
static void _randomlyGenerated(CSDVP & pb);
static int _randomizeIn(const int min, const int max);
static double _randomizeIn(const double min, const double max);
// --------- END GENERATION RELATED FUNCTION ---------
public:
// --------- GENERATION RELATED FUNCTION ---------
/// allows a random attribution of pb's attributes
static void randomizeProblem(CSDVP & pb, int seed);
// --------- END GENERATION RELATED FUNCTION ---------
// === ENUM
enum GenerationType
{
RANDOM
//PRESET
};
// === CONSTRUCTOR
CSDVP();
/// Generate an instance of the CSDVP iff isConfig is true. Thus, seed != -1;
static void generateProblem(CSDVP & csdvp, CSDVP::GenerationType type, int seed= -1 );
// === GETTER
const int id() const{return this->_id;}
const int seed() const{return this->_seed;}
const int cfg_quantityCompetencies() const{return this->_quantityAvailableCompetencies;}
const int cfg_quantityCourses() const{return this->_quantityAvailableCourses;}
const int cfg_minimalTimeFrame() const{return this->_minimalTimeFrame;}
const int cfg_maximalTimeFrame() const{return this->_maximalTimeFrame;}
const int cfg_ectsMax() const{return this->_maximalECTSValue;}
const int cfg_ectsMin() const{return this->_minimalECTSValue;}
const int cfg_courseByTFMax() const{return this->_maximalCoursesByTimeFrame;}
const int cfg_courseByTFMin() const{return this->_minimalCoursesByTimeFrame;}
const int cfg_competencyByCourseMin() const {return this->_minimalCompetencyByCourse;}
const int cfg_competencyByCourseMax() const {return this->_maximalCompetencyByCourse;}
const int cfg_prerequisiteByCourseMin() const {return this->_minimalPrerequisiteByCourse;}
const int cfg_prerequisiteByCourseMax() const {return this->_maximalPrerequisiteByCourse;}
const Magnitude & cfg_magnitudeMin() const{return this->_minimalMagnitude;}
const Magnitude & cfg_magnitudeMax() const{return this->_maximalMagnitude;}
const std::vector<int> & timeFrames() const{return this->_timeFrames;}
const std::vector<Course> & coursesCatalogue() const{return this->_availableCourses;}
const std::vector<Competency> & competencyCatalogue() const{return this->_availableCompentecies;}
std::vector<int> & unlocked_timeFrames(){return this->_timeFrames;}
std::vector<Course> & unlocked_coursesCatalogue(){return this->_availableCourses;}
std::vector<Competency> & unlocked_competenciesCatalogue(){return this->_availableCompentecies;}
///@todo getDecayPolitic
// === MUTATOR
// SETTER
/*setSeed is deactivated. The only way to attribute a seed to CSDVP is by generateProblem.*/
//void setSeed(int s);
void set_cfg_quantityCompetencies(int nb);
void set_cfg_quantityCourses(int nb);
void set_cfg_minimalTimeFrames(int nb);
void set_cfg_maximalTimeFrames(int nb);
void set_cfg_ectsMin(int nb);
void set_cfg_ectsMax(int nb);
void set_cfg_courseByTFMax(int nb);
void set_cfg_courseByTFMin(int nb);
void set_cfg_minimalMagnitude(double mag);
void set_cfg_maximalMagnitude(double mag);
void set_cfg_minimalCompetencyByCourse(int nb);
void set_cfg_maximalCompetencyByCourse(int nb);
void set_cfg_minimalPrerequisiteByCourse(int nb);
void set_cfg_maximalPrerequisiteByCourse(int nb);
void setTimeFrames(std::vector<int> & v);
void setCoursesCatalogue(std::vector<Course> &);
void setCompetenciesCatalogue(std::vector<Competency> &);
// ADDER
//Any adder has a duplicata protection. Tend to favor addX instead of setX to prevent duplicata
/**Returns true if the element has been inserted. Returns false if the insertion has not been performed to prevent a duplicata*/
bool addTimeFrame(int t);
bool addCourseToCatalogue(Course & c);
bool addCompetencyToCatalogue(Competency & c);
// === FUNC
/// Checks all configuration attributes. If they have been all set, then isConfig is set to true
bool checkConfig();
};
std::ostream & operator<<(std::ostream & Stream, const CSDVP & c);
#endif // SRC_PROBLEM_H_
\ No newline at end of file
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include "profession.h"
#include "competency.h"
int Profession::PROFESSION_COUNTER = 0;
// === FACTORY
// No factory needed
// === END FACTORY
// === CONSTRUCTOR
Profession::Profession()
{
this->_id = assignID();
this->_name = "Profession#"+std::to_string(this->_id);
}
Profession::Profession(std::string name)
{
this->_id = assignID();
if(name.empty())
name = "Profession#"+std::to_string(this->_id);
this->_name = name;
}
Profession::Profession(std::vector<Competency> & p, std::string n)
: _prerequisites(p)
{
this->_id = assignID();
if(n.empty())
n = "Profession#"+std::to_string(this->_id);
this->_name = n;
}
// === END CONSTRUCTOR
// === MUTATOR
// SETTER
void Profession::setName(std::string name)
{
if(name.empty())
name = "Profession#"+std::to_string(this->_id);
this->_name = name;
}
std::vector<Competency> & Profession::setPrerequisites(std::vector<Competency> & p)
{
std::vector<Competency> * old = &this->_prerequisites;
this->_prerequisites = p;
return *old;
}
// ADDER
/** Adds a new competency to the prerequisites of a profession. It is protected against duplicata: it can't have twice the same competency.
*
* @return true if an insertion as been made into the prerequiste, false otherwise;
*
* Warning: does not use shallow copy. This can lead to a potential non constant behaviors if use with Profession(vector<Competency>) regarding the modification of compentecies outside this.
* @note Remove the referencing?
*/
bool Profession::addPrerequisite(Competency & c)
{
if(_duplicataProtection(& this->_prerequisites, c))
return false;
this->_prerequisites.push_back(c);
return true;
}
// === FUNC
/// _duplicataProtection returns true if the value (2nd param) searched into (1st param) is found
bool Profession::_duplicataProtection(std::vector<Competency> * prereq, Competency c)
{
std::vector<Competency>::iterator it = std::find( prereq->begin(), prereq->end(), c);
return it != prereq->end();
}
// === OPERATOR
std::ostream & operator<<(std::ostream & Stream, const Profession & p)
{
std::string s = "Profession\n\tid:"+std::to_string(p.id())+"\n\tname:"+p.name()+"\n\t#Prereq:"+std::to_string(p.prerequisites().size());
Stream << s;
return Stream;
}
// === STATIC
int Profession::assignID(){return ++Profession::PROFESSION_COUNTER;}
\ No newline at end of file
#ifndef SRC_PROFESSION_H_
#define SRC_PROFESSION_H_
#include <vector>
#include "competency.h"
/**
* A profession is a job sought by a student.
*
* It has a set a prerequisted competencies for the student to perform it correctly.
*/
class Profession
{
private:
std::vector<Competency> _prerequisites;
std::string _name;
int _id;
// === FUNC
/** _duplicataProtection returns true if the value (2nd param) searched into (1st param) is found*/
bool _duplicataProtection(std::vector<Competency> *, Competency);
// Static
static int PROFESSION_COUNTER;
static int assignID();
public:
Profession();
Profession(std::string name);
Profession(std::vector<Competency> & p, std::string n = "");
// === GETTER
const int id() const{return this->_id;}
const std::string name() const{return this->_name;}
const std::vector<Competency> & prerequisites() const{return this->_prerequisites;}
/// return a modifiable reference to _prerequisite;
std::vector<Competency> & unlocked_prerequisites(){return this->_prerequisites;}
// === MUTATOR
// SETTER
/// Set name of the profession. If name empty, creates a default name based on ID
void setName(std::string name);
/// Set the prerequisites of a profession. The old prereq is returned.
std::vector<Competency> & setPrerequisites(std::vector<Competency> & v);
// ADDER
bool addPrerequisite(Competency &);
};
// === OPERATOR
std::ostream & operator<<(std::ostream & Stream, const Profession & p);
#endif // SRC_PROFESSION_H_
\ No newline at end of file
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/scale)
include_directories(${PARADISEO_INCLUDE_DIR})
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
\ No newline at end of file
#ifndef SRC_SCALE_MAPI_H_
#define SRC_SCALE_MAPI_H_
#include "scale.h"
class MAPIScale : public Scale
{
private:
public:
};
#endif // SRC_SCALE_MAPI_H_
\ No newline at end of file
#ifndef SRC_SCALE_SCALE_H_
#define SRC_SCALE_SCALE_H_
#include "scaleValue.h"
/** Represent a competency scale used by academic to assert competency level of a student.
*
* Use a scale to discretize the magnitude
*/
class Scale
{
private:
public:
void getRange(ScaleValue &, double & inf, double & max);
};
#endif // SRC_SCALE_SCALE_H_
\ No newline at end of file
#ifndef SRC_SCALE_SCALE_VALUE_H_
#define SRC_SCALE_SCALE_VALUE_H_
#include <string>
/**
* Represent a range of competency magnitude for a scale
*/
class ScaleValue
{
private:
std::string name;
public:
ScaleValue();
};
#endif // SRC_SCALE_SCALE_VALUE_H_
\ No newline at end of file
#ifndef SRC_MODEL_TOOLS_H_
#define SRC_MODEL_TOOLS_H
#include <vector>
#include <utility>
#include <algorithm>
template<typename T>
/** Searches into vec the element findMe. The class T must have T() defined ( T()=default; is OK) */
static std::pair<int, T> findInVector(std::vector<T> & vec, T & findMe)
{
std::pair<int, T> res;
typename std::vector<T>::iterator it = std::find( vec.begin(), vec.end(), findMe);
if(it == vec.end())
{
res.first = -1;
res.second; //NTD, -1 SHOULD BE USED TO DETECT THAT NOTHING HAS BEEN FOUND
}
else
{
res.first = std::distance(vec.begin(), it);
res.second = vec.at(res.first);
}
return res;
}
template<typename T>
/** duplicataFlag returns true if the value (2nd param) searched into (1st param) is found */
static bool duplicataFlag(std::vector<T> & toProtect, T & toAdd)
{
std::pair<int, T> res = findInVector(toProtect, toAdd);
if(res.first < 0)
return false;
else
return true;
}
#endif // SRC_MODEL_TOOLS_H_
\ No newline at end of file
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