Apollo 11.0
自动驾驶开放平台
km.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2020 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17#pragma once
18
19#include <unistd.h>
20
21#include <algorithm>
22#include <cmath>
23#include <cstdlib>
24#include <iostream>
25#include <set>
26#include <string>
27#include <utility>
28#include <vector>
29
30#include <Eigen/Core>
31
32#define USR_INF 999999999999
33
34namespace apollo {
35namespace v2x {
36namespace ft {
37
38class KMkernal {
39 public:
40 KMkernal() = default;
41 ~KMkernal() = default;
42 template <typename T>
43 bool GetKMResult(const T& association_mat,
44 std::vector<std::pair<int, int>>* match_cps,
45 bool need_reverse = false);
46
47 private:
48 int u_size_;
49 int v_size_;
50 double* ex_u_;
51 double* ex_v_;
52 int* v_matched_;
53 double* v_slack_;
54 std::set<int> used_u_;
55 std::set<int> used_v_;
56 template <typename T>
57 bool FindCP(const T& mat, int i);
58};
59template <typename T>
60bool KMkernal::GetKMResult(const T& association_mat,
61 std::vector<std::pair<int, int>>* match_cps,
62 bool need_reverse) {
63 match_cps->clear();
64 u_size_ = association_mat.rows();
65 v_size_ = association_mat.cols();
66 if (u_size_ > v_size_) return false;
67 ex_u_ = new double[u_size_];
68 ex_v_ = new double[v_size_];
69 v_matched_ = new int[v_size_];
70 std::fill(v_matched_, v_matched_ + v_size_, -1);
71 memset(ex_v_, 0, v_size_ * sizeof(double));
72 for (int i = 0; i < u_size_; ++i) {
73 ex_u_[i] = association_mat(i, 0);
74 for (int j = 1; j < v_size_; ++j) {
75 ex_u_[i] = std::max(static_cast<float>(ex_u_[i]), association_mat(i, j));
76 }
77 }
78 for (int i = 0; i < u_size_; ++i) {
79 if (ex_u_[i] <= 0) {
80 if (need_reverse)
81 match_cps->push_back(std::make_pair(-1, i));
82 else
83 match_cps->push_back(std::make_pair(i, -1));
84 continue;
85 }
86 v_slack_ = new double[v_size_];
87 std::fill(v_slack_, v_slack_ + v_size_, USR_INF);
88 while (1) {
89 used_u_.clear();
90 used_v_.clear();
91 if (FindCP(association_mat, i)) break;
92 double d = USR_INF;
93 for (int j = 0; j < v_size_; ++j)
94 if (used_v_.find(j) == used_v_.end()) d = std::min(d, v_slack_[j]);
95 for (auto it = used_u_.begin(); it != used_u_.end(); it++) {
96 ex_u_[*it] -= d;
97 }
98 for (int j = 0; j < v_size_; ++j) {
99 if (used_v_.find(j) != used_v_.end())
100 ex_v_[j] += d;
101 else
102 v_slack_[j] -= d;
103 }
104 }
105 delete[] v_slack_;
106 }
107 if (need_reverse) {
108 for (int j = 0; j < v_size_; ++j) {
109 if (v_matched_[j] == -1) {
110 match_cps->push_back(std::make_pair(j, -1));
111 } else if (association_mat(v_matched_[j], j) > 0) {
112 match_cps->push_back(std::make_pair(j, v_matched_[j]));
113 } else {
114 match_cps->push_back(std::make_pair(-1, v_matched_[j]));
115 match_cps->push_back(std::make_pair(j, -1));
116 }
117 }
118 } else {
119 for (int j = 0; j < v_size_; ++j) {
120 if (v_matched_[j] == -1) {
121 match_cps->push_back(std::make_pair(-1, j));
122 } else if (association_mat(v_matched_[j], j) > 0) {
123 match_cps->push_back(std::make_pair(v_matched_[j], j));
124 } else {
125 match_cps->push_back(std::make_pair(v_matched_[j], -1));
126 match_cps->push_back(std::make_pair(-1, j));
127 }
128 }
129 }
130 delete[] ex_u_;
131 delete[] ex_v_;
132 delete[] v_matched_;
133 return true;
134}
135
136template <typename T>
137bool KMkernal::FindCP(const T& mat, int i) {
138 used_u_.insert(i);
139 for (int j = 0; j < v_size_; ++j) {
140 if (used_v_.find(j) != used_v_.end()) {
141 continue;
142 }
143 double gap = ex_u_[i] + ex_v_[j] - mat(i, j);
144 if (gap <= 0) {
145 // res = 0;
146 used_v_.insert(j);
147 bool match_success = v_matched_[j] == -1 || FindCP(mat, v_matched_[j]);
148 if (match_success) {
149 v_matched_[j] = i;
150 return true;
151 }
152 } else {
153 v_slack_[j] = std::min(v_slack_[j], gap);
154 }
155 }
156 return false;
157}
158
159} // namespace ft
160} // namespace v2x
161} // namespace apollo
bool GetKMResult(const T &association_mat, std::vector< std::pair< int, int > > *match_cps, bool need_reverse=false)
Definition km.h:60
#define USR_INF
Definition km.h:32
class register implement
Definition arena_queue.h:37