I have a project which creates a schedule and makes an optimization to it. The project has the Schedule class:
Schedule.h:
#pragma once
#ifndef SCHEDULE_H
#define SCHEDULE_H
#include "Course.h"
#include "Prof.h"
#include "Room.h"
#include "TimeBlock.h"
#include "Weekdays.h"
#include "ScoreCalculator.h"
#include <map>
#include <vector>
/**
* This class represents a schedule for all courses.
*/
class Schedule {
public:
Schedule(std::vector < Room >, std::vector < Prof >, std::vector < Course > );
Schedule(const Schedule& schedule);
std::map < Room, std::vector < std::vector < Course > > > getSchedule();
bool setCourse(const Course&, const Room&, Weekdays, TimeBlock, int);
Course getCourse(const Room&, Weekdays, TimeBlock);
std::vector < Course > getCoursesAt(Weekdays, TimeBlock);
std::vector < Weekdays > getWeekdaysFor(const Course&);
TimeBlock getTimeFor(const Course&);
Room getRoomFor(const Course&);
void swapCourses(Room, Weekdays, TimeBlock, Room, Weekdays, TimeBlock);
void setScore (double score){ _score = score; }
double getScore() { return _score; }
Prof getProf(string);
Prof getProf(Course);
std::vector<Course> getCoursesTaughtBy(Prof&);
std::vector<Course> getCoursesOnGivenDayTaughtBy(Prof&, Weekdays);
std::vector<Room> getRooms();
std::map<string, Prof> getProfs();
void setSchedule(std::map < Room, std::vector < std::vector <Course> > >);
private:
std::map < Room, std::vector < std::vector < Course > > > _schedule;
std::map < std::string, Prof > _professors;
std::map < std::string, Course > _courses;
std::vector<Room> _rooms;
std::vector<Prof> _profs;
std::vector<Course> _coursesVector;
double _score;
};
#endif // SCHEDULE_H
Schedule.cpp:
#include "../include/Schedule.h"
#include "../include/Prof.h"
#include <vector>
#include <set>
#include <string>
using namespace std;
/**
* Constructor for the schedule. Creates the empty schedule
*/
Schedule::Schedule(vector < Room > rooms, vector < Prof > prof, vector < Course > courses){
_rooms = rooms;
_profs = prof;
_coursesVector = courses;
for(unsigned int i = 0; i < prof.size(); i++){
_professors.insert(make_pair(prof.at(i).getId(), prof.at(i)));
}
for (unsigned int i = 0; i < courses.size(); i++){
_courses.insert(make_pair(courses.at(i).getId(), courses.at(i)));
}
_score = -1;
for (unsigned int i = 0; i < _rooms.size(); i++){
vector < vector < Course > > dayVector;
dayVector.resize(WEEKDAYS_SIZE);
for (unsigned int j = 0; j < dayVector.size(); j++){
dayVector.at(j).resize(TIMEBLOCK_SIZE);
}
_schedule.insert(make_pair(_rooms.at(i), dayVector));
}
}
bool Schedule::setCourse(const Course& course, const Room& room, Weekdays firstMeeting, TimeBlock timeBlock, int numberOfMeetings){
if (course.getEnrolled() > room.getCapacity()){
return false;
}
_schedule.at(room).at(firstMeeting).at(timeBlock) = course;
switch (numberOfMeetings){
case 2:
_schedule.at(room).at((TimeBlock)(firstMeeting + 2)).at(timeBlock) = course;
break;
}
return true;
}
Course Schedule::getCourse(const Room& room, Weekdays day, TimeBlock timeBlock){
//returns course
}
vector < Course > Schedule::getCoursesAt(Weekdays day, TimeBlock timeBlock){
//returns course at the given time
}
TimeBlock Schedule::getTimeFor(const Course& course){
//returns time for the course
}
Room Schedule::getRoomFor(const Course& course){
//returns room for the course
}
vector < Weekdays > Schedule::getWeekdaysFor(const Course& course){
//returns weekdays for the course
}
// returns true if swap was successful, false otherwise
void Schedule::swapCourses(Room room1, Weekdays weekdays1, TimeBlock timeBlock1, Room room2, Weekdays weekdays2, TimeBlock timeBlock2){
Course c1, c2;
c1 = getCourse(room1, weekdays1, timeBlock1);
c2 = getCourse(room2, weekdays2, timeBlock2);
setCourse(c2, room1, weekdays1, timeBlock1, 2);
setCourse(c1, room2, weekdays2, timeBlock2, 2);
}
Prof Schedule::getProf(string id){
return _professors.at(id);
}
Prof Schedule::getProf(Course c){
return _professors.at(c.getProfId());
}
void Schedule::setSchedule(map < Room, vector < vector < Course > > > schedule){
_schedule = schedule;
}
map < Room, vector < vector < Course > > > Schedule::getSchedule(){
return _schedule;
}
vector<Room> Schedule::getRooms(){
return _rooms;
}
map <string, Prof> Schedule::getProfs(){
return _professors;
}
vector <Course> Schedule::getCoursesTaughtBy(Prof& prof){
//returns courses taught by
}
Schedule& Schedule::operator=(const Schedule& rhs){
_rooms = rhs._rooms;
_courses = rhs._courses;
_coursesVector = rhs._coursesVector;
_professors = rhs._professors;
_profs = rhs._profs;
_schedule = rhs._schedule;
return *this;
}
It has a class which handles the optimization by swapping two random courses and deciding, which schedule is better:
GeneticScheduleGenerator.h:
#pragma once
#ifndef GENETICSCHEDULEGENERATOR_H
#define GENETICSCHEDULEGENERATOR_H
#include "ScheduleGenerator.h"
#include "ScoreCalculator.h"
#include "Schedule.h"
#include <map>
#include <string>
using namespace std;
class GeneticScheduleGenerator : public ScheduleGenerator {
public:
GeneticScheduleGenerator(ScoreCalculator&, Schedule*, long);
Schedule* getSchedule(void);
Schedule* _schedule;
map < Room, vector < vector < Course > > > getScheduleMap();
private:
double calculateScore(map < string, Prof >, Schedule*);
void optimize ();
std::map<string, ProfInfo> profInfoMap;
ScoreCalculator& _sc;
map<string, double> _scores;
map<Room, vector< vector< Course> > > _scheduleMap;
};
#endif // GENETICSCHEDULEGENERATOR_H
GeneticScheduleGenerator.cpp:
#include "../include/GeneticScheduleGenerator.h"
#include <cstdlib>
#include <time.h>
#include <algorithm>
#include "../include/Weekdays.h"
#include "../include/TimeBlock.h"
#include <iostream>
GeneticScheduleGenerator::GeneticScheduleGenerator(ScoreCalculator& sc, Schedule* schedule, long timeout )
: ScheduleGenerator(timeout) , _sc(sc) {
_schedule = schedule;
}
double GeneticScheduleGenerator::calculateScore(map<string, Prof> professors, Schedule* schedule){
double score = 0;
//does some calculations
return score;
}
Schedule* GeneticScheduleGenerator::getSchedule(){
Schedule* bestSchedule = _schedule;
Schedule _changedSc = *_schedule;
Schedule *_changedSchedule = &_changedSc;
map<string, Prof> professors = bestSchedule->getProfs();
bestSchedule->setScore(calculateScore(professors, bestSchedule));
srand(time(NULL));
vector<Room> rooms = _schedule->getRooms();
int numberOfRooms = rooms.size();
Room room1, room2;
Weekdays day1, day2;
TimeBlock time1, time2;
long endTime = time(0) + getTimeout();
int counter = 0;
do{
counter++;
room1 = rooms.at(rand() % numberOfRooms);
room2 = rooms.at(rand() % numberOfRooms);
day1 = (Weekdays)(rand() % WED);
day2 = (Weekdays)(rand() % WED);
time1 = (TimeBlock)(rand() % TIMEBLOCK_SIZE);
time2 = (TimeBlock)(rand() % TIMEBLOCK_SIZE);
if (_changedSchedule->getCourse(room1, day1, time1).getEnrolled() > room2.getCapacity() ||
_changedSchedule->getCourse(room2, day2, time2).getEnrolled() > room1.getCapacity() ||
_changedSchedule->getCourse(room2, day2, time2) == _changedSchedule->getCourse(room1, day1, time1))
{
continue;
}
else
{
bestSchedule = _schedule;
_changedSchedule->swapCourses(room1, day1, time1, room2, day2, time2);
double newScore = calculateScore(professors, _changedSchedule);
if (bestSchedule->getScore() > newScore){
_schedule = _changedSchedule;
_schedule->setScore(newScore);
}
}
} while (time(0) < endTime);
std::cout << "counter: " << counter << endl;
_scheduleMap = _schedule->getSchedule();
/*map<string, Prof> tempProf = _schedule->getProfs();
map<string, Course> tempCorse = _schedule->getCourses();*/
return _schedule;
}
map < Room, vector < vector < Course > > > GeneticScheduleGenerator::getScheduleMap(){
return _scheduleMap;
}
The ScheduleGeneratorClass is not yet fully functioning(it does not test for class conflicts, i.e. same professor can't teach 2 classes at the same time), but it swaps classes and calculates the score for the schedule. The problem is, that before the return _schedule; part _schedule contains the valid schedule:
But when the caller gets it, the object holds only the score part. Everything else seems to be erased:
I have been trying to solve that for last couple of days and had no luck.
Can anyone help?
If you need the other code or more info, just ask.
Thank you.