1 #ifndef AI_TOOLBOX_FACTORED_FACTOR_GRAPH_HEADER_FILE
2 #define AI_TOOLBOX_FACTORED_FACTOR_GRAPH_HEADER_FILE
30 template <
typename FactorData>
43 const FactorData &
getData()
const {
return f_; }
48 using FactorIt =
typename FactorList::iterator;
49 using CFactorIt =
typename FactorList::const_iterator;
94 void reset(
size_t variables);
174 void erase(
size_t variable);
264 [&variables](
const FactorIt it){
return it->variables_ == variables; }
268 struct VariableNode {
274 std::vector<VariableNode> variableAdjacencies_;
275 size_t activeVariables_;
278 template <
typename FD>
281 template <
typename FD>
284 template <
typename FD>
286 variableAdjacencies_(other.variableAdjacencies_),
287 activeVariables_(other.activeVariables_)
290 auto oIt = std::begin(other.factorAdjacencies_);
291 while (factorAdjacencies_.size() < other.factorAdjacencies_.size()) {
292 if (factorAdjacenciesPool_.size() > 0) {
293 factorAdjacencies_.splice(std::end(factorAdjacencies_), factorAdjacenciesPool_, std::begin(factorAdjacenciesPool_));
294 factorAdjacencies_.back() = *oIt++;
296 factorAdjacencies_.emplace_back(*oIt++);
305 for (
auto & a : variableAdjacencies_)
309 for (
auto it = factorAdjacencies_.begin(); it != factorAdjacencies_.end(); ++it) {
310 for (
auto a : it->getVariables()) {
311 variableAdjacencies_[a].factors.push_back(it);
316 template <
typename FD>
318 factorAdjacencies_.clear();
320 variableAdjacencies_.clear();
321 variableAdjacencies_.resize(variables);
322 activeVariables_ = variables;
325 template <
typename FD>
327 return variableAdjacencies_[variable].factors;
330 template <
typename FD>
332 return variableAdjacencies_[variable].vNeighbors;
335 template <
typename FD>
337 return factor->variables_;
340 template <
typename FD>
342 return factor->variables_;
345 template <
typename FD>
348 for (
const auto factor : factors)
354 template <
typename FD>
356 const auto found = findFactorByVariables(variableAdjacencies_[variables[0]].factors, variables);
357 if (found != variableAdjacencies_[variables[0]].factors.end())
361 if (!factorAdjacenciesPool_.size()) {
362 factorAdjacencies_.emplace_back(
FactorNode());
363 it = --factorAdjacencies_.end();
365 factorAdjacencies_.splice(std::end(factorAdjacencies_), factorAdjacenciesPool_, std::begin(factorAdjacenciesPool_));
366 it = std::prev(factorAdjacencies_.end());
374 it->variables_ = variables;
375 for (
const auto a : variables) {
376 auto & va = variableAdjacencies_[a];
377 va.factors.push_back(it);
380 const auto mid = va.vNeighbors.size();
381 va.vNeighbors.reserve(mid + variables.size() - 1);
383 for (
size_t i = 0, j = 0; i < variables.size(); ) {
384 if (variables[i] == a) {
386 }
else if (j == mid || variables[i] < va.vNeighbors[j]) {
387 va.vNeighbors.push_back(variables[i]);
390 if (variables[i] == va.vNeighbors[j])
395 std::inplace_merge(std::begin(va.vNeighbors), std::begin(va.vNeighbors)+mid, std::end(va.vNeighbors));
400 template <
typename FD>
402 auto & va = variableAdjacencies_[a];
403 if (!va.active)
return;
405 for (
auto it : va.factors) {
406 for (
const auto variable : it->variables_) {
407 if (variable == a)
continue;
409 auto & factors = variableAdjacencies_[variable].factors;
410 const auto foundIt = std::find(std::begin(factors), std::end(factors), it);
412 assert(foundIt != std::end(factors));
413 factors.erase(foundIt);
415 factorAdjacenciesPool_.splice(std::begin(factorAdjacenciesPool_), factorAdjacencies_, it);
417 for (
const auto aa : va.vNeighbors) {
418 auto & vaa = variableAdjacencies_[aa];
419 vaa.vNeighbors.erase(std::find(std::begin(vaa.vNeighbors), std::end(vaa.vNeighbors), a));
423 va.vNeighbors.clear();
428 template <
typename FD>
430 template <
typename FD>
432 template <
typename FD>
434 template <
typename FD>
436 template <
typename FD>
438 template <
typename FD>
440 template <
typename FD>
442 template <
typename FD>
445 template <
typename FD>
447 if (activeVariables_ == 0)
return 0;
451 while (!variableAdjacencies_[retval].active) ++retval;
455 const auto & vNeighbors = getVariables(retval);
459 bool factorExists =
false;
460 if (vNeighbors.size() > 0) {
461 const auto factorIt = findFactorByVariables(variableAdjacencies_[vNeighbors[0]].factors, vNeighbors);
462 factorExists = factorIt != std::end(variableAdjacencies_[vNeighbors[0]].factors);
465 size_t minCost = F[retval];
466 for (
auto n : vNeighbors)
469 for (
size_t next = retval + 1; next < variableAdjacencies_.size(); ++next) {
470 if (!variableAdjacencies_[next].active)
473 const auto & vNeighbors = getVariables(next);
475 bool newExists =
false;
476 if (vNeighbors.size() > 0) {
477 const auto factorIt = findFactorByVariables(variableAdjacencies_[vNeighbors[0]].factors, vNeighbors);
478 newExists = factorIt != std::end(variableAdjacencies_[vNeighbors[0]].factors);
483 if (!newExists && factorExists)
continue;
486 size_t newCost = F[next];
487 for (
auto n : vNeighbors)
492 if ((newExists && !factorExists) || (newCost < minCost)) {