schedule_maker / rooster.h
rooster.h
Raw
#ifndef RoosterHVar  // voorkom dat dit bestand meerdere keren
#define RoosterHVar  // ge-include wordt

#include <vector>
#include "constantes.h"
#include "docent.h"
#include "vak.h"
#include "track.h"

class Rooster
{ public:

    // Default constructor
    Rooster ();

    // Lees een instantie in uit invoernaam.
    // Controleer daarbij of het bestand wel te openen is.
    // Pre:
    // * het aantal dagen, het aantal uren per dag, het aantal zalen,
    //   het aantal docenten, het aantal tijdsloten per docent,
    //   die tijdsloten zelf, het aantal vakken, de nummers van de docent
    //   van een vak, het aantal tracks en de tracks zelf die je inleest
    //   vallen binnen de gegeven grenzen (dat hoef je dus niet meer
    //   te controleren).
    // Retourneer:
    // * true, als het bestand te openen was.
    //   In dat geval is alle ingelezen informatie in het object opgeslagen.
    // * false, anders
    bool leesIn (const char* invoerNaam);

    // Druk de informatie van de instantie af op het scherm.
    void drukAf ();

    // Bepaal zo mogelijk een rooster voor de verschillende tracks,
    // rekening houdend met de beschikbaarheid van de docenten,
    // en de eisen aan de tracks.
    // Retourneer:
    // * true, als het lukt om een rooster te bepalen
    // * false, als het niet lukt om een rooster te bepalen
    // Post:
    // * als het lukt om een rooster te bepalen, bevat parameter `rooster'
    //   zo'n rooster. Dan geldt: rooster[s][z] =
    //   - het nummer van het vak dat op tijdslot s (in de week) en zaal z
    //     is ingeroosterd
    //   - -1 als er geen vak op tijdslot s en zaal z is ingeroosterd
    // * aantalDeelroosters is gelijk aan het aantal deelroosters dat we
    //   hebben gezien bij het bepalen van een rooster
    bool bepaalRooster (int rooster[MaxNrTijdsloten][MaxNrZalen],
                            long long &aantalDeelroosters);

    // Bepaal zo mogelijk een rooster voor de verschillende tracks,
    // rekening houdend met de beschikbaarheid van de docenten,
    // en de eisen aan de tracks. Als er een rooster te vinden is,
    // bepaal dan een zo kort mogelijk rooster (een rooster dat zo vroeg
    // mogelijk (qua tijdslot in de week) klaar is).
    // Retourneer:
    // * true, als het lukt om een rooster te bepalen
    // * false, als het niet lukt om een rooster te bepalen
    // Post:
    // * als het lukt om een rooster te bepalen, bevat parameter `rooster'
    //   een zo kort mogelijk rooster. Dan geldt: rooster[s][z] =
    //   - het nummer van het vak dat op tijdslot s (in de week) en zaal z
    //     is ingeroosterd
    //   - -1 als er geen vak op tijdslot s en zaal z is ingeroosterd
    // * aantalDeelroosters is gelijk aan het aantal deelroosters dat we
    //   hebben gezien bij het bepalen van een rooster
    bool bepaalMinRooster (int rooster[MaxNrTijdsloten][MaxNrZalen],
                            long long &aantalDeelroosters);

    // Druk parameter rooster overzichtelijk af op het scherm
    // (dag, tijd, zaal, naam van vak, nummer van docent).
    // Pre:
    // * er is al een instantie ingelezen, en parameter rooster
    //   bevat een rooster voor die instantie
    void drukAfRooster (int rooster[MaxNrTijdsloten][MaxNrZalen]);

    // Bepaal op een gretige manier een rooster voor de ingelezen vakken,
    // docenten en tracks. Als het niet lukt om aan alle eisen voor een
    // geldig rooster te voldoen, probeer er dan `zo goed mogelijk' aan
    // te voldoen.
    // Pre:
    // * het aantal vakken is <= het aantal combinaties (tijdslot,zaal),
    //   zodat daadwerkelijk alle vakken te geven zijn (los van onze andere,
    //   logische eisen aan een rooster)
    // Post:
    // * rooster bevat een rooster voor alle ingelezen vakken.
    void bepaalRoosterGretig (int rooster[MaxNrTijdsloten][MaxNrZalen]);

  private:
// Private Variabelen:
    vector<Docent> docenten; // vector met de docent objecten op volgorde van id
    vector<Vak> vakken; // vector met de vak objecten op volgorde van id
    vector<Track> tracks; // vector met de track objecten op volgorde van id
    int zaalSymmetrie[MaxNrTijdsloten][MaxNrVakken];
    bool tijdslotVol[MaxNrTijdsloten]; // Alle zalen op een tijdslot zijn ingeroosterd
    int nrDagen,       // aantal dagen in het rooster
        nrUrenPerDag,  // aantal uren per dag
        nrZalen,       // aantal beschikbare zalen
        nrDocenten,    // aantal docenten
        nrVakken,      // aantal vakken 
        nrTijdsloten,  // aantal tijdsloten 
        nrTracks;      // aantal tracks  

// Private Functies:
    // Reset de zaalSymmetrie array vanaf een bepaalde tijdslot
    void resetZaalSymmetrie(int vanafTijdslot);

