12 #include <unordered_map> 14 #include <unordered_set> 16 using namespace gtsam;
19 using std::unordered_map;
21 using std::unordered_set;
31 double heuristic()
const {
return (outWeightSum + 1) / (inWeightSum + 1); }
37 const map<MFAS::KeyPair, double>& edgeWeights) {
38 unordered_map<Key, GraphNode>
graph;
40 for (
const auto& edgeWeight : edgeWeights) {
46 const double& weight = edgeWeight.second;
48 Key edgeSource = weight >= 0 ? edge.first : edge.second;
49 Key edgeDest = weight >= 0 ? edge.second : edge.first;
52 graph[edgeDest].inWeightSum +=
std::abs(weight);
53 graph[edgeDest].inNeighbors.insert(edgeSource);
56 graph[edgeSource].outWeightSum +=
std::abs(weight);
57 graph[edgeSource].outNeighbors.insert(edgeDest);
65 for (
const auto& keyNode : graph) {
67 if (keyNode.second.inWeightSum < 1
e-8) {
75 return std::max_element(graph.begin(), graph.end(),
76 [](
const std::pair<Key, GraphNode>& keyNode1,
77 const std::pair<Key, GraphNode>& keyNode2) {
78 return keyNode1.second.heuristic() <
79 keyNode2.second.heuristic();
86 const map<MFAS::KeyPair, double>& edgeWeights) {
88 return edgeWeights.find(
MFAS::KeyPair(key1, key2)) != edgeWeights.end()
95 const map<MFAS::KeyPair, double> edgeWeights,
96 unordered_map<Key, GraphNode>&
graph) {
98 for (
const Key neighbor : graph[node].inNeighbors) {
101 graph[neighbor].outWeightSum -=
103 graph[neighbor].outNeighbors.erase(node);
106 for (
const Key neighbor : graph[node].outNeighbors) {
107 graph[neighbor].inWeightSum -=
absWeightOfEdge(node, neighbor, edgeWeights);
108 graph[neighbor].inNeighbors.erase(node);
115 const Unit3& projectionDirection) {
118 for (
const auto&
measurement : relativeTranslations) {
133 while (!graph.empty()) {
136 ordering.push_back(selection);
147 unordered_map<Key, int> orderingPositions;
148 for (
size_t i = 0;
i < ordering.size();
i++) {
149 orderingPositions[ordering[
i]] =
i;
152 map<KeyPair, double> outlierWeights;
154 for (
const auto& edgeWeight : edgeWeights_) {
156 Key source = edgeWeight.first.first;
157 Key dest = edgeWeight.first.second;
158 if (edgeWeight.second < 0) {
164 if (orderingPositions.at(dest) < orderingPositions.at(source)) {
165 outlierWeights[edgeWeight.first] =
std::abs(edgeWeight.second);
167 outlierWeights[edgeWeight.first] = 0;
170 return outlierWeights;
void removeNodeFromGraph(const Key node, const map< MFAS::KeyPair, double > edgeWeights, unordered_map< Key, GraphNode > &graph)
MFAS class to solve Minimum Feedback Arc Set graph problem.
KeyVector computeOrdering() const
Computes the 1D MFAS ordering of nodes in the graph.
unordered_set< Key > outNeighbors
NonlinearFactorGraph graph
static enum @1107 ordering
MFAS(const std::map< KeyPair, double > &edgeWeights)
Construct from the weighted directed edges between the nodes. Each node is identified by a Key...
Represents a 3D point on a unit sphere.
static Point2 measurement(323.0, 240.0)
const Symbol key1('v', 1)
Array< double, 1, 3 > e(1./3., 0.5, 2.)
double absWeightOfEdge(const Key key1, const Key key2, const map< MFAS::KeyPair, double > &edgeWeights)
unordered_set< Key > inNeighbors
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)
std::map< KeyPair, double > computeOutlierWeights() const
Computes the outlier weights of the graph. We define the outlier weight of a edge to be zero if the e...
std::vector< BinaryMeasurement< Unit3 > > TranslationEdges
std::pair< Key, Key > KeyPair
Key selectNextNodeInOrdering(const unordered_map< Key, GraphNode > &graph)
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
unordered_map< Key, GraphNode > graphFromEdges(const map< MFAS::KeyPair, double > &edgeWeights)
std::uint64_t Key
Integer nonlinear key type.
const Symbol key2('v', 2)