Ocean
Loading...
Searching...
No Matches
AssignmentSolver.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef OCEAN_CV_DETECTOR_BULLSEYES_ASSIGNMENTSOLVER_H
9#define OCEAN_CV_DETECTOR_BULLSEYES_ASSIGNMENTSOLVER_H
10
12
13#include "ocean/math/Matrix.h"
14
15namespace Ocean
16{
17
18namespace CV
19{
20
21namespace Detector
22{
23
24namespace Bullseyes
25{
26
27/**
28 * This class solves assignment problems using the Hungarian/Kuhn-Munkres algorithm.
29 *
30 * The assignment problem seeks to find an optimal matching between two sets (e.g., workers and jobs)
31 * where each element in one set is assigned to exactly one element in the other set to minimize total cost.
32 *
33 * The solver accepts rectangular cost matrices and handles them by padding to square matrices internally.
34 * All cost values must be non-negative. The algorithm guarantees finding an optimal solution in polynomial time.
35 *
36 * Example usage:
37 * @code
38 * AssignmentSolver::CostMatrix costs(5, 3);
39 * // ... fill costs with non-negative values ...
40 * AssignmentSolver::Assignments assignments;
41 * if (AssignmentSolver::solve(std::move(costs), assignments))
42 * {
43 * // assignments contains optimal (row, column) pairs
44 * }
45 * @endcode
46 *
47 * @ingroup cvdetectorbullseyes
48 */
49class OCEAN_CV_DETECTOR_BULLSEYES_EXPORT AssignmentSolver
50{
51 public:
52
53 /// The type of the cost matrix.
55
56 /// An alias for an index pair.
58
59 /// An alias for a vector of index pairs.
61
62 public:
63
64 /**
65 * Solves the assignment problem for the given cost matrix using the Hungarian/Kuhn-Munkres algorithm.
66 * The algorithm finds an optimal assignment that minimizes the total cost. The cost matrix can be rectangular.
67 * For an NxM matrix, the function will assign min(N,M) pairs such that the sum of their costs is minimized.
68 * @param costMatrix The cost matrix with non-negative values, can be rectangular, will be moved/modified during solving
69 * @param assignments The resulting optimal assignments as pairs of (row, column) indices
70 * @return True if the algorithm succeeded; False if the input matrix is empty or invalid
71 */
72 static bool solve(CostMatrix&& costMatrix, Assignments& assignments);
73
74 protected:
75
76 /**
77 * Performs the initial cost reduction by subtracting row and column minima from the cost matrix.
78 * This step of the Hungarian algorithm creates zeros in the matrix which represent potential assignments.
79 * After this operation, each row and column will have at least one zero.
80 * @param costMatrix The cost matrix to be reduced, will be modified in-place
81 */
82 static void subtractRowAndColumnMinima(CostMatrix& costMatrix);
83
84 /**
85 * Attempts to find an augmenting path starting from a given row using breadth-first search.
86 * An augmenting path alternates between unassigned edges (zeros in the matrix) and assigned edges,
87 * starting and ending at unassigned rows/columns. Finding such a path allows increasing the matching size by one.
88 * @param costMatrix The square cost matrix, must be valid
89 * @param yStart The row index to start searching from, with range [0, matrixSize)
90 * @param yAssignments Row-to-column assignment mapping, will be updated if an augmenting path is found, with invalidIndex() for unassigned rows
91 * @param xAssignments Column-to-row assignment mapping, will be updated if an augmenting path is found, with invalidIndex() for unassigned columns
92 * @param yVisited Tracks visited rows during the search, will be modified, must have size matrixSize, 0 for unvisited, >= 1 for visited
93 * @param xVisited Tracks visited columns during the search, will be modified, must have size matrixSize, 0 for unvisited, >= 1 for visited
94 * @param yParents Tracks parent relationships for path reconstruction, will be modified, must have size matrixSize
95 */
96 static void findAugmentingPath(const CostMatrix& costMatrix, const size_t yStart, Indices32& yAssignments, Indices32& xAssignments, std::vector<uint8_t>& yVisited, std::vector<uint8_t>& xVisited, Indices32& yParents);
97
98 /**
99 * Reduces the cost matrix when no complete assignment can be found with current zeros.
100 * This function implements the matrix adjustment step of the Hungarian algorithm:
101 * it identifies the minimum uncovered element and adjusts the matrix to create new zeros
102 * in positions that may lead to a better assignment in the next iteration.
103 * @param yAssignments Current row-to-column assignment mapping, with invalidIndex() for unassigned rows
104 * @param costMatrix The square cost matrix to be reduced, will be modified in-place
105 * @param yMarked Working array for row marking, will be reinitialized and modified, must have size matrixSize, 0 for unmarked, >= 1 for marked
106 * @param xMarked Working array for column marking, will be reinitialized and modified, must have size matrixSize, 0 for unmarked, >= 1 for marked
107 * @return True on success; False if reduction fails (which should never happen for valid inputs)
108 */
109 static bool reduceCostMatrix(const Indices32& yAssignments, CostMatrix& costMatrix, std::vector<uint8_t>& yMarked, std::vector<uint8_t>& xMarked);
110
111 /**
112 * Returns an invalid index value used as a sentinel for unassigned rows/columns.
113 * @return The invalid index value (Index32(-1))
114 */
115 constexpr static Index32 invalidIndex();
116};
117
119{
120 return Index32(-1);
121}
122
123} // namespace Bullseyes
124
125} // namespace Detector
126
127} // namespace CV
128
129} // namespace Ocean
130
131#endif // OCEAN_CV_DETECTOR_BULLSEYES_ASSIGNMENTSOLVER_H
This class solves assignment problems using the Hungarian/Kuhn-Munkres algorithm.
Definition AssignmentSolver.h:50
static constexpr Index32 invalidIndex()
Returns an invalid index value used as a sentinel for unassigned rows/columns.
Definition AssignmentSolver.h:118
static bool solve(CostMatrix &&costMatrix, Assignments &assignments)
Solves the assignment problem for the given cost matrix using the Hungarian/Kuhn-Munkres algorithm.
IndexPair32 Assignment
An alias for an index pair.
Definition AssignmentSolver.h:57
static void findAugmentingPath(const CostMatrix &costMatrix, const size_t yStart, Indices32 &yAssignments, Indices32 &xAssignments, std::vector< uint8_t > &yVisited, std::vector< uint8_t > &xVisited, Indices32 &yParents)
Attempts to find an augmenting path starting from a given row using breadth-first search.
static void subtractRowAndColumnMinima(CostMatrix &costMatrix)
Performs the initial cost reduction by subtracting row and column minima from the cost matrix.
static bool reduceCostMatrix(const Indices32 &yAssignments, CostMatrix &costMatrix, std::vector< uint8_t > &yMarked, std::vector< uint8_t > &xMarked)
Reduces the cost matrix when no complete assignment can be found with current zeros.
IndexPairs32 Assignments
An alias for a vector of index pairs.
Definition AssignmentSolver.h:60
std::vector< IndexPair32 > IndexPairs32
Definition of a vector holding 32 bit index pairs.
Definition Base.h:144
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition Base.h:138
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
std::vector< Bullseye > Bullseyes
Definition of a vector holding bullseyes.
Definition Bullseye.h:103
The namespace covering the entire Ocean framework.
Definition Accessor.h:15