    // Verwijdert de huidige opzet naar de beginstand voor een nieuwe opzet
    void verwijderOpzetRooster();

    // Simpele hulpfunctie die kijkt of er een integer in een integer vector zit
    bool integerInVector(vector<int> vector, int integer);

    // Maakt een nieuwe track en voegt deze toe aan de 
    // vector tracks, als deze track nog niet bestaat
    void addTrack(int const trackID, int const vakId);

    // Kijkt naar de theoretische mogelijkheid van alle tracks en slaat deze 
    // op in de boolean theoretischMogelijk in de objecten van de tracks
    void tracksTheoretischMogelijk();

    // Leest de waardes voor een rooster opzet in uit een geopende file
    void leesWaardesIn(ifstream& invoer);

    // Initialiseert de rooster array en reset de waardes van de 
    // rooster objecten, zodat er een nieuw rooster kan worden gemaakt
    void initialiseerRooster(int rooster[MaxNrTijdsloten][MaxNrZalen]);

    // Kijkt of alle vakken zijn ingeroosterd
    bool allesIngeroosterd();

    // Kijkt of een track al eerder op een dag les heeft en geeft het tijdslot
    // terug van het laatste moment dat de track les had
    int laatsteLesTrack(int trackid, int tijdslot);

    // Kijkt of een track later op de dag een les heeft en geeft het tijdslot
    // terug van het eerstvolgende moment dat de track les heeft
    int eerstvolgendeLes(int trackid, int tijdslot);

    // Kijkt of het goed gaat met de tussenuren van de tracks van
    // dit vak als deze zou worden ingeroosterd
    bool tracksGoedTussenuren(int vakid, int tijdslot);

    // Kijkt of een track les zou hebben als een vak met vakid wordt ingeroosterd
    bool heeftLes(int trackid, int vakid);

    // Controleert of er op een dag niet een track is met maar één les
    bool tracksGoedUren(int tijdslot);

    // Kijkt of elke track van dit vak niet al een andere vak op dit tijdslot heeft
    bool isVakBeschikbaar(Vak vak, int tijdslot);

    // Kijkt of dit vak op dit tijdslot les kan geven
    bool isCollegeMogelijk(Vak vak, int tijdslot);

    // Als nieuw true is dan wordt er gekeken of er nieuwe tussenuren zijn en als
    // nieuw false is dan wordt er gekeken of er tussenuren weggehaald moeten worden
    void setTussenuur(int tijdslot, int vakid, bool nieuw);

    // Rooster een vak in op dit tijdslot in een beschikbare zaal 
    // en kijkt en set ook naar de tussenuren als dit nodig is 
    int inroosteren(int vakid, int tijdslot, 
                    int rooster[MaxNrTijdsloten][MaxNrZalen], bool tussenuren);

    // Haalt een ingeroosterd vak weer uit het rooster en zet alle waardes weer terug
    void terugroosteren(int tijdslot, int rooster[MaxNrTijdsloten][MaxNrZalen], int zaal);

    // Retourneert het laatste ingeroosterde tijdslot
    int laatsteLesRooster(int rooster[MaxNrTijdsloten][MaxNrZalen]);

    // Bepaalt recursief met backtracking het rooster en retourneert het laatste
    // moment dat iets is ingerooster. Als het niet is gelukt dan wordt -1 
    // geretourneert. Als korste true is dan moet een minimaal
    // rooster gevonden worden en bij false maakt het niet uit
    bool bepaalRoosterBerekening(int rooster[MaxNrTijdsloten][MaxNrZalen],
                                 long long &aantalDeelroosters);


    bool tracksMinGoedUren(int tijdslot, int rooster[MaxNrTijdsloten][MaxNrZalen], 
                           vector<vector<int>> nieuweVakken);

    // Voegt een vector met vakid, tijdslot en zaal toe aan de vector resultaat
    void voegVakToe(vector<vector<int>> &resultaat, int vakid, int tijdslot, int zaal);

    // Bepaalt recursief met backtracking het rooster en retourneert het laatste
    // moment dat iets is ingerooster. Als het niet is gelukt dan wordt -1 
    // geretourneert. Als korste true is dan moet een minimaal
    // rooster gevonden worden en bij false maakt het niet uit
    int bepaalMinRoosterBerekening(int rooster[MaxNrTijdsloten][MaxNrZalen],
                                   long long &aantalDeelroosters, 
                                   vector<vector<int>> &nieuweVakken);

    // Geeft de slechtste rang van beschikbaarheid die het vak in zijn tracks heeft
    int vakBeschikbaarheid(Vak vak, int tijdslot);

    // Kijkt of dit vak aan de regels voldoet dat een track maar een vak op de dag
    // mag hebben en kijkt ook alvast of er een track is met een vak die kan op de
    // volgende twee tijdsloten. Een uitzondering is een theoretisch onmogelijke track
    bool vakVerbondenheid(int vakId, int tijdslot);

    // Hulpfunctie voor het gretige algoritme voor het inroosteren van het beste vak
    bool besteVakInroosteren(int tijdslot, int besteVakId, int beschikbaarheid);

    // Hulpfunctie voor het gretige algoritme voor het check
    // of een vak beter is dan beste vak
    void beterVak(int tijdslot, int vakId, int& besteVakId, 
                  int& beschikbaarheid);
};

#endif