11 #include <Eigen/Dense> 26 centroid = Eigen::Vector2d(0, 0);
30 Cluster(
int l, Eigen::Vector2d p, vector<int> s)
33 centroid = Eigen::Vector2d(p.x(), p.y());
35 for (
int i = 0; i < s.size(); i++)
36 samples.push_back(s[i]);
43 for (
int i = 0; i < other.
samples.size(); i++)
44 samples.push_back(other.
samples[i]);
51 for (
int i = 0; i < other.
samples.size(); i++)
52 samples.push_back(other.
samples[i]);
79 vector<Eigen::Vector2d> s, vector<Eigen::Vector2d> t,
double delta)
84 this->m_domain =
CDT(d);
90 this->m_sources.clear();
91 for (
int i = 0; i < s.size(); i++)
92 this->m_sources.push_back(s[i]);
94 this->m_targets.clear();
95 for (
int i = 0; i < t.size(); i++)
96 this->m_targets.push_back(t[i]);
98 this->m_delta = delta;
100 this->m_result_s_t.clear();
101 this->m_result_s_t.resize(this->m_sources.size());
109 vector<Eigen::Vector2d>().
swap(m_sources);
110 vector<Eigen::Vector2d>().
swap(m_targets);
111 for (
int i = 0; i < m_result_s_t.size(); i++)
112 vector<int>().swap(m_result_s_t[i]);
113 vector<vector<int>>().
swap(m_result_s_t);
118 bool SolveOMT(
int mode = 0);
120 std::vector<std::vector<int>>
getSolution(){
return m_result_s_t; }
122 void CerrDomainCDT();
124 void CerrClusters(std::vector<Cluster> clusters);
129 std::vector<Cluster> ClusterTargets(
int mode = 0);
131 std::vector<int> Match(std::vector<Cluster> clusters);
155 vector<int> assignment(cost.rows());
160 for (
int r = 0; r < cost.rows(); r++)
162 double minima = DBL_MAX;
163 for (
int c = 0; c < cost.cols(); c++)
164 if (cost(r, c) < minima)
166 for (
int c = 0; c < cost.cols(); c++)
167 cost(r, c) -= minima;
170 cerr <<
"Subtract row minima" << endl << cost << endl << endl;
176 for (
int c = 0; c < cost.cols(); c++)
178 double minima = DBL_MAX;
179 for (
int r = 0; r < cost.rows(); r++)
180 if (cost(r, c) < minima)
182 for (
int r = 0; r < cost.rows(); r++)
183 cost(r, c) -= minima;
186 cerr <<
"Subtract column minima" << endl << cost << endl << endl;
190 vector<bool> tick_rows(cost.rows());
191 vector<bool> tick_cols(cost.cols());
192 vector<vector<bool>> circle;
193 vector<vector<bool>> xxxxxx;
198 circle.resize(cost.rows());
199 xxxxxx.resize(cost.rows());
200 for (
int r = 0; r < cost.rows(); r++)
202 circle[r].resize(cost.cols());
203 xxxxxx[r].resize(cost.cols());
204 for (
int c = 0; c < cost.cols(); c++)
206 circle[r][c] =
false;
207 xxxxxx[r][c] =
false;
213 tick_rows.resize(cost.rows());
215 tick_cols.resize(cost.cols());
218 vector<int> num_rows_0(cost.rows());
219 vector<int> num_cols_0(cost.cols());
221 for (
int r = 0; r < num_rows_0.size(); r++)
223 for (
int c = 0; c < num_cols_0.size(); c++)
225 for (
int r = 0; r < cost.rows(); r++)
227 for (
int c = 0; c < cost.cols(); c++)
229 if (cost(r, c) < 0.0001)
248 for (
int r = 0; r < cost.rows(); r++)
252 for (
int c = 0; c < cost.cols(); c++)
254 if (cost(r, c) < 0.0001 && !xxxxxx[r][c])
261 circle[r][index] =
true;
262 for (
int tr = 0; tr < cost.rows(); tr++)
263 if (cost(tr, index) < 0.0001 && !circle[tr][index])
264 xxxxxx[tr][index] =
true;
267 for (
int c = 0; c < cost.cols(); c++)
271 for (
int r = 0; r < cost.rows(); r++)
272 if (cost(r, c) < 0.0001 && !xxxxxx[r][c])
279 circle[index][c] =
true;
280 for (
int tc = 0; tc < cost.cols(); tc++)
281 if (cost(index, tc) < 0.0001 && !circle[index][tc])
282 xxxxxx[index][tc] =
true;
286 for (
int r = 0; r < cost.rows(); r++)
288 for (
int c = 0; c < cost.cols(); c++)
297 if (circle_crt == circle_num && xxxxxx_crt == xxxxxx_num)
303 circle_num = circle_crt;
304 xxxxxx_num = xxxxxx_crt;
311 for (
int r = 0; r < cost.rows(); r++)
313 for (
int c = 0; c < cost.cols(); c++)
315 if (!circle[r][c] && !xxxxxx[r][c] && cost(r, c) < 0.0001)
318 for (
int tr = 0; tr < cost.rows(); tr++)
320 if (cost(tr, c) < 0.0001
321 && !circle[tr][c] && !xxxxxx[tr][c])
323 xxxxxx[tr][c] =
true;
326 for (
int tc = 0; tc < cost.cols(); tc++)
328 if (cost(r, tc) < 0.0001
329 && !circle[r][tc] && !xxxxxx[r][tc])
331 xxxxxx[r][tc] =
true;
345 for (
int r = 0; r < tick_rows.size(); r++)
346 tick_rows[r] =
false;
347 for (
int c = 0; c < tick_cols.size(); c++)
348 tick_cols[c] =
false;
350 for (
int r = 0; r < cost.rows(); r++)
353 for (
int c = 0; c < cost.cols(); c++)
363 for (
int r = 0; r < tick_rows.size(); r++)
366 for (
int c = 0; c < tick_cols.size(); c++)
370 while (crt_num != tick_num)
374 for (
int r = 0; r < cost.rows(); r++)
378 for (
int c = 0; c < cost.cols(); c++)
380 if (cost(r, c) < 0.0001 && xxxxxx[r][c])
388 for (
int c = 0; c < cost.cols(); c++)
392 for (
int r = 0; r < cost.rows(); r++)
394 if (cost(r, c) < 0.0001 && circle[r][c])
403 for (
int r = 0; r < tick_rows.size(); r++)
406 for (
int c = 0; c < tick_cols.size(); c++)
415 Eigen::MatrixXd lmat(cost.rows(), cost.cols());
416 for (
int r = 0; r < lmat.rows(); r++)
417 for (
int c = 0; c < lmat.cols(); c++)
419 for (
int r = 0; r < cost.rows(); r++)
421 for (
int c = 0; c < cost.cols(); c++)
423 for (
int c = 0; c < cost.cols(); c++)
425 for (
int r = 0; r < cost.rows(); r++)
427 cerr <<
"Cover all zeros with a minimum number of lines" << endl
428 << lmat << endl << endl;
434 for (
int r = 0; r < cost.rows(); r++)
439 for (
int c = 0; c < cost.cols(); c++)
445 if (line_num == cost.rows())
457 vector<vector<bool>> covered;
459 covered.resize(cost.rows());
460 for (
int r = 0; r < cost.rows(); r++)
462 covered[r].resize(cost.cols());
463 for (
int c = 0; c < cost.cols(); c++)
465 covered[r][c] =
false;
470 for (
int r = 0; r < cost.rows(); r++)
474 for (
int c = 0; c < cost.cols(); c++)
476 covered[r][c] =
true;
479 for (
int c = 0; c < cost.cols(); c++)
483 for (
int r = 0; r < cost.rows(); r++)
485 covered[r][c] =
true;
492 double minima = DBL_MAX;
493 for (
int r = 0; r < cost.rows(); r++)
495 for (
int c = 0; c < cost.cols(); c++)
499 if (cost(r, c) < minima)
509 for (
int r = 0; r < cost.rows(); r++)
511 for (
int c = 0; c < cost.cols(); c++)
515 cost(r, c) -= minima;
519 if (!tick_rows[r] && tick_cols[c])
520 cost(r, c) += minima;
528 cerr <<
"Create additional zeros" << endl << cost << endl << endl;
537 for (
int r = 0; r < cost.rows(); r++)
539 for (
int c = 0; c < cost.cols(); c++)
550 Eigen::MatrixXd opt(cost.rows(), cost.cols());
551 for (
int r = 0; r < opt.rows(); r++)
552 for (
int c = 0; c < opt.cols(); c++)
554 for (
int r = 0; r < cost.rows(); r++)
555 for (
int c = 0; c < cost.cols(); c++)
558 cerr <<
"result" << endl << opt << endl << endl;
569 for (
auto it = m_domain.finite_faces_begin(); it != m_domain.finite_faces_end(); it++)
571 if (it->info().in_domain())
582 cerr <<
"plt.fill([" << it->vertex(0)->point().x() <<
", " << it->vertex(1)->point().x() <<
", " << it->vertex(2)->point().x()
583 <<
"], [" << it->vertex(0)->point().y() <<
", " << it->vertex(1)->point().y() <<
", " << it->vertex(2)->point().y()
584 <<
"], color=[0.7, 0.7, 0.7])" << endl;
594 for (
int cid = 0; cid < clusters.size(); cid++)
596 double r = (double)rand() / RAND_MAX;
597 double g = (double)rand() / RAND_MAX;
598 double b = (double)rand() / RAND_MAX;
600 for (
int sid = 0; sid < clusters[cid].samples.size(); sid++)
602 int tid = clusters[cid].samples[sid];
604 sprintf(sentence,
"plt.plot(%f, %f, color=[%f, %f, %f])",
605 m_targets[tid].x(), m_targets[tid].y(), r, g, b);
606 cerr << sentence << endl;
610 sprintf(sentence,
"plt.plot(%f, %f, marker='x', color=[%f, %f, %f])",
611 clusters[cid].
centroid.x(), clusters[cid].centroid.y(), r, g, b);
612 cerr << sentence << endl;
621 double t_beg = clock();
624 int max_iter_times = 10;
627 vector<Cluster> clusters;
628 clusters.resize(m_sources.size());
629 for (
int idx = 0; idx < clusters.size(); idx++)
630 clusters[idx].
centroid = m_sources[idx];
633 for (
int it = 0; it < max_iter_times; it++)
635 cerr <<
"cluster iteration = " << it << endl;
638 vector<Eigen::Vector2d> last_centroids(clusters.size());
639 for (
int cid = 0; cid < clusters.size(); cid++)
640 last_centroids[cid] = Eigen::Vector2d(clusters[cid].
centroid.x(), clusters[cid].centroid.y());
643 for (
int cid = 0; cid < clusters.size(); cid++)
649 int dRange = max_iter_times * m_targets.size();
650 double ** m_tid_cid_d =
new double*[dRange];
651 while (m_tid_cid_d == 0)
653 cerr <<
"memory error, re assign memory..." << endl;
655 m_tid_cid_d =
new double*[dRange];
657 for (
int tid = 0; tid < dRange; tid++)
659 m_tid_cid_d[tid] =
new double[dRange];
660 while (m_tid_cid_d[tid] == 0)
662 cerr <<
"memory error, re assign memory..." << endl;
664 m_tid_cid_d[tid] =
new double[dRange];
668 #pragma omp parallel for num_threads(omp_get_num_procs()) 669 for (
int cid = 0; cid < clusters.size(); cid++)
672 vector<double> cDistances = m_metric->GeodesicDistances(clusters[cid].
centroid, m_targets);
673 for (
int tid = 0; tid < m_targets.size(); tid++)
678 sprintf(str,
"cid = %d, dRange = %d", cid, dRange);
680 cout <<
"error: cid out bound" << endl;
685 sprintf(str,
"tid = %d, dRange = %d", tid, dRange);
687 cout <<
"error: tid out bound" << endl;
689 m_tid_cid_d[tid][cid] = cDistances[tid];
693 for (
int tid = 0; tid < m_targets.size(); tid++)
696 double min_distance = DBL_MAX;
697 for (
int cid = 0; cid < clusters.size(); cid++)
699 double distance = m_tid_cid_d[tid][cid];
700 if (distance < min_distance)
702 min_distance = distance;
706 clusters[c].samples.push_back(tid);
709 for (
int tid = 0; tid < dRange; tid++)
710 delete[] m_tid_cid_d[tid];
711 delete[] m_tid_cid_d;
715 #pragma omp parallel for num_threads(omp_get_num_procs()) 716 for (
int cid = 0; cid < clusters.size(); cid++)
719 if (clusters[cid].
samples.empty())
721 clusters[cid].centroid = Eigen::Vector2d(999999, 999999);
725 Eigen::Vector2d val(0, 0);
726 for (
int sid = 0; sid < clusters[cid].samples.size(); sid++)
728 int sample = clusters[cid].samples[sid];
729 val = Eigen::Vector2d(val.x() + m_targets[sample].x(), val.y() + m_targets[sample].y());
731 clusters[cid].centroid = Eigen::Vector2d(val.x() / clusters[cid].samples.size(), val.y() / clusters[cid].samples.size());
737 if (m_p_de->m_recon2D.m_cellmap[r][c].isScanned && m_p_de->m_recon2D.m_cellmap[r][c].isFree)
744 double min_d = DBL_MAX;
745 Eigen::Vector2d min_p;
746 for (
auto it = m_domain.vertices_begin(); it != m_domain.vertices_end(); it++)
748 Eigen::Vector2d p(it->point().x(), it->point().y());
749 double d = (clusters[cid].centroid - p).norm();
753 min_p = Eigen::Vector2d(p);
756 clusters[cid].centroid = min_p;
762 for (
int cid = 0; cid < clusters.size(); cid++)
764 if (clusters[cid].
samples.size() <= 1)
continue;
766 vector<Eigen::Vector2d> targets;
767 for (
int tid = 0; tid < clusters[cid].samples.size(); tid++)
768 targets.push_back(Eigen::Vector2d(m_targets[clusters[cid].samples[tid]].x(), m_targets[clusters[cid].samples[tid]].y()));
770 vector<double> inDistances = m_metric->GeodesicDistances(clusters[cid].
centroid, targets);
773 double maxDistance = -1;
774 for (
int i = 0; i < inDistances.size(); i++)
776 if (maxDistance < inDistances[i])
778 maxDistance = inDistances[i];
784 cerr <<
"error: maxID == -1." << endl;
785 getchar(); getchar(); getchar();
787 if (maxID >= clusters[cid].
samples.size() || maxID >= m_targets.size())
789 cerr <<
"error: maxID out bound." << endl;
790 cerr <<
"maxID = " << maxID << endl;
791 cerr <<
"cluster samples num = " << clusters[cid].samples.size() << endl;
792 cerr <<
"targets num = " << m_targets.size() << endl;
793 getchar(); getchar(); getchar();
800 new_cluster.
label = -1;
802 new_cluster.
centroid = Eigen::Vector2d(m_targets[clusters[cid].
samples[maxID]].x(), m_targets[clusters[cid].
samples[maxID]].y());
803 clusters.push_back(new_cluster);
805 clusters[cid].samples.erase(clusters[cid].
samples.begin() + maxID);
810 int valid_cluster_num = 0;
811 for (
int cid = 0; cid < clusters.size(); cid++)
813 if (clusters[cid].
samples.empty())
817 if (valid_cluster_num <= m_sources.size())
826 for (
int cid = 0; cid < clusters.size() - 1; cid++)
828 if (clusters[cid].
samples.empty())
continue;
829 for (
int oid = cid + 1; oid < clusters.size(); oid++)
831 if (clusters[oid].
samples.empty())
continue;
835 double outerD = m_metric->get_geodesic_distance_fast(p1, p2);
838 if (clusters[oid].
samples.size() == 1)
840 clusters[cid].samples.push_back(clusters[oid].
samples[0]);
841 clusters[oid].samples.clear();
844 else if (clusters[cid].
samples.size() == 1)
846 clusters[oid].samples.push_back(clusters[cid].
samples[0]);
847 clusters[cid].samples.clear();
862 vector<Cluster> temp_clusters;
863 for (
int cid = 0; cid < clusters.size(); cid++)
865 if (!clusters[cid].
samples.empty())
867 temp_clusters.push_back(
Cluster(clusters[cid]));
870 vector<Cluster>().
swap(clusters);
871 clusters = temp_clusters;
876 for (
int cid = 0; cid < clusters.size(); cid++)
878 if (clusters[cid].
samples.empty())
880 clusters[cid].centroid = Eigen::Vector2d(999999, 999999);
884 Eigen::Vector2d val(0, 0);
885 for (
int sid = 0; sid < clusters[cid].samples.size(); sid++)
887 int sample = clusters[cid].samples[sid];
888 val = Eigen::Vector2d(val.x() + m_targets[sample].x(), val.y() + m_targets[sample].y());
890 clusters[cid].centroid = Eigen::Vector2d(val.x() / clusters[cid].samples.size(), val.y() / clusters[cid].samples.size());
896 if (m_p_de->m_recon2D.m_cellmap[r][c].isScanned && m_p_de->m_recon2D.m_cellmap[r][c].isFree)
903 double min_d = DBL_MAX;
904 Eigen::Vector2d min_p;
905 for (
auto it = m_domain.vertices_begin(); it != m_domain.vertices_end(); it++)
907 Eigen::Vector2d p(it->point().x(), it->point().y());
908 double d = (clusters[cid].centroid - p).norm();
912 min_p = Eigen::Vector2d(p);
915 clusters[cid].centroid = min_p;
923 bool terminate =
false;
924 if (last_centroids.size() == clusters.size())
927 for (
int cid = 0; cid < clusters.size(); cid++)
929 diff += (last_centroids[cid] - clusters[cid].centroid).norm();
935 if (diff < 0.001) terminate =
true;
940 cerr <<
"converged at iter " << it <<
"." << endl;
1078 vector<Cluster> temp_clusters;
1079 for (
int cid = 0; cid < clusters.size(); cid++)
1081 if (!clusters[cid].
samples.empty())
1083 temp_clusters.push_back(
Cluster(clusters[cid]));
1086 vector<Cluster>().
swap(clusters);
1087 clusters = temp_clusters;
1091 double t_end = clock();
1092 cerr <<
"DiscreteSolver cluster timing " << (t_end - t_beg)/CLOCKS_PER_SEC <<
" s" << endl;
1164 vector<Eigen::Vector2d> centroids(clusters.size());
1165 for (
int cid = 0; cid < clusters.size(); cid++)
1166 centroids[cid] = clusters[cid].
centroid;
1167 vector<int> matches(m_sources.size());
1168 for (
int sid = 0; sid < m_sources.size(); sid++)
1172 vector<vector<double>> d_s_c(m_sources.size());
1173 for (
int s = 0;
s < d_s_c.size();
s++)
1175 d_s_c[
s] = m_metric->GeodesicDistances(m_sources[
s], centroids);
1183 int dim =
max(m_sources.size(), centroids.size());
1184 Eigen::MatrixXd cost(dim, dim);
1185 if (m_sources.size() < centroids.size())
1187 for (
int r = 0; r < dim; r++)
1188 for (
int c = 0; c < dim; c++)
1190 if (r >= m_sources.size())
1193 cost(r, c) = d_s_c[r][c];
1200 for (
int r = 0; r < m_sources.size(); r++)
1201 matches[r] = assignment[r];
1203 else if (m_sources.size() == centroids.size())
1205 for (
int r = 0; r < dim; r++)
1206 for (
int c = 0; c < dim; c++)
1207 cost(r, c) = d_s_c[r][c];
1215 for (
int r = 0; r < dim; r++)
1216 for (
int c = 0; c < dim; c++)
1218 if (c >= centroids.size())
1221 cost(r, c) = d_s_c[r][c];
1228 for (
int r = 0; r < m_sources.size(); r++)
1230 if (assignment[r] >= centroids.size())
1233 matches[r] = assignment[r];
1255 if (!m_result_s_t.empty())
1257 for (
int i = 0; i < m_result_s_t.size(); i++)
1258 if (!m_result_s_t[i].empty()) vector<int>().swap(m_result_s_t[i]);
1259 vector<vector<int>>().
swap(m_result_s_t);
1261 m_result_s_t.resize(m_sources.size());
1264 vector<Cluster> clusters = ClusterTargets(mode);
1267 vector<int> matches = Match(clusters);
1270 for (
int sid = 0; sid < m_sources.size(); sid++)
1272 int cid = matches[sid];
1275 for (
int idx = 0; idx < clusters[cid].samples.size(); idx++)
1277 int tid = clusters[cid].samples[idx];
1278 m_result_s_t[sid].push_back(tid);
std::vector< Eigen::Vector2d > m_sources
Cluster & operator=(const Cluster &other)
vector< int > hungarian_algorithm(Eigen::MatrixXd cost)
std::vector< std::vector< int > > getSolution()
EIGEN_DEVICE_FUNC const LogReturnType log() const
DistanceMetric * m_metric
std::vector< std::vector< int > > m_result_s_t
std::vector< Cluster > ClusterTargets(int mode=0)
void CerrClusters(std::vector< Cluster > clusters)
std::vector< Eigen::Vector2d > m_targets
std::vector< int > Match(std::vector< Cluster > clusters)
int64_t max(int64_t a, const int b)
CGAL::Constrained_Delaunay_triangulation_2< K, TDS, Itag > CDT
bool SolveOMT(int mode=0)
Cluster(const Cluster &other)
Cluster(int l, Eigen::Vector2d p, vector< int > s)
DiscreteSolver(DataEngine &de, CDT d, DistanceMetric &dm, vector< Eigen::Vector2d > s, vector< Eigen::Vector2d > t, double delta)
void swap(scoped_array< T > &a, scoped_array< T > &b)
EIGEN_DEVICE_FUNC const RoundReturnType round() const