Compare commits

..

6 commits
main ... anri

Author SHA1 Message Date
43517e33ec
refactor 2023-10-22 01:48:19 +02:00
6d3861b718
really iterate over the whole list 2023-10-22 01:46:26 +02:00
60c6686ff6
fix unique id, << overload, add some methods 2023-10-21 18:31:34 +02:00
0a11b3c4d3
explicit constructor init 2023-10-21 16:21:25 +02:00
a964d703fc
state of task 2023-10-21 15:50:27 +02:00
477f73d4c4
Add unique_id for tasks 2023-10-21 15:47:15 +02:00
22 changed files with 56 additions and 861 deletions

View file

@ -9,11 +9,6 @@ OBJETS = $(patsubst %.cpp,%.cpp.o,$(notdir $(SOURCES)))
EXE = tp5 EXE = tp5
EXE_EXT = out EXE_EXT = out
PDF_LOCATION = report
PDF_FILE = explications.pdf
ARCHIVE = $(EXE).tar
%.cpp.o: src/%.cpp %.cpp.o: src/%.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS) $(DEVFLAGS) $(CXX) -c -o $@ $< $(CXXFLAGS) $(DEVFLAGS)
@ -30,19 +25,10 @@ compilation: $(OBJETS)
all: all:
main main
pdf-make: clean:
cd report && \ $(RM) $(OBJETS) $(EXE).$(EXE_EXT)
$(MAKE)
pdf-clean: archive:
cd report && \ $(TAR) "$(EXE).tar" $(SOURCES) $(wildcard includes/*.hpp) Makefile \
$(MAKE) clean binome.txt
# diagramme_uml.* explications.pdf
clean: pdf-clean
-$(RM) $(OBJETS) "$(EXE).$(EXE_EXT)" "$(ARCHIVE)"
archive: pdf-make
cp "$(PDF_LOCATION)/$(PDF_FILE)" .
$(TAR) "$(ARCHIVE)" $(SOURCES) $(wildcard includes/*.hpp) Makefile \
binome.txt "$(PDF_FILE)" diagramme_uml.png
$(RM) "$(PDF_FILE)"

108
TODO.md
View file

@ -2,107 +2,7 @@
TODO avant rendu : TODO avant rendu :
- [x] Page rédigée montrant que l'on a tenu compte des problématiques de copies et sécurité (private/public) en expliquant en français non technique comment vous les avez traitées (`x` à pas accès à `y`) - [ ] "Vous remettrez en plus de votre code une page rédigée montrant que vous
- [x] Écrire des tests pour montrer que ça fonctionne avez tenu compte de certaines problématiques de copies/sécurité etc en
expliquant en français non technique comment vous les avez traitées"
## Notes - [ ] Écrire un "écrirez un petit jeu de test, clair"
- [x] Toute classe doit être surchargée avec `<<`
- [x] Gestion satisfaisante des copies, affectation, destruction
### Projet
- [x] Ne dois **pas** être instanciée directement
- [x] Se décompose en tâches (vecteur de tâches)
- [x] Durée totale dépend du degré de parallélisme que le gestionnaire décide
- [x] Deux natures de projets dépendantent de `Projet`
- En cours d'élaboration (`ProtoProjet`)
- En cours d'exécution (`RunProjet`)
- [x] Peut être vu comme un graphe acyclique (utilisation de `vector`) des tâches
- Les sommets sont des tâches
- Une tâche `fin` servira de source au graphe
- Garder un ordre topologique (triée par dépendances)
- [x] Mère des deux classes `ProtoProjet` et `RunProjet`
- [x] Méthodes utiles qu'à ses sous-classes
- Méthodes (cf. le PDF du prof)
- [x] `pick_two_random_tasks()`
- [x] `contains()`
- [x] Surcharge de `<<` : afficher toutes les tâches
- [x] `consult_tasks()`
- [x] `topologicalSort()`
#### ProtoProjet
- Permet de pouvoir ajouter de nouvelles tâches
- Ne peut pas progresser (a.k.a ne peut pas lancer les tâches)
- Champs
- [x] Tâche `début`
- [x] Tâche `fin`
- Méthodes (cf. le PDF du prof) **⇒ Tout ça avec l'ordre topologique**
- Pas de méthode d'ajout d'un objet `Tache`
- [x] `bool ajoute(nom, durée)` : sélectionne au hasard 2 tâches déjà
enregistrer et **ajoute** la nouvelle tâche entres-elles
- [x] `bool ajoute(nom, durée, id)` : **ajoute** une tâche qui doit se réaliser
**après** la tâche qui à l'`id` correspondant (et avant la tâche finale)
- [x] `bool ajoute(nom, durée, id1, id2)` : **ajoute** une tâche entre les 2 tâches
qui ont l'identifiant `id1` et `id2`
- [x] Surcharge de `<<`
#### RunProjet
- [x] Construit uniquement via un `ProtoProjet`
- [x] Avance vers sa conclusion en prenant en compte des tâches ponctuelles
- [x] Vide le contenu d'un `ProtoProjet` pour se construire, rendre les tâches "read-only"
- Méthodes (cf. le PDF du prof)
- [x] `run(id)` : Lance une tâche
- [x] `run(sequence_taches)` : Exécute une liste de tâches dans l'ordre donnée
- [x] Surcharge de `<<`
### Concepteur
L'utilisateur final en somme
- [x] Interagis avec un `ProtoProjet` pour y mettre des tâches
### Gestionnaire
- [x] Étudie/Analyse des `RunProjet`
- [x] Recommande des ordonnancements pour la suite des exécutions à venir
(ordre d'exécutions des tâches)
- [x] Calcule la durée totale restante d'un projet
- [x] Demande un salaire pour travailler
- Méthodes
- [x] Surcharge de `<<` : Affiche une facturation
- [x] `pair<vector<int>, int> avis(const RunProjet &)` : renvoie l'ordonnancement
et la durée totale restante
#### Consultant
- [x] Calcule **sans** parallélisation des tâches
#### Expert
- [x] Calcule **avec** parallélisation des tâches
### Tâches
- [x] Dépendantes, entre-elles
- [x] Durée exacte, fixe, propre à elle-même
- [x] Ne peut être lancé que si toutes les dépendances sont réalisées
- [x] Dépendances = autres tâches
- [x] Élément atomique (final)
- Champs
- [x] Nom
- [x] Numéro unique
- [x] État (réalisée/en attente)
- Réalisée → En attente : **interdit**
- En attente → Réalisée : **autorisé**
- [x] Vision locale des dépendances (`vector`)
- Méthodes (cf. le PDF du prof)
- [x] `bool realise()`
- [x] `bool depends_from(Tache & x)`
- [x] `bool ajouteDependance(Tache & x)`
- [x] `int dureeParal()`
- [x] Surcharge de `<<`

View file

@ -1,70 +0,0 @@
<!-- https://mermaid.live -->
```mermaid
%%{init: {'theme': 'neutral'}}%%
classDiagram
%% Classes
class Tache {
-static_counter_id
-nom
-duree_total
-etat
-dependances
+unique_id
+visite
+realise()
+depends_from(tache)
+ajouteDependance(tache)
+dureeParal()
+PP_postfixe(liste_tache)
}
class Projet {
#tache_fin
#tache_debut
#taches
-cleanMarks()*
#pick_two_random_tasks()
#contains(id ou name)
#topologicalSort()
+consult_tasks()
}
class ProtoProjet {
-cleanMarks()
+ajoute(nom, duree)
+ajoute(nom, duree, id)
+ajoute(nom, duree, id1, id2)
}
class RunProjet {
+run(id ou liste_tache)
}
class Gestionnaire {
-salaire
+payer(argent)
+avis(RunProjet)*
}
class Consultant {
+avis(RunProjet)
}
class Expert {
+avis(RunProjet)
}
%% Héritage
Projet <|-- ProtoProjet
ProtoProjet <|-- RunProjet
Gestionnaire <|-- Consultant
Gestionnaire <|-- Expert
%% Friends (Dependency)
%% pour : consult_tasks()
Projet ..> Consultant
Projet ..> Expert
%% Composition
Tache --* Projet
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,9 +1,9 @@
#ifndef TP5_CONSULTANT_HPP #ifndef TP5_CONSULTANT_HPP
#define TP5_CONSULTANT_HPP 1 #define TP5_CONSULTANT_HPP 1
#include "Gestionnaire.hpp" #include <iostream>
class Consultant final : public Gestionnaire { class Consultant {
friend std::ostream &operator<<(std::ostream &, const Consultant &); friend std::ostream &operator<<(std::ostream &, const Consultant &);
public: public:
@ -12,8 +12,6 @@ public:
Consultant(const Consultant &); // copy constructor Consultant(const Consultant &); // copy constructor
const Consultant &operator=(const Consultant &); // copy assignement const Consultant &operator=(const Consultant &); // copy assignement
std::pair<std::vector<int>, int> avis(const RunProjet &projet) const;
}; };
#endif #endif

View file

@ -1,9 +1,9 @@
#ifndef TP5_EXPERT_HPP #ifndef TP5_EXPERT_HPP
#define TP5_EXPERT_HPP 1 #define TP5_EXPERT_HPP 1
#include "Gestionnaire.hpp" #include <iostream>
class Expert final : public Gestionnaire { class Expert {
friend std::ostream &operator<<(std::ostream &, const Expert &); friend std::ostream &operator<<(std::ostream &, const Expert &);
public: public:
@ -12,8 +12,6 @@ public:
Expert(const Expert &); // copy constructor Expert(const Expert &); // copy constructor
const Expert &operator=(const Expert &); // copy assignement const Expert &operator=(const Expert &); // copy assignement
std::pair<std::vector<int>, int> avis(const RunProjet &projet) const;
}; };
#endif #endif

View file

@ -1,37 +1,17 @@
#ifndef TP5_GESTIONNAIRE_HPP #ifndef TP5_GESTIONNAIRE_HPP
#define TP5_GESTIONNAIRE_HPP 1 #define TP5_GESTIONNAIRE_HPP 1
#include "RunProjet.hpp" #include <iostream>
class Gestionnaire { class Gestionnaire {
int salaire_attendu;
int salaire_recu;
// Renvoie le reste à payer pour donner une expertise
int reste_a_payer() const;
friend std::ostream &operator<<(std::ostream &, const Gestionnaire &); friend std::ostream &operator<<(std::ostream &, const Gestionnaire &);
protected:
// Auxiliaire pour simplifier l'affichage d'un projet
std::ostream &print(std::ostream &) const;
// Vrai si Gestionnaire à été payé.e
bool payer() const;
public: public:
Gestionnaire(); // constructor Gestionnaire(); // constructor
virtual ~Gestionnaire(); // destructor virtual ~Gestionnaire(); // destructor
Gestionnaire(const Gestionnaire &); // copy constructor Gestionnaire(const Gestionnaire &); // copy constructor
const Gestionnaire &operator=(const Gestionnaire &); // copy assignement const Gestionnaire &operator=(const Gestionnaire &); // copy assignement
// Paye Gestionnaire, renvoie le montant restant à payer
int payer(const int argent);
// Renvoie l'ordonnancement et la durée totale restante
// Renvoie une liste vide et une durée totale -1 si pas payé.e
virtual std::pair<std::vector<int>, int> avis(const RunProjet &) const = 0;
}; };
#endif #endif

View file

@ -1,58 +1,17 @@
#ifndef TP5_PROJET_HPP #ifndef TP5_PROJET_HPP
#define TP5_PROJET_HPP 1 #define TP5_PROJET_HPP 1
#include "Tache.hpp" #include <iostream>
#include <algorithm>
struct RunProjet;
class Projet { class Projet {
// Auxilliaire pour simplifier les copies
void _copy(const Projet &);
// Auxiliiaire pour simplifier la libération de mémoire des tâches
void free_taches();
// Remet tous les marquages à leur valeur initiale
virtual void cleanMarks() const = 0;
friend std::ostream &operator<<(std::ostream &, const Projet &); friend std::ostream &operator<<(std::ostream &, const Projet &);
friend RunProjet;
protected:
Tache
// Source du graphe aka la dernière à être exécutée
*fin,
// Première tâche qui sera exécutée
*debut;
public:
Projet(); // constructor Projet(); // constructor
virtual ~Projet(); // destructor virtual ~Projet(); // destructor
Projet(const Projet &); // copy constructor Projet(const Projet &); // copy constructor
const Projet &operator=(const Projet &); // copy assignement const Projet &operator=(const Projet &); // copy assignement
// Graphe acyclique
std::vector<Tache *> taches;
// Auxiliaire pour simplifier l'affichage d'un projet
std::ostream &print(std::ostream &) const;
// Retourne une paire d'indentifiants de tâches au hasard
const std::pair<const int, const int> pick_two_random_tasks() const;
// Indique pour une tâche si elle fait partie du projet
Tache *contains(const int id) const;
Tache *contains(const std::string name) const;
// Corrige les éventuelles anomalies du vector de tâches
void topologicalSort();
public:
// Donne une version du vecteur de tâches non modifiable
const std::vector<const Tache *> consult_tasks() const;
}; };
#endif #endif

View file

@ -4,8 +4,6 @@
#include "Projet.hpp" #include "Projet.hpp"
class ProtoProjet : public Projet { class ProtoProjet : public Projet {
void cleanMarks() const;
friend std::ostream &operator<<(std::ostream &, const ProtoProjet &); friend std::ostream &operator<<(std::ostream &, const ProtoProjet &);
public: public:
@ -14,18 +12,6 @@ public:
ProtoProjet(const ProtoProjet &); // copy constructor ProtoProjet(const ProtoProjet &); // copy constructor
const ProtoProjet &operator=(const ProtoProjet &); // copy assignement const ProtoProjet &operator=(const ProtoProjet &); // copy assignement
// Insère une nouvelle tâche en la plaçant entre deux tâches au hasard
bool ajoute(const std::string nom, const int duree);
// Insère une nouvelle tâche en la plaçant après la tâche avec l'ID
// renseignée et avant la tâche finale, en créant une dépendance
bool ajoute(const std::string nom, const int duree, const int id);
// Insère une nouvelle tâche en la plaçant entre les deux tâches renseignée
// via ID
bool ajoute(const std::string nom, const int duree, const int id1,
const int id2);
}; };
#endif #endif

View file

@ -3,29 +3,15 @@
#include "ProtoProjet.hpp" #include "ProtoProjet.hpp"
struct Consultant; class RunProjet : public ProtoProjet {
struct Expert;
class RunProjet final : protected ProtoProjet {
friend std::ostream &operator<<(std::ostream &, const RunProjet &); friend std::ostream &operator<<(std::ostream &, const RunProjet &);
// Ami pour pouvoir consulter les tâches
friend Consultant;
friend Expert;
public: public:
RunProjet() = delete; // remove default constructor RunProjet(); // constructor
RunProjet(ProtoProjet &); // constructor
virtual ~RunProjet(); // destructor virtual ~RunProjet(); // destructor
RunProjet(const RunProjet &); // copy constructor RunProjet(const RunProjet &); // copy constructor
const RunProjet &operator=(const RunProjet &); // copy assignement const RunProjet &operator=(const RunProjet &); // copy assignement
// Lance une tâche
bool run(const int id) const;
// Exécute une liste de tâches dans l'ordre donnée
void run(const std::vector<const Tache *> sequence_taches) const;
}; };
#endif #endif

View file

@ -4,7 +4,7 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
class Tache final { class Tache {
// Compteur global pour les IDs // Compteur global pour les IDs
static int counter_id; static int counter_id;
@ -12,8 +12,9 @@ class Tache final {
enum Etat { EnAttente, Realisee }; enum Etat { EnAttente, Realisee };
friend std::ostream &operator<<(std::ostream &, const Etat &); friend std::ostream &operator<<(std::ostream &, const Etat &);
// Nom de la tâche // ID unique de la tâche
std::string name; const int unique_id;
// Durée totale pour faire la tâche // Durée totale pour faire la tâche
int duree_total; int duree_total;
// Etat actuelle de la tâche // Etat actuelle de la tâche
@ -27,12 +28,7 @@ class Tache final {
void _copy(const Tache &); void _copy(const Tache &);
public: public:
// ID unique de la tâche Tache(const int); // constructor
const int unique_id;
// Vrai si la tâche à été visitée par le parcours en profondeur
bool visite;
Tache(const std::string, const int); // constructor
virtual ~Tache(); // destructor virtual ~Tache(); // destructor
Tache(const Tache &); // copy constructor Tache(const Tache &); // copy constructor
@ -49,15 +45,6 @@ public:
// Calcule la durée totale max de réalisation d'une tâche et des dépendances // Calcule la durée totale max de réalisation d'une tâche et des dépendances
int dureeParal() const; int dureeParal() const;
// Parcours en profondeur
void PP_postfixe(std::vector<Tache *> &);
// Récupère la durée totale
int get_duree_totale() const;
// Récupère le nom
std::string get_name() const;
}; };
#endif #endif

5
report/.gitignore vendored
View file

@ -1,5 +0,0 @@
*
!.gitignore
!Makefile
!*.tex

View file

@ -1,16 +0,0 @@
NAME = explications
TEX = $(NAME).tex
SRC = $(TEX)
PDF = $(TEX:.tex=.pdf)
TEXMK = latexmk -shell-escape -lualatex
all: $(PDF)
$(PDF): %.pdf: %.tex
$(TEXMK) $<
EXTS = aux fdb_latexmk fls log nav out snm synctex.gz toc
clean:
rm -rf $(PDF) _minted-$(NAME)/ $(foreach ext,$(EXTS),$(NAME).$(ext))

View file

@ -1,49 +0,0 @@
\documentclass{article}
\usepackage[T1]{fontenc} % encoding
\renewcommand{\familydefault}{\sfdefault} % sans-serif font
\usepackage[french]{babel} % langages
\frenchsetup{SmallCapsFigTabCaptions=false}
\usepackage[hidelinks]{hyperref} % clickable links in table of contents
\usepackage{graphicx} % images
\newcommand{\emma}{Emma Botti}
\newcommand{\anri}{Anri Kennel}
\newcommand{\pp}{\texttt{ProtoProjet}}
\newcommand{\rp}{\texttt{RunProjet}}
\title{Explications TP5}
\author{\emma\thanks{\emma : 00000000} et \anri\thanks{\anri : 22302653} \\
Langages à objet avancés $\cdot$ Université Paris Cité}
\date{Année universitaire 2023-2024}
\begin{document}
\maketitle
\tableofcontents
\clearpage
\section{Explications}
\subsection{Problématique de copies}
La liste des tâches est créée lors du \pp, et vider de la mémoire
lorsque \rp~disparaît. Lors du passage des tâches entre \pp~et \rp, il n'y a pas de copie.
\subsection{Problématique de sécurité}
Les variables sont toutes encapsulées dans des classes qui leur correspondent.
Les variables, quand elles n'ont pas à être exposé, sont soit cachés,
soit immuable.
\section{Diagramme UML}
\begin{figure}[h]
\centering
\includegraphics[width=1.3\textwidth]{../diagramme_uml.png}
\caption{Diagramme UML}
\end{figure}
\end{document}

View file

@ -1,10 +1,10 @@
#include "../includes/Consultant.hpp" #include "../includes/Consultant.hpp"
Consultant::Consultant() {} Consultant::Consultant() { std::cout << "Hello, Consultant!\n"; }
Consultant::~Consultant() {} Consultant::~Consultant() {}
Consultant::Consultant(const Consultant &) : Gestionnaire() {} Consultant::Consultant(const Consultant &) {}
const Consultant &Consultant::operator=(const Consultant &src) { const Consultant &Consultant::operator=(const Consultant &src) {
if (this == &src) { if (this == &src) {
@ -13,27 +13,3 @@ const Consultant &Consultant::operator=(const Consultant &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const Consultant &data) {
return data.print(out);
}
std::pair<std::vector<int>, int>
Consultant::avis(const RunProjet &projet) const {
std::vector<int> ordonnancement;
if (!payer()) {
return std::make_pair(ordonnancement, -1);
}
const std::vector<const Tache *> taches = projet.consult_tasks();
int duree_totale = 0;
for (const Tache *it : taches) {
duree_totale += it->get_duree_totale();
}
for (const Tache *it : taches) {
ordonnancement.push_back(it->unique_id);
}
return std::make_pair(ordonnancement, duree_totale);
}

View file

@ -1,10 +1,10 @@
#include "../includes/Expert.hpp" #include "../includes/Expert.hpp"
Expert::Expert() {} Expert::Expert() { std::cout << "Hello, Expert!\n"; }
Expert::~Expert() {} Expert::~Expert() {}
Expert::Expert(const Expert &) : Gestionnaire() {} Expert::Expert(const Expert &) {}
const Expert &Expert::operator=(const Expert &src) { const Expert &Expert::operator=(const Expert &src) {
if (this == &src) { if (this == &src) {
@ -13,23 +13,3 @@ const Expert &Expert::operator=(const Expert &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const Expert &data) {
return data.print(out);
}
std::pair<std::vector<int>, int> Expert::avis(const RunProjet &projet) const {
std::vector<int> ordonnancement;
if (!payer()) {
return std::make_pair(ordonnancement, -1);
}
const std::vector<const Tache *> taches = projet.consult_tasks();
const int duree_totale = taches.front()->dureeParal();
for (const Tache *it : taches) {
ordonnancement.push_back(it->unique_id);
}
return std::make_pair(ordonnancement, duree_totale);
}

View file

@ -1,59 +1,15 @@
#include "../includes/Gestionnaire.hpp" #include "../includes/Gestionnaire.hpp"
Gestionnaire::Gestionnaire() { Gestionnaire::Gestionnaire() { std::cout << "Hello, Gestionnaire!\n"; }
salaire_attendu = rand() % 500 + 400; // Entre 400 et 899
salaire_recu = 0;
}
Gestionnaire::~Gestionnaire() {} Gestionnaire::~Gestionnaire() {}
Gestionnaire::Gestionnaire(const Gestionnaire &src) Gestionnaire::Gestionnaire(const Gestionnaire &) {}
: salaire_attendu(src.salaire_attendu), salaire_recu(0) {}
const Gestionnaire &Gestionnaire::operator=(const Gestionnaire &src) { const Gestionnaire &Gestionnaire::operator=(const Gestionnaire &src) {
if (this == &src) { if (this == &src) {
return *this; return *this;
} }
salaire_attendu = src.salaire_attendu;
salaire_recu = src.salaire_recu;
return *this; return *this;
} }
std::ostream &Gestionnaire::print(std::ostream &out) const {
out << "La facture s'élève à " << salaire_attendu << "€, il reste "
<< reste_a_payer() << "€ à payer";
return out;
}
std::ostream &operator<<(std::ostream &out, const Gestionnaire &data) {
return data.print(out);
}
int Gestionnaire::reste_a_payer() const {
return salaire_attendu - salaire_recu;
}
bool Gestionnaire::payer() const {
bool return_val = salaire_recu >= salaire_attendu;
if (!return_val) {
std::cerr << "Je n'ai pas été payé. " << *this << ".\n";
}
return return_val;
}
int Gestionnaire::payer(const int argent) {
if (reste_a_payer() <= 0) {
return 0;
}
salaire_recu += argent;
if (reste_a_payer() <= 0) {
return 0;
}
return reste_a_payer();
}

View file

@ -1,117 +1,15 @@
#include "../includes/Projet.hpp" #include "../includes/Projet.hpp"
Projet::Projet() : fin(new Tache("Fin", 0)), debut(new Tache("Début", 0)) { Projet::Projet() { std::cout << "Hello, project!\n"; }
fin->ajouteDependance(*debut);
taches.push_back(fin); Projet::~Projet() {}
taches.push_back(debut);
}
Projet::~Projet() { free_taches(); } Projet::Projet(const Projet &) {}
void Projet::_copy(const Projet &src) {
// Copie des tâches
taches.reserve(src.taches.size());
for (Tache *t : src.taches) {
taches.push_back(t);
}
}
void Projet::free_taches() { taches.clear(); }
Projet::Projet(const Projet &src) : fin(src.fin), debut(src.debut) {
_copy(src);
}
const Projet &Projet::operator=(const Projet &src) { const Projet &Projet::operator=(const Projet &src) {
if (this == &src) { if (this == &src) {
return *this; return *this;
} }
fin = src.fin;
debut = src.debut;
free_taches();
_copy(src);
return *this; return *this;
} }
std::ostream &Projet::print(std::ostream &out) const {
// Liste vide
if (taches.empty()) {
out << "[]";
return out;
}
out << "[\n";
for (Tache *t : taches) {
out << " " << *t << ",\n";
}
out << ']';
return out;
}
std::ostream &operator<<(std::ostream &out, const Projet &data) {
return data.print(out);
}
const std::pair<const int, const int> Projet::pick_two_random_tasks() const {
// Choix aléatoire d'une tâche
size_t size = this->taches.size();
size_t rand1 = static_cast<size_t>(rand()) % size;
size_t rand2 = static_cast<size_t>(rand()) % size;
Tache *tache1 = this->taches[rand1];
Tache *tache2 = this->taches[rand2];
// tache2 ne doit pas dépendre transitivement de tache1
if (tache2->depends_from(*tache1)) {
return pick_two_random_tasks();
}
int id1 = tache1->unique_id;
int id2 = tache2->unique_id;
return std::make_pair(id1, id2);
}
Tache *Projet::contains(const int id) const {
for (Tache *t : this->taches) {
if (id == t->unique_id) {
return t;
}
}
return nullptr;
}
Tache *Projet::contains(const std::string name) const {
for (Tache *t : this->taches) {
if (name == t->get_name()) {
return t;
}
}
return nullptr;
}
const std::vector<const Tache *> Projet::consult_tasks() const {
return std::vector<const Tache *>(taches.begin(), taches.end());
}
void Projet::topologicalSort() {
// Construction de la pile
std::vector<Tache *> pile;
for (Tache *it : taches) {
if (!it->visite) {
it->PP_postfixe(pile);
}
}
// Nettoyage des marques
cleanMarks();
// Reverse de la pile
std::reverse(pile.begin(), pile.end());
// Modifie la liste des tâches topologiquement triée
taches = pile;
}

View file

@ -1,10 +1,10 @@
#include "../includes/ProtoProjet.hpp" #include "../includes/ProtoProjet.hpp"
ProtoProjet::ProtoProjet() {} ProtoProjet::ProtoProjet() { std::cout << "Hello, protoProject!\n"; }
ProtoProjet::~ProtoProjet() {} ProtoProjet::~ProtoProjet() {}
ProtoProjet::ProtoProjet(const ProtoProjet &src) : Projet(src) {} ProtoProjet::ProtoProjet(const ProtoProjet &) : Projet() {}
const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) { const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) {
if (this == &src) { if (this == &src) {
@ -13,50 +13,3 @@ const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const ProtoProjet &data) {
return data.print(out);
}
void ProtoProjet::cleanMarks() const {
for (auto t : taches) {
t->visite = false;
}
};
bool ProtoProjet::ajoute(const std::string nom, const int duree) {
// Sélection de 2 tâches au hasard
auto tasks = pick_two_random_tasks();
// Ajout des tâches
return ajoute(nom, duree, tasks.first, tasks.second);
}
bool ProtoProjet::ajoute(const std::string nom, const int duree, const int id) {
// Ajout de la tâche entre l'ID voulu et la tâche finale
return ajoute(nom, duree, id, fin->unique_id);
}
bool ProtoProjet::ajoute(const std::string nom, const int duree, const int id1,
const int id2) {
Tache *tache1 = contains(id1);
Tache *tache2 = contains(id2);
// Vérifie que les tâches avec les id1 et id2 existent bien dans la liste
if (!tache1 || !tache2) {
return false;
}
// Création des dépendances
Tache *tache = new Tache(nom, duree);
if (!tache1->ajouteDependance(*tache) && !tache->ajouteDependance(*tache2)) {
// Problème de dépendance
delete tache;
return false;
}
// Mise à jour du vecteur avec tri topologique
taches.push_back(tache);
topologicalSort();
return true;
}

View file

@ -1,15 +1,10 @@
#include "../includes/RunProjet.hpp" #include "../includes/RunProjet.hpp"
RunProjet::RunProjet(ProtoProjet &src) : ProtoProjet(src) { src.free_taches(); } RunProjet::RunProjet() { std::cout << "Hello, runProject!\n"; }
RunProjet::~RunProjet() { RunProjet::~RunProjet() {}
// Ici on veut supprimes les tâches
for (Tache *it : taches) {
delete it;
}
}
RunProjet::RunProjet(const RunProjet &src) : ProtoProjet(src) {} RunProjet::RunProjet(const RunProjet &) : ProtoProjet() {}
const RunProjet &RunProjet::operator=(const RunProjet &src) { const RunProjet &RunProjet::operator=(const RunProjet &src) {
if (this == &src) { if (this == &src) {
@ -18,24 +13,3 @@ const RunProjet &RunProjet::operator=(const RunProjet &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const RunProjet &data) {
return data.print(out);
}
bool RunProjet::run(const int id) const {
Tache *tache = contains(id);
// La tâche n'existe pas
if (!tache) {
return false;
}
// Renvoie si la tâche s'est réalisée
return tache->realise();
}
void RunProjet::run(const std::vector<const Tache *> sequence_taches) const {
for (const Tache *it : sequence_taches) {
run(it->unique_id);
}
}

View file

@ -2,10 +2,9 @@
int Tache::counter_id = 0; int Tache::counter_id = 0;
Tache::Tache(const std::string n, const int duree) Tache::Tache(const int duree)
: name(n), duree_total(duree), etat(EnAttente), : unique_id(++counter_id), duree_total(duree), etat(EnAttente),
dependances(std::vector<Tache *>()), unique_id(counter_id++), dependances(std::vector<Tache *>()) {}
visite(false) {}
Tache::~Tache() {} Tache::~Tache() {}
@ -18,8 +17,7 @@ void Tache::_copy(const Tache &src) {
} }
Tache::Tache(const Tache &src) Tache::Tache(const Tache &src)
: name(src.name), duree_total(src.duree_total), etat(src.etat), : unique_id(++counter_id), duree_total(src.duree_total), etat(src.etat) {
unique_id(counter_id++), visite(src.visite) {
_copy(src); _copy(src);
} }
@ -27,10 +25,8 @@ const Tache &Tache::operator=(const Tache &src) {
if (this == &src) { if (this == &src) {
return *this; return *this;
} }
name = src.name;
duree_total = src.duree_total; duree_total = src.duree_total;
etat = src.etat; etat = src.etat;
visite = src.visite;
_copy(src); _copy(src);
return *this; return *this;
} }
@ -38,7 +34,7 @@ const Tache &Tache::operator=(const Tache &src) {
std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) { std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) {
switch (data) { switch (data) {
case Tache::EnAttente: case Tache::EnAttente:
out << "Attend"; out << "En Attente";
break; break;
case Tache::Realisee: case Tache::Realisee:
@ -49,8 +45,8 @@ std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) {
} }
std::ostream &operator<<(std::ostream &out, const Tache &data) { std::ostream &operator<<(std::ostream &out, const Tache &data) {
out << "Tâche(#" << data.unique_id << ", \"" << data.name << "\", " out << "Tâche #" << data.unique_id << " " << data.etat << " avec "
<< data.etat << ")\t=> " << data.dependances.size() << " dépendances"; << data.dependances.size() << " dépendances";
return out; return out;
} }
@ -63,11 +59,9 @@ bool Tache::realise() {
} }
} }
// TODO: Faire une vérification si le temps est écoulée ? // TODO: Ca veux dire quoi déclencher une tâche ?
// Dans ce cas là faut stocker le temps d'exécution actuelle de la tâche ?
etat = Realisee; etat = Realisee;
return true; return false;
} }
bool Tache::depends_from(const Tache &x) const { bool Tache::depends_from(const Tache &x) const {
@ -88,7 +82,7 @@ bool Tache::depends_from(const Tache &x) const {
bool Tache::ajouteDependance(Tache &x) { bool Tache::ajouteDependance(Tache &x) {
// On ne créer pas de dépendances cyclique aka 2 tâches // On ne créer pas de dépendances cyclique aka 2 tâches
// qui dépendent l'une de l'autre // qui dépendent l'une de l'autre
if (x.depends_from(*this)) { if (depends_from(x)) {
return false; return false;
} }
@ -115,19 +109,3 @@ int Tache::dureeParal() const {
// On ajoute la valeur max à notre durée totale // On ajoute la valeur max à notre durée totale
return ret_value + max_duree; return ret_value + max_duree;
} }
void Tache::PP_postfixe(std::vector<Tache *> &pile) {
visite = true;
for (Tache *it : dependances) {
if (!it->visite) {
it->PP_postfixe(pile);
}
}
// Moment post-fix du parcours
pile.push_back(this);
}
int Tache::get_duree_totale() const { return duree_total; }
std::string Tache::get_name() const { return name; }

View file

@ -1,161 +1 @@
#include "../includes/Consultant.hpp" int main(int argc, char const *argv[]) { return 0; }
#include "../includes/Expert.hpp"
using namespace std;
// Fait des tests pour vérifier/montrer que ça fonctionne
void test();
// Transforme un vecteur<int> en string
std::string vecint_tostring(std::vector<int> list);
int main() {
/* test();
return EXIT_SUCCESS; */
ProtoProjet pp;
pp.ajoute("a", 10); // probablement numero 2
cout << pp; // avec ses 3 taches
cout << "\n----------" << endl;
pp.ajoute("b", 15, 0, 1); // en supposant que 0: fin et 1: début
cout << pp;
cout << "\n----------" << endl;
RunProjet rp{pp};
cout << "----- verification : ProtoProjet vide " << endl;
cout << pp << endl;
Consultant c;
c.payer(1000);
cout << c.avis(rp).second << endl; // dira 25
Expert e;
e.payer(1000);
cout << e.avis(rp).second << endl; // dira 15
return EXIT_SUCCESS;
}
void test() {
/********************************** Projet **********************************/
// Projet p; // impossible car classe abstraite
/******************************* ProtoProjet *******************************/
ProtoProjet pp;
cout << "pp: " << pp << "\n";
/* pp: [
* Tâche(#0, "Fin", Attend) => 1 dépendances,
* Tâche(#1, "Début", Attend) => 0 dépendances,
* ] */
pp.ajoute("a", 10); // ajoute une dépendance à #1 le "début"
pp.ajoute("b", 15, 0, 1); // ajoute une dépendance à #0 (id1)
cout << "pp: " << pp << "\n";
/* pp: [
* Tâche(#0, "Fin", Attend) => 2 dépendances,
* Tâche(#3, "b", Attend) => 0 dépendances,
* Tâche(#1, "Début", Attend) => 1 dépendances,
* Tâche(#2, "a", Attend) => 0 dépendances,
* ]
*
* => L'ordre pour les dépendances est respecté */
/******************************** RunProjet ********************************/
// RunProjet rp; // impossible car le constructeur vide n'existe pas
RunProjet rp(pp);
cout << "pp: " << pp << "\n";
/* pp: []
*
* => La liste est bien vidée*/
cout << "rp: " << rp << "\n";
/* rp: [
* Tâche(#0, "Fin", Attend) => 2 dépendances,
* Tâche(#3, "b", Attend) => 0 dépendances,
* Tâche(#1, "Début", Attend) => 1 dépendances,
* Tâche(#2, "a", Attend) => 0 dépendances,
* ]
*
* => Les mêmes tâches ont étés transférés à RunProjet (pas de copie vérifiés
* par les ID identiques) */
/******************************** Consultant *******************************/
Consultant c;
cout << "c: " << c << "\n";
/* c: La facture s'élève à 693€, il reste 693€ à payer
*
* => Affiche la facture */
auto avis = c.avis(rp);
cout << "c(avis): (" << vecint_tostring(avis.first) << ", " << avis.second
<< ")\n";
/* Je n'ai pas été payé. La facture s'élève à 693€, il reste 693€ à payer.
* c(avis): ([], -1)
*
* => Iel ne donne pas d'avis car pas payé. */
cout << "c(payer 1000): " << c.payer(1000) << "\n";
/* c(payer 1000): 0
*
* On donne 1000 pour être sûr qu'iel soit content
* Il renvoie 0 car iel a plus besoin d'être payé */
auto avis2 = c.avis(rp);
cout << "c(avis): (" << vecint_tostring(avis2.first) << ", " << avis2.second
<< ")\n";
/* c(avis): ([0, 3, 1, 2], 25)
*
* => Iel donne la liste d'exécution
* et le temps d'exécution sans parallélisation */
/********************************** Expert *********************************/
Expert e;
cout << "e: " << e << "\n";
/* e: La facture s'élève à x€, il reste x€ à payer
*
* => Affiche la facture */
auto avis3 = e.avis(rp);
cout << "e(avis): (" << vecint_tostring(avis3.first) << ", " << avis3.second
<< ")\n";
/* Je n'ai pas été payé. La facture s'élève à y€, il reste y€ à payer.
* e(avis): ([], -1)
*
* => Iel ne donne pas d'avis car pas payé. */
cout << "e(payer 1000): " << e.payer(1000) << "\n";
/* e(payer 1000): 0
*
* On donne 1000 pour être sûr qu'iel soit content
* Il renvoie 0 car iel a plus besoin d'être payé */
auto avis4 = e.avis(rp);
cout << "e(avis): (" << vecint_tostring(avis4.first) << ", " << avis4.second
<< ")\n";
/* e(avis): ([0, 3, 1, 2], 15)
*
* => Iel donne la liste d'exécution
* et le temps d'exécution avec parallélisation */
/* A la fin, la mémoire est correctement libérée, testé via Valgrind-3.21.0 :
* HEAP SUMMARY:
* in use at exit: 0 bytes in 0 blocks
* total heap usage: 33 allocs, 33 frees, 75,550 bytes allocated
* All heap blocks were freed -- no leaks are possible
* ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) */
}
std::string vecint_tostring(std::vector<int> list) {
std::string return_value = "[";
if (list.empty()) {
return return_value + "]";
}
for (auto it : list) {
return_value += std::to_string(it) + ", ";
}
// \b\b pour retirer la dernière virgule
return return_value + "\b\b]";
}