Some refactoring to reuse the same graph for several trackings.
[mtp.git] / tracker.cc
1
2 ///////////////////////////////////////////////////////////////////////////
3 // This program is free software: you can redistribute it and/or modify  //
4 // it under the terms of the version 3 of the GNU General Public License //
5 // as published by the Free Software Foundation.                         //
6 //                                                                       //
7 // This program is distributed in the hope that it will be useful, but   //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of            //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      //
10 // General Public License for more details.                              //
11 //                                                                       //
12 // You should have received a copy of the GNU General Public License     //
13 // along with this program. If not, see <http://www.gnu.org/licenses/>.  //
14 //                                                                       //
15 // Written by and Copyright (C) Francois Fleuret                         //
16 // Contact <francois.fleuret@idiap.ch> for comments & bug reports        //
17 ///////////////////////////////////////////////////////////////////////////
18
19 #include "tracker.h"
20
21 #include <iostream>
22
23 using namespace std;
24
25 Tracker::Tracker(int nb_time_steps, int nb_locations) {
26   _nb_locations = nb_locations;
27   _nb_time_steps = nb_time_steps;
28   _detection_score = allocate_array<scalar_t>(nb_time_steps, nb_locations);
29   _allowed_motion = allocate_array<int>(nb_locations, nb_locations);
30   for(int l = 0; l < nb_locations; l++) {
31     for(int m = 0; m < nb_locations; m++) {
32       _allowed_motion[l][m] = 0;
33     }
34   }
35
36   _edge_lengths = 0;
37   _graph = 0;
38   _edge_occupation = 0;
39 }
40
41 Tracker::~Tracker() {
42   delete[] _edge_lengths;
43   delete _graph;
44   delete[] _edge_occupation;
45   deallocate_array<scalar_t>(_detection_score);
46   deallocate_array<int>(_allowed_motion);
47 }
48
49 void Tracker::set_allowed_motion(int from_location, int to_location, int v) {
50   _allowed_motion[from_location][to_location] = v;
51 }
52
53 void Tracker::set_detection_score(int time, int location, scalar_t score) {
54   _detection_score[time][location] = score;
55 }
56
57 void Tracker::build_graph() {
58   delete[] _edge_lengths;
59   delete[] _graph;
60   delete[] _edge_occupation;
61
62   int nb_motions = 0;
63   for(int l = 0; l < _nb_locations; l++) {
64     for(int m = 0; m < _nb_locations; m++) {
65       if(_allowed_motion[l][m]) nb_motions++;
66     }
67   }
68
69   int nb_vertices = 2 + 2 * _nb_time_steps * _nb_locations;
70   int nb_edges = _nb_locations * 2
71     + (_nb_time_steps - 1) * nb_motions
72     + _nb_locations * _nb_time_steps;
73
74   int source = 0, sink = nb_vertices - 1;
75   int *node_from = new int[nb_edges];
76   int *node_to = new int[nb_edges];
77   int e = 0;
78
79   _edge_lengths = new scalar_t[nb_edges];
80   _edge_occupation = new int[nb_edges];
81
82   // We put the in-node edges first, since these are the ones whose
83   // lengths we will have to change according to the detection score
84
85   for(int t = 0; t < _nb_time_steps; t++) {
86     for(int l = 0; l < _nb_locations; l++) {
87       node_from[e] = 1 + (2 * (t + 0) + 0) * _nb_locations + l;
88       node_to[e] =   1 + (2 * (t + 0) + 1) * _nb_locations + l;
89       e++;
90     }
91   }
92
93   // We put the other edges after
94
95   for(int l = 0; l < _nb_locations; l++) {
96     node_from[e] = source;
97     node_to[e] = 1 + l + 0 * _nb_locations;
98     _edge_lengths[e] = 0.0;
99     e++;
100   }
101
102   for(int t = 0; t < _nb_time_steps; t++) {
103     for(int l = 0; l < _nb_locations; l++) {
104       if(t == _nb_time_steps - 1) {
105         node_from[e] = 1 + (2 * (t + 0) + 1) * _nb_locations + l;
106         node_to[e] = sink;
107         _edge_lengths[e] = 0.0;
108         e++;
109       } else {
110         for(int k = 0; k < _nb_locations; k++) {
111           if(_allowed_motion[l][k]) {
112             node_from[e] = 1 + (2 * (t + 0) + 1) * _nb_locations + l;
113             node_to[e] =   1 + (2 * (t + 1) + 0) * _nb_locations + k;
114             _edge_lengths[e] = 0.0;
115             e++;
116           }
117         }
118       }
119     }
120   }
121
122   _graph = new MTPGraph(nb_vertices, nb_edges,
123                         node_from, node_to,
124                         source, sink);
125
126   delete[] node_from;
127   delete[] node_to;
128 }
129
130 void Tracker::track() {
131   int e = 0;
132   for(int t = 0; t < _nb_time_steps; t++) {
133     for(int l = 0; l < _nb_locations; l++) {
134       _edge_lengths[e] = - _detection_score[t][l];
135       e++;
136     }
137   }
138
139   _graph->find_best_paths(_edge_lengths, _edge_occupation);
140
141   _graph->print_dot();
142 }
143
144 // void Tracker::track() {
145 // }
146
147 // int Tracker::nb_trajectories() {
148 // }
149
150 // int Tracker::trajectory_start_time(int k) {
151 // }
152
153 // int Tracker::trajectory_end_time(int k) {
154 // }
155
156 // int Tracker::trajectory_location(int k, int time) {
157 // }