172 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
| /*
 | |
|  * Scheduler.h
 | |
|  * @brief an example how inference can be used for scheduling qualifiers
 | |
|  * @date Mar 26, 2011
 | |
|  * @author Frank Dellaert
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <gtsam_unstable/discrete/CSP.h>
 | |
| 
 | |
| namespace gtsam {
 | |
| 
 | |
| 	/**
 | |
| 	 * Scheduler class
 | |
| 	 * Creates one variable for each student, and three variables for each
 | |
| 	 * of the student's areas, for a total of 4*nrStudents variables.
 | |
| 	 * The "student" variable will determine when the student takes the qual.
 | |
| 	 * The "area" variables determine which faculty are on his/her committee.
 | |
| 	 */
 | |
| 	class Scheduler : public CSP {
 | |
| 
 | |
| 	private:
 | |
| 
 | |
| 		/** Internal data structure for students */
 | |
| 		struct Student {
 | |
| 			std::string name_;
 | |
| 			DiscreteKey key_; // key for student
 | |
| 			std::vector<DiscreteKey> keys_; // key for areas
 | |
| 			std::vector<std::string> areaName_;
 | |
| 			std::vector<double> advisor_;
 | |
| 			Student(size_t nrFaculty, size_t advisorIndex) :
 | |
| 				keys_(3), areaName_(3), advisor_(nrFaculty, 1.0) {
 | |
| 				advisor_[advisorIndex] = 0.0;
 | |
| 			}
 | |
| 			void print() const {
 | |
| 				using std::cout;
 | |
| 				cout << name_ << ": ";
 | |
| 				for (size_t area = 0; area < 3; area++)
 | |
| 					cout << areaName_[area] << " ";
 | |
| 				cout << std::endl;
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 		/** Maximum number of students */
 | |
| 		size_t maxNrStudents_;
 | |
| 
 | |
| 		/** discrete keys, indexed by student and area index */
 | |
| 		std::vector<Student> students_;
 | |
| 
 | |
| 		/** faculty identifiers */
 | |
| 		std::map<std::string, size_t> facultyIndex_;
 | |
| 		std::vector<std::string> facultyName_, slotName_, areaName_;
 | |
| 
 | |
| 		/** area constraints */
 | |
| 		typedef std::map<std::string, std::vector<double> > FacultyInArea;
 | |
| 		FacultyInArea facultyInArea_;
 | |
| 
 | |
| 		/** nrTimeSlots * nrFaculty availability constraints */
 | |
| 		std::string available_;
 | |
| 
 | |
| 		/** which slots are good */
 | |
| 		std::vector<double> slotsAvailable_;
 | |
| 
 | |
| 	public:
 | |
| 
 | |
| 		/**
 | |
| 		 * Constructor
 | |
| 		 * WE need to know the number of students in advance for ordering keys.
 | |
| 		 * then add faculty, slots, areas, availability, students, in that order
 | |
| 		 */
 | |
| 		Scheduler(size_t maxNrStudents):maxNrStudents_(maxNrStudents) {
 | |
| 		}
 | |
| 
 | |
| 		void addFaculty(const std::string& facultyName) {
 | |
| 			facultyIndex_[facultyName] = nrFaculty();
 | |
| 			facultyName_.push_back(facultyName);
 | |
| 		}
 | |
| 
 | |
| 		size_t nrFaculty() const {
 | |
| 			return facultyName_.size();
 | |
| 		}
 | |
| 
 | |
| 		/** boolean std::string of nrTimeSlots * nrFaculty */
 | |
| 		void setAvailability(const std::string& available) {
 | |
| 			available_ = available;
 | |
| 		}
 | |
| 
 | |
| 		void addSlot(const std::string& slotName) {
 | |
| 			slotName_.push_back(slotName);
 | |
| 		}
 | |
| 
 | |
| 		size_t nrTimeSlots() const {
 | |
| 			return slotName_.size();
 | |
| 		}
 | |
| 
 | |
| 		const std::string& slotName(size_t s) const {
 | |
| 			return slotName_[s];
 | |
| 		}
 | |
| 
 | |
| 		/** slots available, boolean */
 | |
| 		void setSlotsAvailable(const std::vector<double>& slotsAvailable) {
 | |
| 			slotsAvailable_ = slotsAvailable;
 | |
| 		}
 | |
| 
 | |
| 		void addArea(const std::string& facultyName, const std::string& areaName) {
 | |
| 			areaName_.push_back(areaName);
 | |
| 			std::vector<double>& table = facultyInArea_[areaName]; // will create if needed
 | |
| 			if (table.empty()) table.resize(nrFaculty(), 0);
 | |
| 			table[facultyIndex_[facultyName]] = 1;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Constructor that reads in faculty, slots, availibility.
 | |
| 		 * Still need to add areas and students after this
 | |
| 		 */
 | |
| 		Scheduler(size_t maxNrStudents, const std::string& filename);
 | |
| 
 | |
| 		/** get key for student and area, 0 is time slot itself */
 | |
| 		const DiscreteKey& key(size_t s, boost::optional<size_t> area = boost::none) const;
 | |
| 
 | |
| 		/** addStudent has to be called after adding slots and faculty */
 | |
| 		void addStudent(const std::string& studentName, const std::string& area1,
 | |
| 				const std::string& area2, const std::string& area3,
 | |
| 				const std::string& advisor);
 | |
| 
 | |
| 		/// current number of students
 | |
| 		size_t nrStudents() const {
 | |
| 			return students_.size();
 | |
| 		}
 | |
| 
 | |
| 		const std::string& studentName(size_t i) const;
 | |
| 		const DiscreteKey& studentKey(size_t i) const;
 | |
| 		const std::string& studentArea(size_t i, size_t area) const;
 | |
| 
 | |
| 		/** Add student-specific constraints to the graph */
 | |
| 		void addStudentSpecificConstraints(size_t i, boost::optional<size_t> slot = boost::none);
 | |
| 
 | |
| 		/** Main routine that builds factor graph */
 | |
| 		void buildGraph(size_t mutexBound = 7);
 | |
| 
 | |
| 		/** print */
 | |
| 		void print(const std::string& s = "Scheduler") const;
 | |
| 
 | |
| 		/** Print readable form of assignment */
 | |
| 		void printAssignment(sharedValues assignment) const;
 | |
| 
 | |
| 		/** Special print for single-student case */
 | |
| 		void printSpecial(sharedValues assignment) const;
 | |
| 
 | |
| 		/** Accumulate faculty stats */
 | |
| 		void accumulateStats(sharedValues assignment,
 | |
| 				std::vector<size_t>& stats) const;
 | |
| 
 | |
| 		/** Eliminate, return a Bayes net */
 | |
| 		DiscreteBayesNet::shared_ptr eliminate() const;
 | |
| 
 | |
| 		/** Find the best total assignment - can be expensive */
 | |
| 		sharedValues optimalAssignment() const;
 | |
| 
 | |
| 		/** find the assignment of students to slots with most possible committees */
 | |
| 		sharedValues bestSchedule() const;
 | |
| 
 | |
| 		/** find the corresponding most desirable committee assignment */
 | |
| 		sharedValues bestAssignment(sharedValues bestSchedule) const;
 | |
| 
 | |
| 	}; // Scheduler
 | |
| 
 | |
| } // gtsam
 | |
| 
 | |
| 
 |