Small changes for Qualifier 2013 Scheduling

release/4.3a0
Frank Dellaert 2013-03-19 18:05:13 +00:00
parent 396732ff6a
commit 458707ed45
9 changed files with 310 additions and 21 deletions

View File

@ -46,9 +46,8 @@ namespace gtsam {
const DecisionTreeFactor& marginal) : const DecisionTreeFactor& marginal) :
IndexConditional(joint.keys(), joint.size() - marginal.size()), Potentials( IndexConditional(joint.keys(), joint.size() - marginal.size()), Potentials(
ISDEBUG("DiscreteConditional::COUNT") ? joint : joint / marginal) { ISDEBUG("DiscreteConditional::COUNT") ? joint : joint / marginal) {
// assert(nrFrontals() == 1); if (ISDEBUG("DiscreteConditional::DiscreteConditional"))
if (ISDEBUG("DiscreteConditional::DiscreteConditional")) cout cout << (firstFrontalKey()) << endl; //TODO Print all keys
<< (firstFrontalKey()) << endl; //TODO Print all keys
} }
/* ******************************************************************************** */ /* ******************************************************************************** */
@ -88,16 +87,8 @@ namespace gtsam {
/* ******************************************************************************** */ /* ******************************************************************************** */
void DiscreteConditional::solveInPlace(Values& values) const { void DiscreteConditional::solveInPlace(Values& values) const {
// OLD // TODO: Abhijit asks: is this really the fastest way? He thinks it is.
// assert(nrFrontals() == 1);
// Index j = (firstFrontalKey());
// size_t mpe = solve(values); // Solve for variable
// values[j] = mpe; // store result in partial solution
// OLD
// TODO: is this really the fastest way? I think it is.
//The following is to make make adjustment for nFrontals \neq 1
ADT pFS = choose(values); // P(F|S=parentsValues) ADT pFS = choose(values); // P(F|S=parentsValues)
// Initialize // Initialize

View File

@ -100,9 +100,8 @@ namespace gtsam {
// PRODUCT: multiply all factors // PRODUCT: multiply all factors
gttic(product); gttic(product);
DecisionTreeFactor product; DecisionTreeFactor product;
BOOST_FOREACH(const DiscreteFactor::shared_ptr& factor, factors){ BOOST_FOREACH(const DiscreteFactor::shared_ptr& factor, factors)
product = (*factor) * product; product = (*factor) * product;
}
gttoc(product); gttoc(product);

View File

@ -32,6 +32,7 @@ namespace gtsam {
template<class FACTOR> template<class FACTOR>
GenericSequentialSolver<FACTOR>::GenericSequentialSolver(const FactorGraph<FACTOR>& factorGraph) { GenericSequentialSolver<FACTOR>::GenericSequentialSolver(const FactorGraph<FACTOR>& factorGraph) {
gttic(GenericSequentialSolver_constructor1); gttic(GenericSequentialSolver_constructor1);
assert(factorGraph.size());
factors_.reset(new FactorGraph<FACTOR>(factorGraph)); factors_.reset(new FactorGraph<FACTOR>(factorGraph));
structure_.reset(new VariableIndex(factorGraph)); structure_.reset(new VariableIndex(factorGraph));
eliminationTree_ = EliminationTree<FACTOR>::Create(*factors_, *structure_); eliminationTree_ = EliminationTree<FACTOR>::Create(*factors_, *structure_);

View File

@ -29,6 +29,7 @@ add_dependencies(check.unstable check.discrete_unstable)
set(discrete_unstable_examples set(discrete_unstable_examples
schedulingExample schedulingExample
schedulingQuals12 schedulingQuals12
schedulingQuals13
) )
if (GTSAM_BUILD_EXAMPLES) if (GTSAM_BUILD_EXAMPLES)

View File

@ -112,6 +112,7 @@ namespace gtsam {
if (!slot && !slotsAvailable_.empty()) { if (!slot && !slotsAvailable_.empty()) {
if (debug) cout << "Adding availability of slots" << endl; if (debug) cout << "Adding availability of slots" << endl;
assert(slotsAvailable_.size()==s.key_.second);
CSP::add(s.key_, slotsAvailable_); CSP::add(s.key_, slotsAvailable_);
} }
@ -122,21 +123,24 @@ namespace gtsam {
const string& areaName = s.areaName_[area]; const string& areaName = s.areaName_[area];
if (debug) cout << "Area constraints " << areaName << endl; if (debug) cout << "Area constraints " << areaName << endl;
assert(facultyInArea_[areaName].size()==areaKey.second);
CSP::add(areaKey, facultyInArea_[areaName]); CSP::add(areaKey, facultyInArea_[areaName]);
if (debug) cout << "Advisor constraint " << areaName << endl; if (debug) cout << "Advisor constraint " << areaName << endl;
assert(s.advisor_.size()==areaKey.second);
CSP::add(areaKey, s.advisor_); CSP::add(areaKey, s.advisor_);
if (debug) cout << "Availability of faculty " << areaName << endl; if (debug) cout << "Availability of faculty " << areaName << endl;
if (slot) { if (slot) {
// get all constraints then specialize to slot // get all constraints then specialize to slot
DiscreteKey dummy(0, nrTimeSlots()); size_t dummyIndex = maxNrStudents_*3+maxNrStudents_;
Potentials::ADT p(dummy & areaKey, available_); DiscreteKey dummy(dummyIndex, nrTimeSlots());
Potentials::ADT q = p.choose(0, *slot); Potentials::ADT p(dummy & areaKey, available_); // available_ is Doodle string
Potentials::ADT q = p.choose(dummyIndex, *slot);
DiscreteFactor::shared_ptr f(new DecisionTreeFactor(areaKey, q)); DiscreteFactor::shared_ptr f(new DecisionTreeFactor(areaKey, q));
CSP::push_back(f); CSP::push_back(f);
} else { } else {
CSP::add(s.key_, areaKey, available_); CSP::add(s.key_, areaKey, available_); // available_ is Doodle string
} }
} }
@ -233,7 +237,7 @@ namespace gtsam {
Values::const_iterator it = assignment->begin(); Values::const_iterator it = assignment->begin();
for (size_t area = 0; area < 3; area++, it++) { for (size_t area = 0; area < 3; area++, it++) {
size_t f = it->second; size_t f = it->second;
cout << setw(12) << it->first << ": " << facultyName_[f] << endl; cout << setw(12) << studentArea(0,area) << ": " << facultyName_[f] << endl;
} }
cout << endl; cout << endl;
} }

View File

@ -0,0 +1 @@
,Ayanna Howard,Ron Arkin,Henrik Christensen,Panos Tsiotras,Patricio Vela,Magnus Egerstedt,Fumin Zhang,Charles Isbell,Karen Feigh,Jun Ueda,Frank Dellaert,Andrea Thomaz,Wayne Book,Harvey Lipkin,Charlie Kemp,Mike Stilman,Jeff Shamma Mon 9:00 AM - 10:30 AM,1,,1,1,1,1,,1,,,1,,,1,1,,1 Mon 10:30 AM - 12:00 PM,1,,1,1,1,,1,,,1,1,1,1,,1,1, Mon 12:00 PM - 1:30 PM,1,1,,,1,1,1,,,1,1,1,1,1,1,1,1 Mon 1:30 PM - 3:00 PM,1,1,,,1,1,1,1,,1,1,1,1,1,,1,1 Mon 3:00 PM - 4:30 PM,1,,1,1,1,,1,1,,1,1,1,1,1,,1,1 Tue 9:00 AM - 10:30 AM,1,,1,1,,1,,1,,,1,,,1,,,1 Tue 10:30 AM - 12:00 PM,1,,1,1,,1,1,1,,1,1,1,,1,,1, Tue 12:00 PM - 1:30 PM,1,1,1,1,,1,1,1,1,,1,1,,1,,, Tue 1:30 PM - 3:00 PM,,1,,1,,,1,,1,1,1,1,,1,,1, Tue 3:00 PM - 4:30 PM,,,1,1,,1,1,,,1,,1,,1,,, Wed 9:00 AM - 10:30 AM,,,1,1,1,1,,1,1,,1,,,1,1,1, Wed 10:30 AM - 12:00 PM,,,1,1,1,1,1,1,,1,1,1,,,1,, Wed 12:00 PM - 1:30 PM,1,,,1,1,1,,1,,1,1,,,1,1,, Wed 1:30 PM - 3:00 PM,,,1,,1,1,,1,,1,1,,,1,1,1, Wed 3:00 PM - 4:30 PM,,,1,1,1,1,1,1,,1,,,,,1,,1 Thu 9:00 AM - 10:30 AM,1,,1,1,1,,,,,,1,,,1,1,,1 Thu 10:30 AM - 12:00 PM,,,1,1,1,,1,,,1,1,1,,1,,1, Thu 12:00 PM - 1:30 PM,,1,1,1,,,1,,1,,1,1,,1,,, Thu 1:30 PM - 3:00 PM,,,1,1,,,1,,1,1,1,1,,1,,1, Thu 3:00 PM - 4:30 PM,1,,1,1,,,1,,,1,,1,,,,1, Fri 9:00 AM - 10:30 AM,1,,1,1,,,,1,,,1,,,1,,, Fri 10:30 AM - 12:00 PM,,,1,1,1,,1,1,,1,1,1,,,1,1, Fri 12:00 PM - 1:30 PM,1,,1,1,1,,1,,,1,1,,,1,1,1, Fri 1:30 PM - 3:00 PM,1,,1,1,,,,,,1,1,,,1,,1, Fri 3:00 PM - 4:30 PM,,,1,1,1,,,,,1,1,,,1,,,
1 Ayanna Howard Ron Arkin Henrik Christensen Panos Tsiotras Patricio Vela Magnus Egerstedt Fumin Zhang Charles Isbell Karen Feigh Jun Ueda Frank Dellaert Andrea Thomaz Wayne Book Harvey Lipkin Charlie Kemp Mike Stilman Jeff Shamma Mon 9:00 AM - 10:30 AM 1 1 1 1 1 1 1 1 1 1 Mon 10:30 AM - 12:00 PM 1 1 1 1 1 1 1 1 1 1 1 Mon 12:00 PM - 1:30 PM 1 1 1 1 1 1 1 1 1 1 1 1 1 Mon 1:30 PM - 3:00 PM 1 1 1 1 1 1 1 1 1 1 1 1 1 Mon 3:00 PM - 4:30 PM 1 1 1 1 1 1 1 1 1 1 1 1 1 Tue 9:00 AM - 10:30 AM 1 1 1 1 1 1 1 1 Tue 10:30 AM - 12:00 PM 1 1 1 1 1 1 1 1 1 1 1 Tue 12:00 PM - 1:30 PM 1 1 1 1 1 1 1 1 1 1 1 Tue 1:30 PM - 3:00 PM 1 1 1 1 1 1 1 1 1 Tue 3:00 PM - 4:30 PM 1 1 1 1 1 1 1 Wed 9:00 AM - 10:30 AM 1 1 1 1 1 1 1 1 1 1 Wed 10:30 AM - 12:00 PM 1 1 1 1 1 1 1 1 1 1 Wed 12:00 PM - 1:30 PM 1 1 1 1 1 1 1 1 1 Wed 1:30 PM - 3:00 PM 1 1 1 1 1 1 1 1 1 Wed 3:00 PM - 4:30 PM 1 1 1 1 1 1 1 1 1 Thu 9:00 AM - 10:30 AM 1 1 1 1 1 1 1 1 Thu 10:30 AM - 12:00 PM 1 1 1 1 1 1 1 1 1 Thu 12:00 PM - 1:30 PM 1 1 1 1 1 1 1 1 Thu 1:30 PM - 3:00 PM 1 1 1 1 1 1 1 1 1 Thu 3:00 PM - 4:30 PM 1 1 1 1 1 1 1 Fri 9:00 AM - 10:30 AM 1 1 1 1 1 1 Fri 10:30 AM - 12:00 PM 1 1 1 1 1 1 1 1 1 1 Fri 12:00 PM - 1:30 PM 1 1 1 1 1 1 1 1 1 1 Fri 1:30 PM - 3:00 PM 1 1 1 1 1 1 1 Fri 3:00 PM - 4:30 PM 1 1 1 1 1 1

Binary file not shown.

View File

@ -255,8 +255,8 @@ void sampleSolutions() {
/* ************************************************************************* */ /* ************************************************************************* */
int main() { int main() {
runLargeExample(); // runLargeExample();
// solveStaged(3); solveStaged(3);
// sampleSolutions(); // sampleSolutions();
return 0; return 0;
} }

View File

@ -0,0 +1,292 @@
/*
* schedulingExample.cpp
* @brief hard scheduling example
* @date March 25, 2011
* @author Frank Dellaert
*/
#define ENABLE_TIMING
#define ADD_NO_CACHING
#define ADD_NO_PRUNING
#include <gtsam_unstable/discrete/Scheduler.h>
#include <gtsam/base/debug.h>
#include <gtsam/base/timing.h>
#include <boost/assign/std/vector.hpp>
#include <boost/assign/std/map.hpp>
#include <boost/optional.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <algorithm>
using namespace boost::assign;
using namespace std;
using namespace gtsam;
size_t NRSTUDENTS = 12;
bool NonZero(size_t i) {
return i > 0;
}
/* ************************************************************************* */
void addStudent(Scheduler& s, size_t i) {
switch (i) {
case 0:
s.addStudent("Young, Carol", "Controls", "Autonomy", "Mechanics", "Fumin Zhang");
break;
case 1:
s.addStudent("Erdogan, Can", "Controls", "AI", "Perception", "Mike Stilman");
break;
case 2:
s.addStudent("Arslan, Oktay", "Controls", "AI", "Mechanics", "Panos Tsiotras");
break;
case 3:
s.addStudent("Bhattacharjee, Tapomayukh", "Controls", "AI", "Mechanics", "Charlie Kemp");
break;
case 4:
s.addStudent("Grey, Michael", "Controls", "AI", "Mechanics", "Wayne Book");
break;
case 5:
s.addStudent("O'Flaherty, Rowland", "Controls", "AI", "Mechanics", "Magnus Egerstedt");
break;
case 6:
s.addStudent("Pickem, Daniel", "Controls", "AI", "Mechanics", "Jeff Shamma");
break;
case 7:
s.addStudent("Lee, Kimoon", "Controls", "Autonomy", "Mechanics", "Henrik Christensen");
break;
case 8:
s.addStudent("Melim, Andrew Lyon", "Controls", "AI", "Perception", "Frank Dellaert");
break;
case 9:
s.addStudent("Jensen, David", "Controls", "Autonomy", "HRI", "Andrea Thomaz");
break;
case 10:
s.addStudent("Nisbett, Jared", "Controls", "Perception", "Mechanics", "Magnus Egerstedt");
break;
case 11:
s.addStudent("Pan, Yunpeng", "Controls", "Perception", "Mechanics", "Wayne Book");
break;
// case 12:
// s.addStudent("Grice, Phillip", "Controls", "None", "None", "Wayne Book");
// break;
// case 13:
// s.addStudent("Robinette, Paul", "Controls", "None", "None", "Ayanna Howard");
// break;
// case 14:
// s.addStudent("Huaman, Ana", "Autonomy", "None", "None", "Mike Stilman");
// break;
}
}
/* ************************************************************************* */
Scheduler largeExample(size_t nrStudents = NRSTUDENTS, bool addStudents=true) {
string path("../../../gtsam_unstable/discrete/examples/");
Scheduler s(nrStudents, path + "Doodle2013.csv");
s.addArea("Harvey Lipkin", "Mechanics");
s.addArea("Jun Ueda", "Mechanics");
s.addArea("Mike Stilman", "Mechanics");
// s.addArea("Frank Dellaert", "Mechanics");
s.addArea("Wayne Book", "Mechanics");
// s.addArea("Charlie Kemp", "Mechanics");
s.addArea("Patricio Vela", "Controls");
s.addArea("Magnus Egerstedt", "Controls");
s.addArea("Jun Ueda", "Controls");
s.addArea("Panos Tsiotras", "Controls");
s.addArea("Fumin Zhang", "Controls");
s.addArea("Ayanna Howard", "Controls");
s.addArea("Jeff Shamma", "Controls");
s.addArea("Frank Dellaert", "Perception");
s.addArea("Henrik Christensen", "Perception");
s.addArea("Mike Stilman", "AI");
// s.addArea("Henrik Christensen", "AI");
// s.addArea("Ayanna Howard", "AI");
s.addArea("Charles Isbell", "AI");
// s.addArea("Tucker Balch", "AI");
s.addArea("Andrea Thomaz", "AI");
s.addArea("Ayanna Howard", "Autonomy");
s.addArea("Charlie Kemp", "Autonomy");
// s.addArea("Andrea Thomaz", "HRI");
s.addArea("Karen Feigh", "HRI");
// s.addArea("Charlie Kemp", "HRI");
// add students
if (addStudents)
for (size_t i = 0; i < nrStudents; i++)
addStudent(s, i);
return s;
}
/* ************************************************************************* */
void runLargeExample() {
Scheduler scheduler = largeExample();
scheduler.print();
// BUILD THE GRAPH !
size_t addMutex = 3;
SETDEBUG("Scheduler::buildGraph", true);
scheduler.buildGraph(addMutex);
// Do brute force product and output that to file
if (scheduler.nrStudents() == 1) { // otherwise too slow
DecisionTreeFactor product = scheduler.product();
product.dot("scheduling-large", false);
}
// Do exact inference
// SETDEBUG("timing-verbose", true);
SETDEBUG("DiscreteConditional::DiscreteConditional", true);
//#define SAMPLE
#ifdef SAMPLE
gttic(large);
DiscreteBayesNet::shared_ptr chordal = scheduler.eliminate();
gttoc(large);
tictoc_finishedIteration();
tictoc_print();
for (size_t i=0;i<100;i++) {
DiscreteFactor::sharedValues assignment = sample(*chordal);
vector<size_t> stats(scheduler.nrFaculty());
scheduler.accumulateStats(assignment, stats);
size_t max = *max_element(stats.begin(), stats.end());
size_t min = *min_element(stats.begin(), stats.end());
size_t nz = count_if(stats.begin(), stats.end(), NonZero);
// cout << min << ", " << max << ", " << nz << endl;
if (nz >= 13 && min >=1 && max <= 4) {
cout << "======================================================\n";
scheduler.printAssignment(assignment);
}
}
#else
gttic(large);
DiscreteFactor::sharedValues MPE = scheduler.optimalAssignment();
gttoc(large);
tictoc_finishedIteration();
tictoc_print();
scheduler.printAssignment(MPE);
#endif
}
/* ************************************************************************* */
// Solve a series of relaxed problems for maximum flexibility solution
void solveStaged(size_t addMutex = 2) {
bool debug = false;
// super-hack! just count...
SETDEBUG("DiscreteConditional::COUNT", true);
SETDEBUG("DiscreteConditional::DiscreteConditional", debug); // progress
// make a vector with slot availability, initially all 1
// Reads file to get count :-)
vector<double> slotsAvailable(largeExample(0).nrTimeSlots(), 1.0);
// now, find optimal value for each student, using relaxed mutex constraints
for (size_t s = 0; s < NRSTUDENTS; s++) {
// add all students first time, then drop last one second time, etc...
Scheduler scheduler = largeExample(NRSTUDENTS - s);
// scheduler.print(str(boost::format("Scheduler %d") % (NRSTUDENTS-s)));
// only allow slots not yet taken
scheduler.setSlotsAvailable(slotsAvailable);
// BUILD THE GRAPH !
scheduler.buildGraph(addMutex);
// Do EXACT INFERENCE
gttic_(eliminate);
DiscreteBayesNet::shared_ptr chordal = scheduler.eliminate();
gttoc_(eliminate);
// find root node
DiscreteConditional::shared_ptr root = *(chordal->rbegin());
if (debug)
root->print(""/*scheduler.studentName(s)*/);
// solve root node only
Scheduler::Values values;
size_t bestSlot = root->solve(values);
// get corresponding count
DiscreteKey dkey = scheduler.studentKey(NRSTUDENTS - 1 - s);
values[dkey.first] = bestSlot;
double count = (*root)(values);
// remove this slot from consideration
slotsAvailable[bestSlot] = 0.0;
cout << boost::format("%s = %d (%d), count = %d") % scheduler.studentName(NRSTUDENTS-1-s)
% scheduler.slotName(bestSlot) % bestSlot % count << endl;
}
tictoc_print_();
}
/* ************************************************************************* */
// Sample from solution found above and evaluate cost function
DiscreteBayesNet::shared_ptr createSampler(size_t i,
size_t slot, vector<Scheduler>& schedulers) {
Scheduler scheduler = largeExample(1,false);
addStudent(scheduler, i);
cout << " creating sampler for " << scheduler.studentName(0) << endl;
SETDEBUG("Scheduler::buildGraph", false);
// scheduler.print();
scheduler.addStudentSpecificConstraints(0, slot);
DiscreteBayesNet::shared_ptr chordal = scheduler.eliminate();
schedulers.push_back(scheduler);
return chordal;
}
void sampleSolutions() {
size_t nrFaculty = 17; // Change to correct number !
vector<Scheduler> schedulers;
vector<DiscreteBayesNet::shared_ptr> samplers(NRSTUDENTS);
// Given the time-slots, we can create NRSTUDENTS independent samplers
vector<size_t> slots;
slots += 12,11,13, 21,16,1, 3,2,6, 7,22,4; // given slots
for (size_t i = 0; i < NRSTUDENTS; i++)
samplers[i] = createSampler(i, slots[i], schedulers);
// now, sample schedules
for (size_t n = 0; n < 10000; n++) {
vector<size_t> stats(nrFaculty, 0);
vector<Scheduler::sharedValues> samples;
for (size_t i = 0; i < NRSTUDENTS; i++) {
samples.push_back(sample(*samplers[i]));
schedulers[i].accumulateStats(samples[i], stats);
}
size_t max = *max_element(stats.begin(), stats.end());
size_t min = *min_element(stats.begin(), stats.end());
size_t nz = count_if(stats.begin(), stats.end(), NonZero);
if (nz >= 16 && max <= 3) {
cout << boost::format(
"Sampled schedule %d, min = %d, nz = %d, max = %d\n") % (n + 1) % min
% nz % max;
for (size_t i = 0; i < NRSTUDENTS; i++) {
cout << schedulers[i].studentName(0) << " : " << schedulers[i].slotName(
slots[i]) << endl;
schedulers[i].printSpecial(samples[i]);
}
}
}
}
/* ************************************************************************* */
int main() {
// runLargeExample();
// solveStaged(3);
sampleSolutions();
return 0;
}
/* ************************************************************************* */