Formatting with Google style
parent
13b0136e03
commit
d27d6b60a7
|
@ -5,26 +5,23 @@
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/Domain.h>
|
|
||||||
#include <gtsam_unstable/discrete/AllDiff.h>
|
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
|
#include <gtsam_unstable/discrete/AllDiff.h>
|
||||||
|
#include <gtsam_unstable/discrete/Domain.h>
|
||||||
|
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
AllDiff::AllDiff(const DiscreteKeys& dkeys) :
|
AllDiff::AllDiff(const DiscreteKeys& dkeys) : Constraint(dkeys.indices()) {
|
||||||
Constraint(dkeys.indices()) {
|
for (const DiscreteKey& dkey : dkeys) cardinalities_.insert(dkey);
|
||||||
for(const DiscreteKey& dkey: dkeys)
|
|
||||||
cardinalities_.insert(dkey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void AllDiff::print(const std::string& s,
|
void AllDiff::print(const std::string& s, const KeyFormatter& formatter) const {
|
||||||
const KeyFormatter& formatter) const {
|
|
||||||
std::cout << s << "AllDiff on ";
|
std::cout << s << "AllDiff on ";
|
||||||
for (Key dkey: keys_)
|
for (Key dkey : keys_) std::cout << formatter(dkey) << " ";
|
||||||
std::cout << formatter(dkey) << " ";
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +38,8 @@ namespace gtsam {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
DecisionTreeFactor AllDiff::toDecisionTreeFactor() const {
|
DecisionTreeFactor AllDiff::toDecisionTreeFactor() const {
|
||||||
// We will do this by converting the allDif into many BinaryAllDiff constraints
|
// We will do this by converting the allDif into many BinaryAllDiff
|
||||||
|
// constraints
|
||||||
DecisionTreeFactor converted;
|
DecisionTreeFactor converted;
|
||||||
size_t nrKeys = keys_.size();
|
size_t nrKeys = keys_.size();
|
||||||
for (size_t i1 = 0; i1 < nrKeys; i1++)
|
for (size_t i1 = 0; i1 < nrKeys; i1++)
|
||||||
|
@ -59,7 +57,8 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
bool AllDiff::ensureArcConsistency(size_t j, std::vector<Domain>& domains) const {
|
bool AllDiff::ensureArcConsistency(size_t j,
|
||||||
|
std::vector<Domain>& domains) const {
|
||||||
// Though strictly not part of allDiff, we check for
|
// Though strictly not part of allDiff, we check for
|
||||||
// a value in domains[j] that does not occur in any other connected domain.
|
// a value in domains[j] that does not occur in any other connected domain.
|
||||||
// If found, we make this a singleton...
|
// If found, we make this a singleton...
|
||||||
|
@ -101,8 +100,7 @@ namespace gtsam {
|
||||||
DiscreteFactor::Values known;
|
DiscreteFactor::Values known;
|
||||||
for (Key k : keys_) {
|
for (Key k : keys_) {
|
||||||
const Domain& Dk = domains[k];
|
const Domain& Dk = domains[k];
|
||||||
if (Dk.isSingleton())
|
if (Dk.isSingleton()) known[k] = Dk.firstValue();
|
||||||
known[k] = Dk.firstValue();
|
|
||||||
}
|
}
|
||||||
return partiallyApply(known);
|
return partiallyApply(known);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/BinaryAllDiff.h>
|
|
||||||
#include <gtsam/discrete/DiscreteKey.h>
|
#include <gtsam/discrete/DiscreteKey.h>
|
||||||
|
#include <gtsam_unstable/discrete/BinaryAllDiff.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ namespace gtsam {
|
||||||
* keep the Indices locally, and the Indices are stored in IndexFactor.
|
* keep the Indices locally, and the Indices are stored in IndexFactor.
|
||||||
*/
|
*/
|
||||||
class GTSAM_UNSTABLE_EXPORT AllDiff : public Constraint {
|
class GTSAM_UNSTABLE_EXPORT AllDiff : public Constraint {
|
||||||
|
|
||||||
std::map<Key, size_t> cardinalities_;
|
std::map<Key, size_t> cardinalities_;
|
||||||
|
|
||||||
DiscreteKey discreteKey(size_t i) const {
|
DiscreteKey discreteKey(size_t i) const {
|
||||||
|
@ -29,13 +28,12 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
AllDiff(const DiscreteKeys& dkeys);
|
AllDiff(const DiscreteKeys& dkeys);
|
||||||
|
|
||||||
// print
|
// print
|
||||||
void print(const std::string& s = "",
|
void print(const std::string& s = "", const KeyFormatter& formatter =
|
||||||
const KeyFormatter& formatter = DefaultKeyFormatter) const override;
|
DefaultKeyFormatter) const override;
|
||||||
|
|
||||||
/// equals
|
/// equals
|
||||||
bool equals(const DiscreteFactor& other, double tol) const override {
|
bool equals(const DiscreteFactor& other, double tol) const override {
|
||||||
|
@ -43,8 +41,8 @@ namespace gtsam {
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
const AllDiff& f(static_cast<const AllDiff&>(other));
|
const AllDiff& f(static_cast<const AllDiff&>(other));
|
||||||
return cardinalities_.size() == f.cardinalities_.size()
|
return cardinalities_.size() == f.cardinalities_.size() &&
|
||||||
&& std::equal(cardinalities_.begin(), cardinalities_.end(),
|
std::equal(cardinalities_.begin(), cardinalities_.end(),
|
||||||
f.cardinalities_.begin());
|
f.cardinalities_.begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,13 +63,15 @@ namespace gtsam {
|
||||||
* @param j domain to be checked
|
* @param j domain to be checked
|
||||||
* @param domains all other domains
|
* @param domains all other domains
|
||||||
*/
|
*/
|
||||||
bool ensureArcConsistency(size_t j, std::vector<Domain>& domains) const override;
|
bool ensureArcConsistency(size_t j,
|
||||||
|
std::vector<Domain>& domains) const override;
|
||||||
|
|
||||||
/// Partially apply known values
|
/// Partially apply known values
|
||||||
Constraint::shared_ptr partiallyApply(const Values&) const override;
|
Constraint::shared_ptr partiallyApply(const Values&) const override;
|
||||||
|
|
||||||
/// Partially apply known values, domain version
|
/// Partially apply known values, domain version
|
||||||
Constraint::shared_ptr partiallyApply(const std::vector<Domain>&) const override;
|
Constraint::shared_ptr partiallyApply(
|
||||||
|
const std::vector<Domain>&) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gtsam
|
} // namespace gtsam
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/Domain.h>
|
|
||||||
#include <gtsam_unstable/discrete/Constraint.h>
|
|
||||||
#include <gtsam/discrete/DecisionTreeFactor.h>
|
#include <gtsam/discrete/DecisionTreeFactor.h>
|
||||||
|
#include <gtsam_unstable/discrete/Constraint.h>
|
||||||
|
#include <gtsam_unstable/discrete/Domain.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
@ -21,19 +21,18 @@ namespace gtsam {
|
||||||
* keep the Indices locally, and the Indices are stored in IndexFactor.
|
* keep the Indices locally, and the Indices are stored in IndexFactor.
|
||||||
*/
|
*/
|
||||||
class BinaryAllDiff : public Constraint {
|
class BinaryAllDiff : public Constraint {
|
||||||
|
|
||||||
size_t cardinality0_, cardinality1_; /// cardinality
|
size_t cardinality0_, cardinality1_; /// cardinality
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
BinaryAllDiff(const DiscreteKey& key1, const DiscreteKey& key2) :
|
BinaryAllDiff(const DiscreteKey& key1, const DiscreteKey& key2)
|
||||||
Constraint(key1.first, key2.first),
|
: Constraint(key1.first, key2.first),
|
||||||
cardinality0_(key1.second), cardinality1_(key2.second) {
|
cardinality0_(key1.second),
|
||||||
}
|
cardinality1_(key2.second) {}
|
||||||
|
|
||||||
// print
|
// print
|
||||||
void print(const std::string& s = "",
|
void print(
|
||||||
|
const std::string& s = "",
|
||||||
const KeyFormatter& formatter = DefaultKeyFormatter) const override {
|
const KeyFormatter& formatter = DefaultKeyFormatter) const override {
|
||||||
std::cout << s << "BinaryAllDiff on " << formatter(keys_[0]) << " and "
|
std::cout << s << "BinaryAllDiff on " << formatter(keys_[0]) << " and "
|
||||||
<< formatter(keys_[1]) << std::endl;
|
<< formatter(keys_[1]) << std::endl;
|
||||||
|
@ -45,7 +44,8 @@ namespace gtsam {
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
const BinaryAllDiff& f(static_cast<const BinaryAllDiff&>(other));
|
const BinaryAllDiff& f(static_cast<const BinaryAllDiff&>(other));
|
||||||
return (cardinality0_==f.cardinality0_) && (cardinality1_==f.cardinality1_);
|
return (cardinality0_ == f.cardinality0_) &&
|
||||||
|
(cardinality1_ == f.cardinality1_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +61,7 @@ namespace gtsam {
|
||||||
keys.push_back(DiscreteKey(keys_[1], cardinality1_));
|
keys.push_back(DiscreteKey(keys_[1], cardinality1_));
|
||||||
std::vector<double> table;
|
std::vector<double> table;
|
||||||
for (size_t i1 = 0; i1 < cardinality0_; i1++)
|
for (size_t i1 = 0; i1 < cardinality0_; i1++)
|
||||||
for (size_t i2 = 0; i2 < cardinality1_; i2++)
|
for (size_t i2 = 0; i2 < cardinality1_; i2++) table.push_back(i1 != i2);
|
||||||
table.push_back(i1 != i2);
|
|
||||||
DecisionTreeFactor converted(keys, table);
|
DecisionTreeFactor converted(keys, table);
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
|
@ -78,8 +77,8 @@ namespace gtsam {
|
||||||
* @param j domain to be checked
|
* @param j domain to be checked
|
||||||
* @param domains all other domains
|
* @param domains all other domains
|
||||||
*/
|
*/
|
||||||
///
|
bool ensureArcConsistency(size_t j,
|
||||||
bool ensureArcConsistency(size_t j, std::vector<Domain>& domains) const override {
|
std::vector<Domain>& domains) const override {
|
||||||
// throw std::runtime_error(
|
// throw std::runtime_error(
|
||||||
// "BinaryAllDiff::ensureArcConsistency not implemented");
|
// "BinaryAllDiff::ensureArcConsistency not implemented");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/Domain.h>
|
|
||||||
#include <gtsam_unstable/discrete/CSP.h>
|
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
|
#include <gtsam_unstable/discrete/CSP.h>
|
||||||
|
#include <gtsam_unstable/discrete/Domain.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ namespace gtsam {
|
||||||
return mpe;
|
return mpe;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSP::runArcConsistency(size_t cardinality, size_t nrIterations, bool print) const {
|
void CSP::runArcConsistency(size_t cardinality, size_t nrIterations,
|
||||||
|
bool print) const {
|
||||||
// Create VariableIndex
|
// Create VariableIndex
|
||||||
VariableIndex index(*this);
|
VariableIndex index(*this);
|
||||||
// index.print();
|
// index.print();
|
||||||
|
@ -55,9 +56,12 @@ namespace gtsam {
|
||||||
// if not already a singleton
|
// if not already a singleton
|
||||||
if (!domains[v].isSingleton()) {
|
if (!domains[v].isSingleton()) {
|
||||||
// get the constraint and call its ensureArcConsistency method
|
// get the constraint and call its ensureArcConsistency method
|
||||||
Constraint::shared_ptr constraint = boost::dynamic_pointer_cast<Constraint>((*this)[f]);
|
Constraint::shared_ptr constraint =
|
||||||
if (!constraint) throw runtime_error("CSP:runArcConsistency: non-constraint factor");
|
boost::dynamic_pointer_cast<Constraint>((*this)[f]);
|
||||||
changed[v] = constraint->ensureArcConsistency(v,domains) || changed[v];
|
if (!constraint)
|
||||||
|
throw runtime_error("CSP:runArcConsistency: non-constraint factor");
|
||||||
|
changed[v] =
|
||||||
|
constraint->ensureArcConsistency(v, domains) || changed[v];
|
||||||
}
|
}
|
||||||
} // f
|
} // f
|
||||||
if (changed[v]) anyChange = true;
|
if (changed[v]) anyChange = true;
|
||||||
|
@ -92,12 +96,13 @@ namespace gtsam {
|
||||||
// KeyOrdering ordering;
|
// KeyOrdering ordering;
|
||||||
// vector<Index> dkeys;
|
// vector<Index> dkeys;
|
||||||
for (const DiscreteFactor::shared_ptr& f : factors_) {
|
for (const DiscreteFactor::shared_ptr& f : factors_) {
|
||||||
Constraint::shared_ptr constraint = boost::dynamic_pointer_cast<Constraint>(f);
|
Constraint::shared_ptr constraint =
|
||||||
if (!constraint) throw runtime_error("CSP:runArcConsistency: non-constraint factor");
|
boost::dynamic_pointer_cast<Constraint>(f);
|
||||||
|
if (!constraint)
|
||||||
|
throw runtime_error("CSP:runArcConsistency: non-constraint factor");
|
||||||
Constraint::shared_ptr reduced = constraint->partiallyApply(domains);
|
Constraint::shared_ptr reduced = constraint->partiallyApply(domains);
|
||||||
if (print) reduced->print();
|
if (print) reduced->print();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} // gtsam
|
} // namespace gtsam
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtsam/discrete/DiscreteFactorGraph.h>
|
||||||
#include <gtsam_unstable/discrete/AllDiff.h>
|
#include <gtsam_unstable/discrete/AllDiff.h>
|
||||||
#include <gtsam_unstable/discrete/SingleValue.h>
|
#include <gtsam_unstable/discrete/SingleValue.h>
|
||||||
#include <gtsam/discrete/DiscreteFactorGraph.h>
|
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
@ -20,14 +20,12 @@ namespace gtsam {
|
||||||
*/
|
*/
|
||||||
class GTSAM_UNSTABLE_EXPORT CSP : public DiscreteFactorGraph {
|
class GTSAM_UNSTABLE_EXPORT CSP : public DiscreteFactorGraph {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** A map from keys to values */
|
/** A map from keys to values */
|
||||||
typedef KeyVector Indices;
|
typedef KeyVector Indices;
|
||||||
typedef Assignment<Key> Values;
|
typedef Assignment<Key> Values;
|
||||||
typedef boost::shared_ptr<Values> sharedValues;
|
typedef boost::shared_ptr<Values> sharedValues;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// /// Constructor
|
// /// Constructor
|
||||||
// CSP() {
|
// CSP() {
|
||||||
// }
|
// }
|
||||||
|
@ -40,8 +38,7 @@ namespace gtsam {
|
||||||
|
|
||||||
/// Add a binary AllDiff constraint
|
/// Add a binary AllDiff constraint
|
||||||
void addAllDiff(const DiscreteKey& key1, const DiscreteKey& key2) {
|
void addAllDiff(const DiscreteKey& key1, const DiscreteKey& key2) {
|
||||||
boost::shared_ptr<BinaryAllDiff> factor(
|
boost::shared_ptr<BinaryAllDiff> factor(new BinaryAllDiff(key1, key2));
|
||||||
new BinaryAllDiff(key1, key2));
|
|
||||||
push_back(factor);
|
push_back(factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +68,8 @@ namespace gtsam {
|
||||||
// * whether any satisfying separator assignment can be found.
|
// * whether any satisfying separator assignment can be found.
|
||||||
// * This corresponds to hyper-arc consistency in CSP speak.
|
// * This corresponds to hyper-arc consistency in CSP speak.
|
||||||
// * This can be done by creating a mini-factor graph and search.
|
// * This can be done by creating a mini-factor graph and search.
|
||||||
// * For a nine-by-nine Sudoku, the search tree will be 8+6+6=20 levels deep.
|
// * For a nine-by-nine Sudoku, the search tree will be 8+6+6=20 levels
|
||||||
|
// deep.
|
||||||
// * It will be very expensive to exclude values that way.
|
// * It will be very expensive to exclude values that way.
|
||||||
// */
|
// */
|
||||||
// void applyBeliefPropagation(size_t nrIterations = 10) const;
|
// void applyBeliefPropagation(size_t nrIterations = 10) const;
|
||||||
|
@ -86,5 +84,4 @@ namespace gtsam {
|
||||||
bool print = false) const;
|
bool print = false) const;
|
||||||
}; // CSP
|
}; // CSP
|
||||||
|
|
||||||
} // gtsam
|
} // namespace gtsam
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam_unstable/dllexport.h>
|
|
||||||
#include <gtsam/discrete/DiscreteFactor.h>
|
#include <gtsam/discrete/DiscreteFactor.h>
|
||||||
|
#include <gtsam_unstable/dllexport.h>
|
||||||
|
|
||||||
#include <boost/assign.hpp>
|
#include <boost/assign.hpp>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -30,36 +31,26 @@ namespace gtsam {
|
||||||
* The most general one is the derived DecisionTreeFactor
|
* The most general one is the derived DecisionTreeFactor
|
||||||
*/
|
*/
|
||||||
class Constraint : public DiscreteFactor {
|
class Constraint : public DiscreteFactor {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<Constraint> shared_ptr;
|
typedef boost::shared_ptr<Constraint> shared_ptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Construct n-way factor
|
/// Construct n-way factor
|
||||||
Constraint(const KeyVector& js) :
|
Constraint(const KeyVector& js) : DiscreteFactor(js) {}
|
||||||
DiscreteFactor(js) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct unary factor
|
/// Construct unary factor
|
||||||
Constraint(Key j) :
|
Constraint(Key j) : DiscreteFactor(boost::assign::cref_list_of<1>(j)) {}
|
||||||
DiscreteFactor(boost::assign::cref_list_of<1>(j)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct binary factor
|
/// Construct binary factor
|
||||||
Constraint(Key j1, Key j2) :
|
Constraint(Key j1, Key j2)
|
||||||
DiscreteFactor(boost::assign::cref_list_of<2>(j1)(j2)) {
|
: DiscreteFactor(boost::assign::cref_list_of<2>(j1)(j2)) {}
|
||||||
}
|
|
||||||
|
|
||||||
/// construct from container
|
/// construct from container
|
||||||
template <class KeyIterator>
|
template <class KeyIterator>
|
||||||
Constraint(KeyIterator beginKey, KeyIterator endKey) :
|
Constraint(KeyIterator beginKey, KeyIterator endKey)
|
||||||
DiscreteFactor(beginKey, endKey) {
|
: DiscreteFactor(beginKey, endKey) {}
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @name Standard Constructors
|
/// @name Standard Constructors
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
@ -78,12 +69,12 @@ namespace gtsam {
|
||||||
* @param j domain to be checked
|
* @param j domain to be checked
|
||||||
* @param domains all other domains
|
* @param domains all other domains
|
||||||
*/
|
*/
|
||||||
virtual bool ensureArcConsistency(size_t j, std::vector<Domain>& domains) const = 0;
|
virtual bool ensureArcConsistency(size_t j,
|
||||||
|
std::vector<Domain>& domains) const = 0;
|
||||||
|
|
||||||
/// Partially apply known values
|
/// Partially apply known values
|
||||||
virtual shared_ptr partiallyApply(const Values&) const = 0;
|
virtual shared_ptr partiallyApply(const Values&) const = 0;
|
||||||
|
|
||||||
|
|
||||||
/// Partially apply known values, domain version
|
/// Partially apply known values, domain version
|
||||||
virtual shared_ptr partiallyApply(const std::vector<Domain>&) const = 0;
|
virtual shared_ptr partiallyApply(const std::vector<Domain>&) const = 0;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/Domain.h>
|
|
||||||
#include <gtsam/discrete/DecisionTreeFactor.h>
|
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
|
#include <gtsam/discrete/DecisionTreeFactor.h>
|
||||||
|
#include <gtsam_unstable/discrete/Domain.h>
|
||||||
|
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -15,8 +16,7 @@ namespace gtsam {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Domain::print(const string& s,
|
void Domain::print(const string& s, const KeyFormatter& formatter) const {
|
||||||
const KeyFormatter& formatter) const {
|
|
||||||
// cout << s << ": Domain on " << formatter(keys_[0]) << " (j=" <<
|
// cout << s << ": Domain on " << formatter(keys_[0]) << " (j=" <<
|
||||||
// formatter(keys_[0]) << ") with values";
|
// formatter(keys_[0]) << ") with values";
|
||||||
// for (size_t v: values_) cout << " " << v;
|
// for (size_t v: values_) cout << " " << v;
|
||||||
|
@ -34,8 +34,7 @@ namespace gtsam {
|
||||||
DiscreteKeys keys;
|
DiscreteKeys keys;
|
||||||
keys += DiscreteKey(keys_[0], cardinality_);
|
keys += DiscreteKey(keys_[0], cardinality_);
|
||||||
vector<double> table;
|
vector<double> table;
|
||||||
for (size_t i1 = 0; i1 < cardinality_; ++i1)
|
for (size_t i1 = 0; i1 < cardinality_; ++i1) table.push_back(contains(i1));
|
||||||
table.push_back(contains(i1));
|
|
||||||
DecisionTreeFactor converted(keys, table);
|
DecisionTreeFactor converted(keys, table);
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
|
@ -64,8 +63,7 @@ namespace gtsam {
|
||||||
// for all connected domains
|
// for all connected domains
|
||||||
for (Key k : keys)
|
for (Key k : keys)
|
||||||
// if any domain contains the value we cannot make this domain singleton
|
// if any domain contains the value we cannot make this domain singleton
|
||||||
if (k!=j && domains[k].contains(value))
|
if (k != j && domains[k].contains(value)) goto found;
|
||||||
goto found;
|
|
||||||
values_.clear();
|
values_.clear();
|
||||||
values_.insert(value);
|
values_.insert(value);
|
||||||
return true; // we changed it
|
return true; // we changed it
|
||||||
|
@ -75,11 +73,10 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Constraint::shared_ptr Domain::partiallyApply(
|
Constraint::shared_ptr Domain::partiallyApply(const Values& values) const {
|
||||||
const Values& values) const {
|
|
||||||
Values::const_iterator it = values.find(keys_[0]);
|
Values::const_iterator it = values.find(keys_[0]);
|
||||||
if (it != values.end() && !contains(it->second)) throw runtime_error(
|
if (it != values.end() && !contains(it->second))
|
||||||
"Domain::partiallyApply: unsatisfiable");
|
throw runtime_error("Domain::partiallyApply: unsatisfiable");
|
||||||
return boost::make_shared<Domain>(*this);
|
return boost::make_shared<Domain>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,8 +84,8 @@ namespace gtsam {
|
||||||
Constraint::shared_ptr Domain::partiallyApply(
|
Constraint::shared_ptr Domain::partiallyApply(
|
||||||
const vector<Domain>& domains) const {
|
const vector<Domain>& domains) const {
|
||||||
const Domain& Dk = domains[keys_[0]];
|
const Domain& Dk = domains[keys_[0]];
|
||||||
if (Dk.isSingleton() && !contains(*Dk.begin())) throw runtime_error(
|
if (Dk.isSingleton() && !contains(*Dk.begin()))
|
||||||
"Domain::partiallyApply: unsatisfiable");
|
throw runtime_error("Domain::partiallyApply: unsatisfiable");
|
||||||
return boost::make_shared<Domain>(Dk);
|
return boost::make_shared<Domain>(Dk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/Constraint.h>
|
|
||||||
#include <gtsam/discrete/DiscreteKey.h>
|
#include <gtsam/discrete/DiscreteKey.h>
|
||||||
|
#include <gtsam_unstable/discrete/Constraint.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
@ -16,58 +16,44 @@ namespace gtsam {
|
||||||
* Domain restriction constraint
|
* Domain restriction constraint
|
||||||
*/
|
*/
|
||||||
class GTSAM_UNSTABLE_EXPORT Domain : public Constraint {
|
class GTSAM_UNSTABLE_EXPORT Domain : public Constraint {
|
||||||
|
|
||||||
size_t cardinality_; /// Cardinality
|
size_t cardinality_; /// Cardinality
|
||||||
std::set<size_t> values_; /// allowed values
|
std::set<size_t> values_; /// allowed values
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<Domain> shared_ptr;
|
typedef boost::shared_ptr<Domain> shared_ptr;
|
||||||
|
|
||||||
// Constructor on Discrete Key initializes an "all-allowed" domain
|
// Constructor on Discrete Key initializes an "all-allowed" domain
|
||||||
Domain(const DiscreteKey& dkey) :
|
Domain(const DiscreteKey& dkey)
|
||||||
Constraint(dkey.first), cardinality_(dkey.second) {
|
: Constraint(dkey.first), cardinality_(dkey.second) {
|
||||||
for (size_t v = 0; v < cardinality_; v++)
|
for (size_t v = 0; v < cardinality_; v++) values_.insert(v);
|
||||||
values_.insert(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor on Discrete Key with single allowed value
|
// Constructor on Discrete Key with single allowed value
|
||||||
// Consider SingleValue constraint
|
// Consider SingleValue constraint
|
||||||
Domain(const DiscreteKey& dkey, size_t v) :
|
Domain(const DiscreteKey& dkey, size_t v)
|
||||||
Constraint(dkey.first), cardinality_(dkey.second) {
|
: Constraint(dkey.first), cardinality_(dkey.second) {
|
||||||
values_.insert(v);
|
values_.insert(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Domain(const Domain& other) :
|
Domain(const Domain& other)
|
||||||
Constraint(other.keys_[0]), values_(other.values_) {
|
: Constraint(other.keys_[0]), values_(other.values_) {}
|
||||||
}
|
|
||||||
|
|
||||||
/// insert a value, non const :-(
|
/// insert a value, non const :-(
|
||||||
void insert(size_t value) {
|
void insert(size_t value) { values_.insert(value); }
|
||||||
values_.insert(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// erase a value, non const :-(
|
/// erase a value, non const :-(
|
||||||
void erase(size_t value) {
|
void erase(size_t value) { values_.erase(value); }
|
||||||
values_.erase(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nrValues() const {
|
size_t nrValues() const { return values_.size(); }
|
||||||
return values_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSingleton() const {
|
bool isSingleton() const { return nrValues() == 1; }
|
||||||
return nrValues() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t firstValue() const {
|
size_t firstValue() const { return *values_.begin(); }
|
||||||
return *values_.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// print
|
// print
|
||||||
void print(const std::string& s = "",
|
void print(const std::string& s = "", const KeyFormatter& formatter =
|
||||||
const KeyFormatter& formatter = DefaultKeyFormatter) const override;
|
DefaultKeyFormatter) const override;
|
||||||
|
|
||||||
/// equals
|
/// equals
|
||||||
bool equals(const DiscreteFactor& other, double tol) const override {
|
bool equals(const DiscreteFactor& other, double tol) const override {
|
||||||
|
@ -79,9 +65,7 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains(size_t value) const {
|
bool contains(size_t value) const { return values_.count(value) > 0; }
|
||||||
return values_.count(value)>0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate value
|
/// Calculate value
|
||||||
double operator()(const Values& values) const override;
|
double operator()(const Values& values) const override;
|
||||||
|
@ -97,11 +81,13 @@ namespace gtsam {
|
||||||
* @param j domain to be checked
|
* @param j domain to be checked
|
||||||
* @param domains all other domains
|
* @param domains all other domains
|
||||||
*/
|
*/
|
||||||
bool ensureArcConsistency(size_t j, std::vector<Domain>& domains) const override;
|
bool ensureArcConsistency(size_t j,
|
||||||
|
std::vector<Domain>& domains) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for a value in domain that does not occur in any other connected domain.
|
* Check for a value in domain that does not occur in any other connected
|
||||||
* If found, we make this a singleton... Called in AllDiff::ensureArcConsistency
|
* domain. If found, we make this a singleton... Called in
|
||||||
|
* AllDiff::ensureArcConsistency
|
||||||
* @param keys connected domains through alldiff
|
* @param keys connected domains through alldiff
|
||||||
*/
|
*/
|
||||||
bool checkAllDiff(const KeyVector keys, std::vector<Domain>& domains);
|
bool checkAllDiff(const KeyVector keys, std::vector<Domain>& domains);
|
||||||
|
|
|
@ -5,24 +5,22 @@
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/Scheduler.h>
|
|
||||||
#include <gtsam/discrete/DiscreteFactorGraph.h>
|
|
||||||
#include <gtsam/base/debug.h>
|
#include <gtsam/base/debug.h>
|
||||||
#include <gtsam/base/timing.h>
|
#include <gtsam/base/timing.h>
|
||||||
|
#include <gtsam/discrete/DiscreteFactorGraph.h>
|
||||||
|
#include <gtsam_unstable/discrete/Scheduler.h>
|
||||||
|
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Scheduler::Scheduler(size_t maxNrStudents, const string& filename):
|
Scheduler::Scheduler(size_t maxNrStudents, const string& filename)
|
||||||
maxNrStudents_(maxNrStudents)
|
: maxNrStudents_(maxNrStudents) {
|
||||||
{
|
|
||||||
typedef boost::tokenizer<boost::escaped_list_separator<char> > Tokenizer;
|
typedef boost::tokenizer<boost::escaped_list_separator<char> > Tokenizer;
|
||||||
|
|
||||||
// open file
|
// open file
|
||||||
|
@ -38,8 +36,7 @@ namespace gtsam {
|
||||||
if (getline(is, line, '\r')) {
|
if (getline(is, line, '\r')) {
|
||||||
Tokenizer tok(line);
|
Tokenizer tok(line);
|
||||||
Tokenizer::iterator it = tok.begin();
|
Tokenizer::iterator it = tok.begin();
|
||||||
for (++it; it != tok.end(); ++it)
|
for (++it; it != tok.end(); ++it) addFaculty(*it);
|
||||||
addFaculty(*it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for all remaining lines
|
// for all remaining lines
|
||||||
|
@ -50,16 +47,15 @@ namespace gtsam {
|
||||||
Tokenizer::iterator it = tok.begin();
|
Tokenizer::iterator it = tok.begin();
|
||||||
addSlot(*it++); // add slot
|
addSlot(*it++); // add slot
|
||||||
// add availability
|
// add availability
|
||||||
for (; it != tok.end(); ++it)
|
for (; it != tok.end(); ++it) available_ += (it->empty()) ? "0 " : "1 ";
|
||||||
available_ += (it->empty()) ? "0 " : "1 ";
|
|
||||||
available_ += '\n';
|
available_ += '\n';
|
||||||
}
|
}
|
||||||
} // constructor
|
} // constructor
|
||||||
|
|
||||||
/** addStudent has to be called after adding slots and faculty */
|
/** addStudent has to be called after adding slots and faculty */
|
||||||
void Scheduler::addStudent(const string& studentName,
|
void Scheduler::addStudent(const string& studentName, const string& area1,
|
||||||
const string& area1, const string& area2,
|
const string& area2, const string& area3,
|
||||||
const string& area3, const string& advisor) {
|
const string& advisor) {
|
||||||
assert(nrStudents() < maxNrStudents_);
|
assert(nrStudents() < maxNrStudents_);
|
||||||
assert(facultyInArea_.count(area1));
|
assert(facultyInArea_.count(area1));
|
||||||
assert(facultyInArea_.count(area2));
|
assert(facultyInArea_.count(area2));
|
||||||
|
@ -82,7 +78,8 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get key for student and area, 0 is time slot itself */
|
/** get key for student and area, 0 is time slot itself */
|
||||||
const DiscreteKey& Scheduler::key(size_t s, boost::optional<size_t> area) const {
|
const DiscreteKey& Scheduler::key(size_t s,
|
||||||
|
boost::optional<size_t> area) const {
|
||||||
return area ? students_[s].keys_[*area] : students_[s].key_;
|
return area ? students_[s].keys_[*area] : students_[s].key_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +99,8 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add student-specific constraints to the graph */
|
/** Add student-specific constraints to the graph */
|
||||||
void Scheduler::addStudentSpecificConstraints(size_t i, boost::optional<size_t> slot) {
|
void Scheduler::addStudentSpecificConstraints(size_t i,
|
||||||
|
boost::optional<size_t> slot) {
|
||||||
bool debug = ISDEBUG("Scheduler::buildGraph");
|
bool debug = ISDEBUG("Scheduler::buildGraph");
|
||||||
|
|
||||||
assert(i < nrStudents());
|
assert(i < nrStudents());
|
||||||
|
@ -116,7 +114,6 @@ namespace gtsam {
|
||||||
|
|
||||||
// For all areas
|
// For all areas
|
||||||
for (size_t area = 0; area < 3; area++) {
|
for (size_t area = 0; area < 3; area++) {
|
||||||
|
|
||||||
DiscreteKey areaKey = s.keys_[area];
|
DiscreteKey areaKey = s.keys_[area];
|
||||||
const string& areaName = s.areaName_[area];
|
const string& areaName = s.areaName_[area];
|
||||||
|
|
||||||
|
@ -133,7 +130,8 @@ namespace gtsam {
|
||||||
// get all constraints then specialize to slot
|
// get all constraints then specialize to slot
|
||||||
size_t dummyIndex = maxNrStudents_ * 3 + maxNrStudents_;
|
size_t dummyIndex = maxNrStudents_ * 3 + maxNrStudents_;
|
||||||
DiscreteKey dummy(dummyIndex, nrTimeSlots());
|
DiscreteKey dummy(dummyIndex, nrTimeSlots());
|
||||||
Potentials::ADT p(dummy & areaKey, available_); // available_ is Doodle string
|
Potentials::ADT p(dummy & areaKey,
|
||||||
|
available_); // available_ is Doodle string
|
||||||
Potentials::ADT q = p.choose(dummyIndex, *slot);
|
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);
|
||||||
|
@ -147,23 +145,20 @@ namespace gtsam {
|
||||||
addAllDiff(s.keys_[0] & s.keys_[1] & s.keys_[2]);
|
addAllDiff(s.keys_[0] & s.keys_[1] & s.keys_[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Main routine that builds factor graph */
|
/** Main routine that builds factor graph */
|
||||||
void Scheduler::buildGraph(size_t mutexBound) {
|
void Scheduler::buildGraph(size_t mutexBound) {
|
||||||
bool debug = ISDEBUG("Scheduler::buildGraph");
|
bool debug = ISDEBUG("Scheduler::buildGraph");
|
||||||
|
|
||||||
if (debug) cout << "Adding student-specific constraints" << endl;
|
if (debug) cout << "Adding student-specific constraints" << endl;
|
||||||
for (size_t i = 0; i < nrStudents(); i++)
|
for (size_t i = 0; i < nrStudents(); i++) addStudentSpecificConstraints(i);
|
||||||
addStudentSpecificConstraints(i);
|
|
||||||
|
|
||||||
// special constraint for MN
|
// special constraint for MN
|
||||||
if (studentName(0) == "Michael N") CSP::add(studentKey(0),
|
if (studentName(0) == "Michael N")
|
||||||
"0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1");
|
CSP::add(studentKey(0), "0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1");
|
||||||
|
|
||||||
if (!mutexBound) {
|
if (!mutexBound) {
|
||||||
DiscreteKeys dkeys;
|
DiscreteKeys dkeys;
|
||||||
for(const Student& s: students_)
|
for (const Student& s : students_) dkeys.push_back(s.key_);
|
||||||
dkeys.push_back(s.key_);
|
|
||||||
addAllDiff(dkeys);
|
addAllDiff(dkeys);
|
||||||
} else {
|
} else {
|
||||||
if (debug) cout << "Mutex for Students" << endl;
|
if (debug) cout << "Mutex for Students" << endl;
|
||||||
|
@ -180,31 +175,26 @@ namespace gtsam {
|
||||||
/** print */
|
/** print */
|
||||||
void Scheduler::print(const string& s, const KeyFormatter& formatter) const {
|
void Scheduler::print(const string& s, const KeyFormatter& formatter) const {
|
||||||
cout << s << " Faculty:" << endl;
|
cout << s << " Faculty:" << endl;
|
||||||
for(const string& name: facultyName_)
|
for (const string& name : facultyName_) cout << name << '\n';
|
||||||
cout << name << '\n';
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
|
|
||||||
cout << s << " Slots:\n";
|
cout << s << " Slots:\n";
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for(const string& name: slotName_)
|
for (const string& name : slotName_) cout << i++ << " " << name << endl;
|
||||||
cout << i++ << " " << name << endl;
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
|
|
||||||
cout << "Availability:\n" << available_ << '\n';
|
cout << "Availability:\n" << available_ << '\n';
|
||||||
|
|
||||||
cout << s << " Area constraints:\n";
|
cout << s << " Area constraints:\n";
|
||||||
for(const FacultyInArea::value_type& it: facultyInArea_)
|
for (const FacultyInArea::value_type& it : facultyInArea_) {
|
||||||
{
|
|
||||||
cout << setw(12) << it.first << ": ";
|
cout << setw(12) << it.first << ": ";
|
||||||
for(double v: it.second)
|
for (double v : it.second) cout << v << " ";
|
||||||
cout << v << " ";
|
|
||||||
cout << '\n';
|
cout << '\n';
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
|
|
||||||
cout << s << " Students:\n";
|
cout << s << " Students:\n";
|
||||||
for (const Student& student: students_)
|
for (const Student& student : students_) student.print();
|
||||||
student.print();
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
|
|
||||||
CSP::print(s + " Factor graph");
|
CSP::print(s + " Factor graph");
|
||||||
|
@ -240,8 +230,8 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Accumulate faculty stats */
|
/** Accumulate faculty stats */
|
||||||
void Scheduler::accumulateStats(sharedValues assignment, vector<
|
void Scheduler::accumulateStats(sharedValues assignment,
|
||||||
size_t>& stats) const {
|
vector<size_t>& stats) const {
|
||||||
for (size_t s = 0; s < nrStudents(); s++) {
|
for (size_t s = 0; s < nrStudents(); s++) {
|
||||||
Key base = 3 * s;
|
Key base = 3 * s;
|
||||||
for (size_t area = 0; area < 3; area++) {
|
for (size_t area = 0; area < 3; area++) {
|
||||||
|
@ -258,9 +248,9 @@ namespace gtsam {
|
||||||
// TODO: fix this!!
|
// TODO: fix this!!
|
||||||
size_t maxKey = keys().size();
|
size_t maxKey = keys().size();
|
||||||
Ordering defaultKeyOrdering;
|
Ordering defaultKeyOrdering;
|
||||||
for (size_t i = 0; i<maxKey; ++i)
|
for (size_t i = 0; i < maxKey; ++i) defaultKeyOrdering += Key(i);
|
||||||
defaultKeyOrdering += Key(i);
|
DiscreteBayesNet::shared_ptr chordal =
|
||||||
DiscreteBayesNet::shared_ptr chordal = this->eliminateSequential(defaultKeyOrdering);
|
this->eliminateSequential(defaultKeyOrdering);
|
||||||
gttoc(my_eliminate);
|
gttoc(my_eliminate);
|
||||||
return chordal;
|
return chordal;
|
||||||
}
|
}
|
||||||
|
@ -297,6 +287,4 @@ namespace gtsam {
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // gtsam
|
} // namespace gtsam
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,7 @@ namespace gtsam {
|
||||||
* The "area" variables determine which faculty are on his/her committee.
|
* The "area" variables determine which faculty are on his/her committee.
|
||||||
*/
|
*/
|
||||||
class GTSAM_UNSTABLE_EXPORT Scheduler : public CSP {
|
class GTSAM_UNSTABLE_EXPORT Scheduler : public CSP {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Internal data structure for students */
|
/** Internal data structure for students */
|
||||||
struct Student {
|
struct Student {
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
@ -29,15 +27,14 @@ namespace gtsam {
|
||||||
std::vector<DiscreteKey> keys_; // key for areas
|
std::vector<DiscreteKey> keys_; // key for areas
|
||||||
std::vector<std::string> areaName_;
|
std::vector<std::string> areaName_;
|
||||||
std::vector<double> advisor_;
|
std::vector<double> advisor_;
|
||||||
Student(size_t nrFaculty, size_t advisorIndex) :
|
Student(size_t nrFaculty, size_t advisorIndex)
|
||||||
keys_(3), areaName_(3), advisor_(nrFaculty, 1.0) {
|
: keys_(3), areaName_(3), advisor_(nrFaculty, 1.0) {
|
||||||
advisor_[advisorIndex] = 0.0;
|
advisor_[advisorIndex] = 0.0;
|
||||||
}
|
}
|
||||||
void print() const {
|
void print() const {
|
||||||
using std::cout;
|
using std::cout;
|
||||||
cout << name_ << ": ";
|
cout << name_ << ": ";
|
||||||
for (size_t area = 0; area < 3; area++)
|
for (size_t area = 0; area < 3; area++) cout << areaName_[area] << " ";
|
||||||
cout << areaName_[area] << " ";
|
|
||||||
cout << std::endl;
|
cout << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -63,7 +60,6 @@ namespace gtsam {
|
||||||
std::vector<double> slotsAvailable_;
|
std::vector<double> slotsAvailable_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* We need to know the number of students in advance for ordering keys.
|
* We need to know the number of students in advance for ordering keys.
|
||||||
|
@ -79,26 +75,16 @@ namespace gtsam {
|
||||||
facultyName_.push_back(facultyName);
|
facultyName_.push_back(facultyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nrFaculty() const {
|
size_t nrFaculty() const { return facultyName_.size(); }
|
||||||
return facultyName_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** boolean std::string of nrTimeSlots * nrFaculty */
|
/** boolean std::string of nrTimeSlots * nrFaculty */
|
||||||
void setAvailability(const std::string& available) {
|
void setAvailability(const std::string& available) { available_ = available; }
|
||||||
available_ = available;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addSlot(const std::string& slotName) {
|
void addSlot(const std::string& slotName) { slotName_.push_back(slotName); }
|
||||||
slotName_.push_back(slotName);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nrTimeSlots() const {
|
size_t nrTimeSlots() const { return slotName_.size(); }
|
||||||
return slotName_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& slotName(size_t s) const {
|
const std::string& slotName(size_t s) const { return slotName_[s]; }
|
||||||
return slotName_[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** slots available, boolean */
|
/** slots available, boolean */
|
||||||
void setSlotsAvailable(const std::vector<double>& slotsAvailable) {
|
void setSlotsAvailable(const std::vector<double>& slotsAvailable) {
|
||||||
|
@ -107,7 +93,8 @@ namespace gtsam {
|
||||||
|
|
||||||
void addArea(const std::string& facultyName, const std::string& areaName) {
|
void addArea(const std::string& facultyName, const std::string& areaName) {
|
||||||
areaName_.push_back(areaName);
|
areaName_.push_back(areaName);
|
||||||
std::vector<double>& table = facultyInArea_[areaName]; // will create if needed
|
std::vector<double>& table =
|
||||||
|
facultyInArea_[areaName]; // will create if needed
|
||||||
if (table.empty()) table.resize(nrFaculty(), 0);
|
if (table.empty()) table.resize(nrFaculty(), 0);
|
||||||
table[facultyIndex_[facultyName]] = 1;
|
table[facultyIndex_[facultyName]] = 1;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +106,8 @@ namespace gtsam {
|
||||||
Scheduler(size_t maxNrStudents, const std::string& filename);
|
Scheduler(size_t maxNrStudents, const std::string& filename);
|
||||||
|
|
||||||
/** get key for student and area, 0 is time slot itself */
|
/** 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;
|
const DiscreteKey& key(size_t s,
|
||||||
|
boost::optional<size_t> area = boost::none) const;
|
||||||
|
|
||||||
/** addStudent has to be called after adding slots and faculty */
|
/** addStudent has to be called after adding slots and faculty */
|
||||||
void addStudent(const std::string& studentName, const std::string& area1,
|
void addStudent(const std::string& studentName, const std::string& area1,
|
||||||
|
@ -127,16 +115,15 @@ namespace gtsam {
|
||||||
const std::string& advisor);
|
const std::string& advisor);
|
||||||
|
|
||||||
/// current number of students
|
/// current number of students
|
||||||
size_t nrStudents() const {
|
size_t nrStudents() const { return students_.size(); }
|
||||||
return students_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& studentName(size_t i) const;
|
const std::string& studentName(size_t i) const;
|
||||||
const DiscreteKey& studentKey(size_t i) const;
|
const DiscreteKey& studentKey(size_t i) const;
|
||||||
const std::string& studentArea(size_t i, size_t area) const;
|
const std::string& studentArea(size_t i, size_t area) const;
|
||||||
|
|
||||||
/** Add student-specific constraints to the graph */
|
/** Add student-specific constraints to the graph */
|
||||||
void addStudentSpecificConstraints(size_t i, boost::optional<size_t> slot = boost::none);
|
void addStudentSpecificConstraints(
|
||||||
|
size_t i, boost::optional<size_t> slot = boost::none);
|
||||||
|
|
||||||
/** Main routine that builds factor graph */
|
/** Main routine that builds factor graph */
|
||||||
void buildGraph(size_t mutexBound = 7);
|
void buildGraph(size_t mutexBound = 7);
|
||||||
|
@ -170,6 +157,4 @@ namespace gtsam {
|
||||||
|
|
||||||
}; // Scheduler
|
}; // Scheduler
|
||||||
|
|
||||||
} // gtsam
|
} // namespace gtsam
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/SingleValue.h>
|
|
||||||
#include <gtsam_unstable/discrete/Domain.h>
|
|
||||||
#include <gtsam/discrete/DecisionTreeFactor.h>
|
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
|
#include <gtsam/discrete/DecisionTreeFactor.h>
|
||||||
|
#include <gtsam_unstable/discrete/Domain.h>
|
||||||
|
#include <gtsam_unstable/discrete/SingleValue.h>
|
||||||
|
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -16,10 +17,9 @@ namespace gtsam {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void SingleValue::print(const string& s,
|
void SingleValue::print(const string& s, const KeyFormatter& formatter) const {
|
||||||
const KeyFormatter& formatter) const {
|
cout << s << "SingleValue on "
|
||||||
cout << s << "SingleValue on " << "j=" << formatter(keys_[0])
|
<< "j=" << formatter(keys_[0]) << " with value " << value_ << endl;
|
||||||
<< " with value " << value_ << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -32,8 +32,7 @@ namespace gtsam {
|
||||||
DiscreteKeys keys;
|
DiscreteKeys keys;
|
||||||
keys += DiscreteKey(keys_[0], cardinality_);
|
keys += DiscreteKey(keys_[0], cardinality_);
|
||||||
vector<double> table;
|
vector<double> table;
|
||||||
for (size_t i1 = 0; i1 < cardinality_; i1++)
|
for (size_t i1 = 0; i1 < cardinality_; i1++) table.push_back(i1 == value_);
|
||||||
table.push_back(i1 == value_);
|
|
||||||
DecisionTreeFactor converted(keys, table);
|
DecisionTreeFactor converted(keys, table);
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
|
@ -47,8 +46,8 @@ namespace gtsam {
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
bool SingleValue::ensureArcConsistency(size_t j,
|
bool SingleValue::ensureArcConsistency(size_t j,
|
||||||
vector<Domain>& domains) const {
|
vector<Domain>& domains) const {
|
||||||
if (j != keys_[0]) throw invalid_argument(
|
if (j != keys_[0])
|
||||||
"SingleValue check on wrong domain");
|
throw invalid_argument("SingleValue check on wrong domain");
|
||||||
Domain& D = domains[j];
|
Domain& D = domains[j];
|
||||||
if (D.isSingleton()) {
|
if (D.isSingleton()) {
|
||||||
if (D.firstValue() != value_) throw runtime_error("Unsatisfiable");
|
if (D.firstValue() != value_) throw runtime_error("Unsatisfiable");
|
||||||
|
@ -61,8 +60,8 @@ namespace gtsam {
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Constraint::shared_ptr SingleValue::partiallyApply(const Values& values) const {
|
Constraint::shared_ptr SingleValue::partiallyApply(const Values& values) const {
|
||||||
Values::const_iterator it = values.find(keys_[0]);
|
Values::const_iterator it = values.find(keys_[0]);
|
||||||
if (it != values.end() && it->second != value_) throw runtime_error(
|
if (it != values.end() && it->second != value_)
|
||||||
"SingleValue::partiallyApply: unsatisfiable");
|
throw runtime_error("SingleValue::partiallyApply: unsatisfiable");
|
||||||
return boost::make_shared<SingleValue>(keys_[0], cardinality_, value_);
|
return boost::make_shared<SingleValue>(keys_[0], cardinality_, value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +69,8 @@ namespace gtsam {
|
||||||
Constraint::shared_ptr SingleValue::partiallyApply(
|
Constraint::shared_ptr SingleValue::partiallyApply(
|
||||||
const vector<Domain>& domains) const {
|
const vector<Domain>& domains) const {
|
||||||
const Domain& Dk = domains[keys_[0]];
|
const Domain& Dk = domains[keys_[0]];
|
||||||
if (Dk.isSingleton() && !Dk.contains(value_)) throw runtime_error(
|
if (Dk.isSingleton() && !Dk.contains(value_))
|
||||||
"SingleValue::partiallyApply: unsatisfiable");
|
throw runtime_error("SingleValue::partiallyApply: unsatisfiable");
|
||||||
return boost::make_shared<SingleValue>(discreteKey(), value_);
|
return boost::make_shared<SingleValue>(discreteKey(), value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/Constraint.h>
|
|
||||||
#include <gtsam/discrete/DiscreteKey.h>
|
#include <gtsam/discrete/DiscreteKey.h>
|
||||||
|
#include <gtsam_unstable/discrete/Constraint.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ namespace gtsam {
|
||||||
* SingleValue constraint
|
* SingleValue constraint
|
||||||
*/
|
*/
|
||||||
class GTSAM_UNSTABLE_EXPORT SingleValue : public Constraint {
|
class GTSAM_UNSTABLE_EXPORT SingleValue : public Constraint {
|
||||||
|
|
||||||
/// Number of values
|
/// Number of values
|
||||||
size_t cardinality_;
|
size_t cardinality_;
|
||||||
|
|
||||||
|
@ -28,22 +27,19 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<SingleValue> shared_ptr;
|
typedef boost::shared_ptr<SingleValue> shared_ptr;
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
SingleValue(Key key, size_t n, size_t value) :
|
SingleValue(Key key, size_t n, size_t value)
|
||||||
Constraint(key), cardinality_(n), value_(value) {
|
: Constraint(key), cardinality_(n), value_(value) {}
|
||||||
}
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
SingleValue(const DiscreteKey& dkey, size_t value) :
|
SingleValue(const DiscreteKey& dkey, size_t value)
|
||||||
Constraint(dkey.first), cardinality_(dkey.second), value_(value) {
|
: Constraint(dkey.first), cardinality_(dkey.second), value_(value) {}
|
||||||
}
|
|
||||||
|
|
||||||
// print
|
// print
|
||||||
void print(const std::string& s = "",
|
void print(const std::string& s = "", const KeyFormatter& formatter =
|
||||||
const KeyFormatter& formatter = DefaultKeyFormatter) const override;
|
DefaultKeyFormatter) const override;
|
||||||
|
|
||||||
/// equals
|
/// equals
|
||||||
bool equals(const DiscreteFactor& other, double tol) const override {
|
bool equals(const DiscreteFactor& other, double tol) const override {
|
||||||
|
@ -69,7 +65,8 @@ namespace gtsam {
|
||||||
* @param j domain to be checked
|
* @param j domain to be checked
|
||||||
* @param domains all other domains
|
* @param domains all other domains
|
||||||
*/
|
*/
|
||||||
bool ensureArcConsistency(size_t j, std::vector<Domain>& domains) const override;
|
bool ensureArcConsistency(size_t j,
|
||||||
|
std::vector<Domain>& domains) const override;
|
||||||
|
|
||||||
/// Partially apply known values
|
/// Partially apply known values
|
||||||
Constraint::shared_ptr partiallyApply(const Values& values) const override;
|
Constraint::shared_ptr partiallyApply(const Values& values) const override;
|
||||||
|
|
|
@ -7,21 +7,23 @@
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/CSP.h>
|
#include <gtsam_unstable/discrete/CSP.h>
|
||||||
#include <gtsam_unstable/discrete/Domain.h>
|
#include <gtsam_unstable/discrete/Domain.h>
|
||||||
|
|
||||||
#include <boost/assign/std/map.hpp>
|
#include <boost/assign/std/map.hpp>
|
||||||
using boost::assign::insert;
|
using boost::assign::insert;
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( BinaryAllDif, allInOne)
|
TEST_UNSAFE(BinaryAllDif, allInOne) {
|
||||||
{
|
|
||||||
// Create keys and ordering
|
// Create keys and ordering
|
||||||
size_t nrColors = 2;
|
size_t nrColors = 2;
|
||||||
// DiscreteKey ID("Idaho", nrColors), UT("Utah", nrColors), AZ("Arizona", nrColors);
|
// DiscreteKey ID("Idaho", nrColors), UT("Utah", nrColors), AZ("Arizona",
|
||||||
|
// nrColors);
|
||||||
DiscreteKey ID(0, nrColors), UT(2, nrColors), AZ(1, nrColors);
|
DiscreteKey ID(0, nrColors), UT(2, nrColors), AZ(1, nrColors);
|
||||||
|
|
||||||
// Check construction and conversion
|
// Check construction and conversion
|
||||||
|
@ -40,8 +42,7 @@ TEST_UNSAFE( BinaryAllDif, allInOne)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( CSP, allInOne)
|
TEST_UNSAFE(CSP, allInOne) {
|
||||||
{
|
|
||||||
// Create keys and ordering
|
// Create keys and ordering
|
||||||
size_t nrColors = 2;
|
size_t nrColors = 2;
|
||||||
DiscreteKey ID(0, nrColors), UT(2, nrColors), AZ(1, nrColors);
|
DiscreteKey ID(0, nrColors), UT(2, nrColors), AZ(1, nrColors);
|
||||||
|
@ -80,15 +81,15 @@ TEST_UNSAFE( CSP, allInOne)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( CSP, WesternUS)
|
TEST_UNSAFE(CSP, WesternUS) {
|
||||||
{
|
|
||||||
// Create keys
|
// Create keys
|
||||||
size_t nrColors = 4;
|
size_t nrColors = 4;
|
||||||
DiscreteKey
|
DiscreteKey
|
||||||
// Create ordering according to example in ND-CSP.lyx
|
// Create ordering according to example in ND-CSP.lyx
|
||||||
WA(0, nrColors), OR(3, nrColors), CA(1, nrColors),NV(2, nrColors),
|
WA(0, nrColors),
|
||||||
ID(8, nrColors), UT(9, nrColors), AZ(10, nrColors),
|
OR(3, nrColors), CA(1, nrColors), NV(2, nrColors), ID(8, nrColors),
|
||||||
MT(4, nrColors), WY(5, nrColors), CO(7, nrColors), NM(6, nrColors);
|
UT(9, nrColors), AZ(10, nrColors), MT(4, nrColors), WY(5, nrColors),
|
||||||
|
CO(7, nrColors), NM(6, nrColors);
|
||||||
|
|
||||||
// Create the CSP
|
// Create the CSP
|
||||||
CSP csp;
|
CSP csp;
|
||||||
|
@ -117,14 +118,14 @@ TEST_UNSAFE( CSP, WesternUS)
|
||||||
|
|
||||||
// Solve
|
// Solve
|
||||||
Ordering ordering;
|
Ordering ordering;
|
||||||
ordering += Key(0),Key(1),Key(2),Key(3),Key(4),Key(5),Key(6),Key(7),Key(8),Key(9),Key(10);
|
ordering += Key(0), Key(1), Key(2), Key(3), Key(4), Key(5), Key(6), Key(7),
|
||||||
|
Key(8), Key(9), Key(10);
|
||||||
CSP::sharedValues mpe = csp.optimalAssignment(ordering);
|
CSP::sharedValues mpe = csp.optimalAssignment(ordering);
|
||||||
// GTSAM_PRINT(*mpe);
|
// GTSAM_PRINT(*mpe);
|
||||||
CSP::Values expected;
|
CSP::Values expected;
|
||||||
insert(expected)
|
insert(expected)(WA.first, 1)(CA.first, 1)(NV.first, 3)(OR.first, 0)(
|
||||||
(WA.first,1)(CA.first,1)(NV.first,3)(OR.first,0)
|
MT.first, 1)(WY.first, 0)(NM.first, 3)(CO.first, 2)(ID.first, 2)(
|
||||||
(MT.first,1)(WY.first,0)(NM.first,3)(CO.first,2)
|
UT.first, 1)(AZ.first, 0);
|
||||||
(ID.first,2)(UT.first,1)(AZ.first,0);
|
|
||||||
|
|
||||||
// TODO: Fix me! mpe result seems to be right. (See the printing)
|
// TODO: Fix me! mpe result seems to be right. (See the printing)
|
||||||
// It has the same prob as the expected solution.
|
// It has the same prob as the expected solution.
|
||||||
|
@ -142,8 +143,7 @@ TEST_UNSAFE( CSP, WesternUS)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( CSP, AllDiff)
|
TEST_UNSAFE(CSP, AllDiff) {
|
||||||
{
|
|
||||||
// Create keys and ordering
|
// Create keys and ordering
|
||||||
size_t nrColors = 3;
|
size_t nrColors = 3;
|
||||||
DiscreteKey ID(0, nrColors), UT(2, nrColors), AZ(1, nrColors);
|
DiscreteKey ID(0, nrColors), UT(2, nrColors), AZ(1, nrColors);
|
||||||
|
@ -166,7 +166,8 @@ TEST_UNSAFE( CSP, AllDiff)
|
||||||
DecisionTreeFactor actual = alldiff.toDecisionTreeFactor();
|
DecisionTreeFactor actual = alldiff.toDecisionTreeFactor();
|
||||||
// GTSAM_PRINT(actual);
|
// GTSAM_PRINT(actual);
|
||||||
// actual.dot("actual");
|
// actual.dot("actual");
|
||||||
DecisionTreeFactor f2(ID & AZ & UT,
|
DecisionTreeFactor f2(
|
||||||
|
ID & AZ & UT,
|
||||||
"0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0");
|
"0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0");
|
||||||
EXPECT(assert_equal(f2, actual));
|
EXPECT(assert_equal(f2, actual));
|
||||||
|
|
||||||
|
@ -229,4 +230,3 @@ int main() {
|
||||||
return TestRegistry::runAllTests(tr);
|
return TestRegistry::runAllTests(tr);
|
||||||
}
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,15 @@
|
||||||
* @date Oct 11, 2013
|
* @date Oct 11, 2013
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam/inference/VariableIndex.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <gtsam/discrete/DecisionTreeFactor.h>
|
#include <gtsam/discrete/DecisionTreeFactor.h>
|
||||||
#include <gtsam/discrete/DiscreteFactorGraph.h>
|
#include <gtsam/discrete/DiscreteFactorGraph.h>
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <gtsam/inference/VariableIndex.h>
|
||||||
#include <boost/range/adaptor/map.hpp>
|
|
||||||
#include <boost/assign/list_of.hpp>
|
#include <boost/assign/list_of.hpp>
|
||||||
#include <iostream>
|
#include <boost/range/adaptor/map.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
@ -23,11 +24,12 @@ using namespace gtsam;
|
||||||
* Loopy belief solver for graphs with only binary and unary factors
|
* Loopy belief solver for graphs with only binary and unary factors
|
||||||
*/
|
*/
|
||||||
class LoopyBelief {
|
class LoopyBelief {
|
||||||
|
|
||||||
/** Star graph struct for each node, containing
|
/** Star graph struct for each node, containing
|
||||||
* - the star graph itself
|
* - the star graph itself
|
||||||
* - the product of original unary factors so we don't have to recompute it later, and
|
* - the product of original unary factors so we don't have to recompute it
|
||||||
* - the factor indices of the corrected belief factors of the neighboring nodes
|
* later, and
|
||||||
|
* - the factor indices of the corrected belief factors of the neighboring
|
||||||
|
* nodes
|
||||||
*/
|
*/
|
||||||
typedef std::map<Key, size_t> CorrectedBeliefIndices;
|
typedef std::map<Key, size_t> CorrectedBeliefIndices;
|
||||||
struct StarGraph {
|
struct StarGraph {
|
||||||
|
@ -37,10 +39,11 @@ class LoopyBelief {
|
||||||
VariableIndex varIndex_;
|
VariableIndex varIndex_;
|
||||||
StarGraph(const DiscreteFactorGraph::shared_ptr& _star,
|
StarGraph(const DiscreteFactorGraph::shared_ptr& _star,
|
||||||
const CorrectedBeliefIndices& _beliefIndices,
|
const CorrectedBeliefIndices& _beliefIndices,
|
||||||
const DecisionTreeFactor::shared_ptr& _unary) :
|
const DecisionTreeFactor::shared_ptr& _unary)
|
||||||
star(_star), correctedBeliefIndices(_beliefIndices), unary(_unary), varIndex_(
|
: star(_star),
|
||||||
*_star) {
|
correctedBeliefIndices(_beliefIndices),
|
||||||
}
|
unary(_unary),
|
||||||
|
varIndex_(*_star) {}
|
||||||
|
|
||||||
void print(const std::string& s = "") const {
|
void print(const std::string& s = "") const {
|
||||||
cout << s << ":" << endl;
|
cout << s << ":" << endl;
|
||||||
|
@ -49,8 +52,7 @@ class LoopyBelief {
|
||||||
cout << "Belief factor index for " << key << ": "
|
cout << "Belief factor index for " << key << ": "
|
||||||
<< correctedBeliefIndices.at(key) << endl;
|
<< correctedBeliefIndices.at(key) << endl;
|
||||||
}
|
}
|
||||||
if (unary)
|
if (unary) unary->print("Unary: ");
|
||||||
unary->print("Unary: ");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,13 +61,13 @@ class LoopyBelief {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor
|
/** Constructor
|
||||||
* Need all discrete keys to access node's cardinality for creating belief factors
|
* Need all discrete keys to access node's cardinality for creating belief
|
||||||
|
* factors
|
||||||
* TODO: so troublesome!!
|
* TODO: so troublesome!!
|
||||||
*/
|
*/
|
||||||
LoopyBelief(const DiscreteFactorGraph& graph,
|
LoopyBelief(const DiscreteFactorGraph& graph,
|
||||||
const std::map<Key, DiscreteKey>& allDiscreteKeys) :
|
const std::map<Key, DiscreteKey>& allDiscreteKeys)
|
||||||
starGraphs_(buildStarGraphs(graph, allDiscreteKeys)) {
|
: starGraphs_(buildStarGraphs(graph, allDiscreteKeys)) {}
|
||||||
}
|
|
||||||
|
|
||||||
/// print
|
/// print
|
||||||
void print(const std::string& s = "") const {
|
void print(const std::string& s = "") const {
|
||||||
|
@ -79,7 +81,8 @@ public:
|
||||||
DiscreteFactorGraph::shared_ptr iterate(
|
DiscreteFactorGraph::shared_ptr iterate(
|
||||||
const std::map<Key, DiscreteKey>& allDiscreteKeys) {
|
const std::map<Key, DiscreteKey>& allDiscreteKeys) {
|
||||||
static const bool debug = false;
|
static const bool debug = false;
|
||||||
static DiscreteConditional::shared_ptr dummyCond; // unused by-product of elimination
|
static DiscreteConditional::shared_ptr
|
||||||
|
dummyCond; // unused by-product of elimination
|
||||||
DiscreteFactorGraph::shared_ptr beliefs(new DiscreteFactorGraph());
|
DiscreteFactorGraph::shared_ptr beliefs(new DiscreteFactorGraph());
|
||||||
std::map<Key, std::map<Key, DiscreteFactor::shared_ptr> > allMessages;
|
std::map<Key, std::map<Key, DiscreteFactor::shared_ptr> > allMessages;
|
||||||
// Eliminate each star graph
|
// Eliminate each star graph
|
||||||
|
@ -92,15 +95,16 @@ public:
|
||||||
std::map<Key, DiscreteFactor::shared_ptr> messages;
|
std::map<Key, DiscreteFactor::shared_ptr> messages;
|
||||||
|
|
||||||
// eliminate each neighbor in this star graph one by one
|
// eliminate each neighbor in this star graph one by one
|
||||||
for(Key neighbor: starGraphs_.at(key).correctedBeliefIndices | boost::adaptors::map_keys) {
|
for (Key neighbor : starGraphs_.at(key).correctedBeliefIndices |
|
||||||
|
boost::adaptors::map_keys) {
|
||||||
DiscreteFactorGraph subGraph;
|
DiscreteFactorGraph subGraph;
|
||||||
for (size_t factor : starGraphs_.at(key).varIndex_[neighbor]) {
|
for (size_t factor : starGraphs_.at(key).varIndex_[neighbor]) {
|
||||||
subGraph.push_back(starGraphs_.at(key).star->at(factor));
|
subGraph.push_back(starGraphs_.at(key).star->at(factor));
|
||||||
}
|
}
|
||||||
if (debug) subGraph.print("------- Subgraph:");
|
if (debug) subGraph.print("------- Subgraph:");
|
||||||
DiscreteFactor::shared_ptr message;
|
DiscreteFactor::shared_ptr message;
|
||||||
boost::tie(dummyCond, message) = EliminateDiscrete(subGraph,
|
boost::tie(dummyCond, message) =
|
||||||
Ordering(list_of(neighbor)));
|
EliminateDiscrete(subGraph, Ordering(list_of(neighbor)));
|
||||||
// store the new factor into messages
|
// store the new factor into messages
|
||||||
messages.insert(make_pair(neighbor, message));
|
messages.insert(make_pair(neighbor, message));
|
||||||
if (debug) message->print("------- Message: ");
|
if (debug) message->print("------- Message: ");
|
||||||
|
@ -108,14 +112,12 @@ public:
|
||||||
// Belief is the product of all messages and the unary factor
|
// Belief is the product of all messages and the unary factor
|
||||||
// Incorporate new the factor to belief
|
// Incorporate new the factor to belief
|
||||||
if (!beliefAtKey)
|
if (!beliefAtKey)
|
||||||
beliefAtKey = boost::dynamic_pointer_cast<DecisionTreeFactor>(
|
|
||||||
message);
|
|
||||||
else
|
|
||||||
beliefAtKey =
|
beliefAtKey =
|
||||||
boost::make_shared<DecisionTreeFactor>(
|
boost::dynamic_pointer_cast<DecisionTreeFactor>(message);
|
||||||
(*beliefAtKey)
|
else
|
||||||
* (*boost::dynamic_pointer_cast<DecisionTreeFactor>(
|
beliefAtKey = boost::make_shared<DecisionTreeFactor>(
|
||||||
message)));
|
(*beliefAtKey) *
|
||||||
|
(*boost::dynamic_pointer_cast<DecisionTreeFactor>(message)));
|
||||||
}
|
}
|
||||||
if (starGraphs_.at(key).unary)
|
if (starGraphs_.at(key).unary)
|
||||||
beliefAtKey = boost::make_shared<DecisionTreeFactor>(
|
beliefAtKey = boost::make_shared<DecisionTreeFactor>(
|
||||||
|
@ -133,7 +135,8 @@ public:
|
||||||
sumFactorTable = (boost::format("%s %f") % sumFactorTable % sum).str();
|
sumFactorTable = (boost::format("%s %f") % sumFactorTable % sum).str();
|
||||||
DecisionTreeFactor sumFactor(allDiscreteKeys.at(key), sumFactorTable);
|
DecisionTreeFactor sumFactor(allDiscreteKeys.at(key), sumFactorTable);
|
||||||
if (debug) sumFactor.print("denomFactor: ");
|
if (debug) sumFactor.print("denomFactor: ");
|
||||||
beliefAtKey = boost::make_shared<DecisionTreeFactor>((*beliefAtKey) / sumFactor);
|
beliefAtKey =
|
||||||
|
boost::make_shared<DecisionTreeFactor>((*beliefAtKey) / sumFactor);
|
||||||
if (debug) beliefAtKey->print("New belief at key normalized: ");
|
if (debug) beliefAtKey->print("New belief at key normalized: ");
|
||||||
beliefs->push_back(beliefAtKey);
|
beliefs->push_back(beliefAtKey);
|
||||||
allMessages[key] = messages;
|
allMessages[key] = messages;
|
||||||
|
@ -143,15 +146,18 @@ public:
|
||||||
VariableIndex beliefFactors(*beliefs);
|
VariableIndex beliefFactors(*beliefs);
|
||||||
for (Key key : starGraphs_ | boost::adaptors::map_keys) {
|
for (Key key : starGraphs_ | boost::adaptors::map_keys) {
|
||||||
std::map<Key, DiscreteFactor::shared_ptr> messages = allMessages[key];
|
std::map<Key, DiscreteFactor::shared_ptr> messages = allMessages[key];
|
||||||
for(Key neighbor: starGraphs_.at(key).correctedBeliefIndices | boost::adaptors::map_keys) {
|
for (Key neighbor : starGraphs_.at(key).correctedBeliefIndices |
|
||||||
DecisionTreeFactor correctedBelief = (*boost::dynamic_pointer_cast<
|
boost::adaptors::map_keys) {
|
||||||
DecisionTreeFactor>(beliefs->at(beliefFactors[key].front())))
|
DecisionTreeFactor correctedBelief =
|
||||||
/ (*boost::dynamic_pointer_cast<DecisionTreeFactor>(
|
(*boost::dynamic_pointer_cast<DecisionTreeFactor>(
|
||||||
|
beliefs->at(beliefFactors[key].front()))) /
|
||||||
|
(*boost::dynamic_pointer_cast<DecisionTreeFactor>(
|
||||||
messages.at(neighbor)));
|
messages.at(neighbor)));
|
||||||
if (debug) correctedBelief.print("correctedBelief: ");
|
if (debug) correctedBelief.print("correctedBelief: ");
|
||||||
size_t beliefIndex = starGraphs_.at(neighbor).correctedBeliefIndices.at(
|
size_t beliefIndex =
|
||||||
key);
|
starGraphs_.at(neighbor).correctedBeliefIndices.at(key);
|
||||||
starGraphs_.at(neighbor).star->replace(beliefIndex,
|
starGraphs_.at(neighbor).star->replace(
|
||||||
|
beliefIndex,
|
||||||
boost::make_shared<DecisionTreeFactor>(correctedBelief));
|
boost::make_shared<DecisionTreeFactor>(correctedBelief));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +171,8 @@ private:
|
||||||
/**
|
/**
|
||||||
* Build star graphs for each node.
|
* Build star graphs for each node.
|
||||||
*/
|
*/
|
||||||
StarGraphs buildStarGraphs(const DiscreteFactorGraph& graph,
|
StarGraphs buildStarGraphs(
|
||||||
|
const DiscreteFactorGraph& graph,
|
||||||
const std::map<Key, DiscreteKey>& allDiscreteKeys) const {
|
const std::map<Key, DiscreteKey>& allDiscreteKeys) const {
|
||||||
StarGraphs starGraphs;
|
StarGraphs starGraphs;
|
||||||
VariableIndex varIndex(graph); ///< access to all factors of each node
|
VariableIndex varIndex(graph); ///< access to all factors of each node
|
||||||
|
@ -185,8 +192,8 @@ private:
|
||||||
graph.at(factorIndex));
|
graph.at(factorIndex));
|
||||||
else
|
else
|
||||||
prodOfUnaries = boost::make_shared<DecisionTreeFactor>(
|
prodOfUnaries = boost::make_shared<DecisionTreeFactor>(
|
||||||
*prodOfUnaries
|
*prodOfUnaries *
|
||||||
* (*boost::dynamic_pointer_cast<DecisionTreeFactor>(
|
(*boost::dynamic_pointer_cast<DecisionTreeFactor>(
|
||||||
graph.at(factorIndex))));
|
graph.at(factorIndex))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,9 +214,8 @@ private:
|
||||||
DecisionTreeFactor(allDiscreteKeys.at(neighbor), initialBelief));
|
DecisionTreeFactor(allDiscreteKeys.at(neighbor), initialBelief));
|
||||||
correctedBeliefIndices.insert(make_pair(neighbor, star->size() - 1));
|
correctedBeliefIndices.insert(make_pair(neighbor, star->size() - 1));
|
||||||
}
|
}
|
||||||
starGraphs.insert(
|
starGraphs.insert(make_pair(
|
||||||
make_pair(key,
|
key, StarGraph(star, correctedBeliefIndices, prodOfUnaries)));
|
||||||
StarGraph(star, correctedBeliefIndices, prodOfUnaries)));
|
|
||||||
}
|
}
|
||||||
return starGraphs;
|
return starGraphs;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +255,6 @@ TEST_UNSAFE(LoopyBelief, construction) {
|
||||||
DiscreteFactorGraph::shared_ptr beliefs = solver.iterate(allKeys);
|
DiscreteFactorGraph::shared_ptr beliefs = solver.iterate(allKeys);
|
||||||
beliefs->print();
|
beliefs->print();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define ENABLE_TIMING
|
//#define ENABLE_TIMING
|
||||||
#include <gtsam_unstable/discrete/Scheduler.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
#include <gtsam/base/timing.h>
|
#include <gtsam/base/timing.h>
|
||||||
|
#include <gtsam_unstable/discrete/Scheduler.h>
|
||||||
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
|
||||||
|
|
||||||
#include <boost/assign/std/vector.hpp>
|
|
||||||
#include <boost/assign/std/map.hpp>
|
#include <boost/assign/std/map.hpp>
|
||||||
|
#include <boost/assign/std/vector.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
using namespace boost::assign;
|
using namespace boost::assign;
|
||||||
|
@ -22,7 +21,6 @@ using namespace gtsam;
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// Create the expected graph of constraints
|
// Create the expected graph of constraints
|
||||||
DiscreteFactorGraph createExpected() {
|
DiscreteFactorGraph createExpected() {
|
||||||
|
|
||||||
// Start building
|
// Start building
|
||||||
size_t nrFaculty = 4, nrTimeSlots = 3;
|
size_t nrFaculty = 4, nrTimeSlots = 3;
|
||||||
|
|
||||||
|
@ -79,8 +77,7 @@ DiscreteFactorGraph createExpected() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST( schedulingExample, test)
|
TEST(schedulingExample, test) {
|
||||||
{
|
|
||||||
Scheduler s(2);
|
Scheduler s(2);
|
||||||
|
|
||||||
// add faculty
|
// add faculty
|
||||||
|
@ -146,8 +143,7 @@ TEST( schedulingExample, test)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST( schedulingExample, smallFromFile)
|
TEST(schedulingExample, smallFromFile) {
|
||||||
{
|
|
||||||
string path(TOPSRCDIR "/gtsam_unstable/discrete/examples/");
|
string path(TOPSRCDIR "/gtsam_unstable/discrete/examples/");
|
||||||
Scheduler s(2, path + "small.csv");
|
Scheduler s(2, path + "small.csv");
|
||||||
|
|
||||||
|
@ -179,4 +175,3 @@ int main() {
|
||||||
return TestRegistry::runAllTests(tr);
|
return TestRegistry::runAllTests(tr);
|
||||||
}
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam_unstable/discrete/CSP.h>
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
|
#include <gtsam_unstable/discrete/CSP.h>
|
||||||
|
|
||||||
#include <boost/assign/std/map.hpp>
|
#include <boost/assign/std/map.hpp>
|
||||||
using boost::assign::insert;
|
using boost::assign::insert;
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
@ -19,7 +21,6 @@ using namespace gtsam;
|
||||||
#define PRINT false
|
#define PRINT false
|
||||||
|
|
||||||
class Sudoku : public CSP {
|
class Sudoku : public CSP {
|
||||||
|
|
||||||
/// sudoku size
|
/// sudoku size
|
||||||
size_t n_;
|
size_t n_;
|
||||||
|
|
||||||
|
@ -28,20 +29,16 @@ class Sudoku: public CSP {
|
||||||
std::map<IJ, DiscreteKey> dkeys_;
|
std::map<IJ, DiscreteKey> dkeys_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// return DiscreteKey for cell(i,j)
|
/// return DiscreteKey for cell(i,j)
|
||||||
const DiscreteKey& dkey(size_t i, size_t j) const {
|
const DiscreteKey& dkey(size_t i, size_t j) const {
|
||||||
return dkeys_.at(IJ(i, j));
|
return dkeys_.at(IJ(i, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return Key for cell(i,j)
|
/// return Key for cell(i,j)
|
||||||
Key key(size_t i, size_t j) const {
|
Key key(size_t i, size_t j) const { return dkey(i, j).first; }
|
||||||
return dkey(i, j).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Sudoku(size_t n, ...) :
|
Sudoku(size_t n, ...) : n_(n) {
|
||||||
n_(n) {
|
|
||||||
// Create variables, ordering, and unary constraints
|
// Create variables, ordering, and unary constraints
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, n);
|
va_start(ap, n);
|
||||||
|
@ -63,16 +60,14 @@ public:
|
||||||
// add row constraints
|
// add row constraints
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
DiscreteKeys dkeys;
|
DiscreteKeys dkeys;
|
||||||
for (size_t j = 0; j < n; j++)
|
for (size_t j = 0; j < n; j++) dkeys += dkey(i, j);
|
||||||
dkeys += dkey(i, j);
|
|
||||||
addAllDiff(dkeys);
|
addAllDiff(dkeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add col constraints
|
// add col constraints
|
||||||
for (size_t j = 0; j < n; j++) {
|
for (size_t j = 0; j < n; j++) {
|
||||||
DiscreteKeys dkeys;
|
DiscreteKeys dkeys;
|
||||||
for (size_t i = 0; i < n; i++)
|
for (size_t i = 0; i < n; i++) dkeys += dkey(i, j);
|
||||||
dkeys += dkey(i, j);
|
|
||||||
addAllDiff(dkeys);
|
addAllDiff(dkeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +79,7 @@ public:
|
||||||
// Box I,J
|
// Box I,J
|
||||||
DiscreteKeys dkeys;
|
DiscreteKeys dkeys;
|
||||||
for (size_t i = i0; i < i0 + N; i++)
|
for (size_t i = i0; i < i0 + N; i++)
|
||||||
for (size_t j = j0; j < j0 + N; j++)
|
for (size_t j = j0; j < j0 + N; j++) dkeys += dkey(i, j);
|
||||||
dkeys += dkey(i, j);
|
|
||||||
addAllDiff(dkeys);
|
addAllDiff(dkeys);
|
||||||
j0 += N;
|
j0 += N;
|
||||||
}
|
}
|
||||||
|
@ -109,18 +103,13 @@ public:
|
||||||
DiscreteFactor::sharedValues MPE = optimalAssignment();
|
DiscreteFactor::sharedValues MPE = optimalAssignment();
|
||||||
printAssignment(MPE);
|
printAssignment(MPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( Sudoku, small)
|
TEST_UNSAFE(Sudoku, small) {
|
||||||
{
|
Sudoku csp(4, 1, 0, 0, 4, 0, 0, 0, 0,
|
||||||
Sudoku csp(4,
|
|
||||||
1,0, 0,4,
|
|
||||||
0,0, 0,0,
|
|
||||||
|
|
||||||
4,0, 2,0,
|
4, 0, 2, 0, 0, 1, 0, 0);
|
||||||
0,1, 0,0);
|
|
||||||
|
|
||||||
// Do BP
|
// Do BP
|
||||||
csp.runArcConsistency(4, 10, PRINT);
|
csp.runArcConsistency(4, 10, PRINT);
|
||||||
|
@ -128,30 +117,25 @@ TEST_UNSAFE( Sudoku, small)
|
||||||
// optimize and check
|
// optimize and check
|
||||||
CSP::sharedValues solution = csp.optimalAssignment();
|
CSP::sharedValues solution = csp.optimalAssignment();
|
||||||
CSP::Values expected;
|
CSP::Values expected;
|
||||||
insert(expected)
|
insert(expected)(csp.key(0, 0), 0)(csp.key(0, 1), 1)(csp.key(0, 2), 2)(
|
||||||
(csp.key(0,0), 0)(csp.key(0,1), 1)(csp.key(0,2), 2)(csp.key(0,3), 3)
|
csp.key(0, 3), 3)(csp.key(1, 0), 2)(csp.key(1, 1), 3)(csp.key(1, 2), 0)(
|
||||||
(csp.key(1,0), 2)(csp.key(1,1), 3)(csp.key(1,2), 0)(csp.key(1,3), 1)
|
csp.key(1, 3), 1)(csp.key(2, 0), 3)(csp.key(2, 1), 2)(csp.key(2, 2), 1)(
|
||||||
(csp.key(2,0), 3)(csp.key(2,1), 2)(csp.key(2,2), 1)(csp.key(2,3), 0)
|
csp.key(2, 3), 0)(csp.key(3, 0), 1)(csp.key(3, 1), 0)(csp.key(3, 2), 3)(
|
||||||
(csp.key(3,0), 1)(csp.key(3,1), 0)(csp.key(3,2), 3)(csp.key(3,3), 2);
|
csp.key(3, 3), 2);
|
||||||
EXPECT(assert_equal(expected, *solution));
|
EXPECT(assert_equal(expected, *solution));
|
||||||
// csp.printAssignment(solution);
|
// csp.printAssignment(solution);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( Sudoku, easy)
|
TEST_UNSAFE(Sudoku, easy) {
|
||||||
{
|
Sudoku sudoku(9, 0, 0, 5, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 7, 3, 7, 6,
|
||||||
Sudoku sudoku(9,
|
0, 0, 0, 8, 2, 0, 0,
|
||||||
0,0,5, 0,9,0, 0,0,1,
|
|
||||||
0,0,0, 0,0,2, 0,7,3,
|
|
||||||
7,6,0, 0,0,8, 2,0,0,
|
|
||||||
|
|
||||||
0,1,2, 0,0,9, 0,0,4,
|
0, 1, 2, 0, 0, 9, 0, 0, 4, 0, 0, 0, 2, 0, 3, 0, 0, 0, 3, 0, 0,
|
||||||
0,0,0, 2,0,3, 0,0,0,
|
1, 0, 0, 9, 6, 0,
|
||||||
3,0,0, 1,0,0, 9,6,0,
|
|
||||||
|
|
||||||
0,0,1, 9,0,0, 0,5,8,
|
0, 0, 1, 9, 0, 0, 0, 5, 8, 9, 7, 0, 5, 0, 0, 0, 0, 0, 5, 0, 0,
|
||||||
9,7,0, 5,0,0, 0,0,0,
|
0, 3, 0, 7, 0, 0);
|
||||||
5,0,0, 0,3,0, 7,0,0);
|
|
||||||
|
|
||||||
// Do BP
|
// Do BP
|
||||||
sudoku.runArcConsistency(4, 10, PRINT);
|
sudoku.runArcConsistency(4, 10, PRINT);
|
||||||
|
@ -160,20 +144,15 @@ TEST_UNSAFE( Sudoku, easy)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( Sudoku, extreme)
|
TEST_UNSAFE(Sudoku, extreme) {
|
||||||
{
|
Sudoku sudoku(9, 0, 0, 9, 7, 4, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
|
||||||
Sudoku sudoku(9,
|
0, 1, 0, 9, 0, 0, 0,
|
||||||
0,0,9, 7,4,8, 0,0,0,
|
|
||||||
7,0,0, 0,0,0, 0,0,0,
|
|
||||||
0,2,0, 1,0,9, 0,0,0,
|
|
||||||
|
|
||||||
0,0,7, 0,0,0, 2,4,0,
|
0, 0, 7, 0, 0, 0, 2, 4, 0, 0, 6, 4, 0, 1, 0, 5, 9, 0, 0, 9, 8,
|
||||||
0,6,4, 0,1,0, 5,9,0,
|
0, 0, 0, 3, 0, 0,
|
||||||
0,9,8, 0,0,0, 3,0,0,
|
|
||||||
|
|
||||||
0,0,0, 8,0,3, 0,2,0,
|
0, 0, 0, 8, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
|
||||||
0,0,0, 0,0,0, 0,0,6,
|
2, 7, 5, 9, 0, 0);
|
||||||
0,0,0, 2,7,5, 9,0,0);
|
|
||||||
|
|
||||||
// Do BP
|
// Do BP
|
||||||
sudoku.runArcConsistency(9, 10, PRINT);
|
sudoku.runArcConsistency(9, 10, PRINT);
|
||||||
|
@ -189,20 +168,15 @@ TEST_UNSAFE( Sudoku, extreme)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST_UNSAFE( Sudoku, AJC_3star_Feb8_2012)
|
TEST_UNSAFE(Sudoku, AJC_3star_Feb8_2012) {
|
||||||
{
|
Sudoku sudoku(9, 9, 5, 0, 0, 0, 6, 0, 0, 0, 0, 8, 4, 0, 7, 0, 0, 0, 0, 6, 2,
|
||||||
Sudoku sudoku(9,
|
0, 5, 0, 0, 4, 0, 0,
|
||||||
9,5,0, 0,0,6, 0,0,0,
|
|
||||||
0,8,4, 0,7,0, 0,0,0,
|
|
||||||
6,2,0, 5,0,0, 4,0,0,
|
|
||||||
|
|
||||||
0,0,0, 2,9,0, 6,0,0,
|
0, 0, 0, 2, 9, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2,
|
||||||
0,9,0, 0,0,0, 0,2,0,
|
0, 6, 3, 0, 0, 0,
|
||||||
0,0,2, 0,6,3, 0,0,0,
|
|
||||||
|
|
||||||
0,0,9, 0,0,7, 0,6,8,
|
0, 0, 9, 0, 0, 7, 0, 6, 8, 0, 0, 0, 0, 3, 0, 2, 9, 0, 0, 0, 0,
|
||||||
0,0,0, 0,3,0, 2,9,0,
|
1, 0, 0, 0, 3, 7);
|
||||||
0,0,0, 1,0,0, 0,3,7);
|
|
||||||
|
|
||||||
// Do BP
|
// Do BP
|
||||||
sudoku.runArcConsistency(9, 10, PRINT);
|
sudoku.runArcConsistency(9, 10, PRINT);
|
||||||
|
@ -216,4 +190,3 @@ int main() {
|
||||||
return TestRegistry::runAllTests(tr);
|
return TestRegistry::runAllTests(tr);
|
||||||
}
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue