我有一个项目,可以创建一个计划并对其进行优化。该项目具有Schedule类:
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;
}
它有一个类,通过交换两个随机课程并决定处理优化,哪个时间表更好:
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;
}
ScheduleGeneratorClass尚未完全运作(它不会测试类冲突,即同一教授不能同时教授2个班级),但它会交换课程并计算日程安排的分数。问题是,在返回_schedule之前; part _schedule包含有效的时间表:
但是当调用者得到它时,该对象只保留得分部分。其他一切似乎都被抹去了:
过去几天我一直试图解决这个问题而且没有运气。 有人可以帮忙吗? 如果您需要其他代码或更多信息,请询问。 谢谢。
答案 0 :(得分:3)
在getSchedule
这些代码行中:
Schedule _changedSc = *_schedule;
Schedule *_changedSchedule = &_changedSc;
在堆栈上创建{strong>本地实例Schedule
,并指向该本地实例。
这行代码:
_schedule = _changedSchedule;
表示_schedule
现在指向该局部变量。
当您的方法返回时,局部变量超出范围,因此您的_schedule
指针现在无效。
向量大小变回零的原因可能是由于向量析构函数,但是没有什么能阻止程序将该内存重用于其他内容,如果您尝试使用向量,则会出现段错误。
解决此问题的一种方法是拥有一个更长久的地方来存储已更改的Schedule
,例如在课堂上。另一种方法是传入一个Schedule
对象来填充。另一种方法是将Schedule
作为对象而不是指针传回。
答案 1 :(得分:0)
使用new
运算符,您知道该对象不会在初始化范围内使用。例如:
Schedule *_changedSchedule = &_changedSc;
当_changedSc
超出范围时,它将不再在堆栈中。您需要能够使用new
运算符将其存储在堆中。