Apollo  6.0
Open source self driving car software
km.h
Go to the documentation of this file.
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 
34 namespace apollo {
35 namespace v2x {
36 namespace ft {
37 
38 class 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 };
59 template <typename T>
60 bool 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 
136 template <typename T>
137 bool 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
#define USR_INF
Definition: km.h:32
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
bool GetKMResult(const T &association_mat, std::vector< std::pair< int, int >> *match_cps, bool need_reverse=false)
Definition: km.h:60
Definition: km.h:38