]> ruin.nu Git - germs.git/blob - src/main.cpp
Added progress information for the search
[germs.git] / src / main.cpp
1 #include <iostream>
2 #include <vector>
3 #include <queue>
4 #include <iterator>
5 #include <fstream>
6 #include <cstdlib>
7
8 using namespace std;
9
10 #include <unistd.h>
11 #include <signal.h>
12
13 #include "geneorder.h"
14 #include "modelidentifier.h"
15 #include "genesorter.h"
16 #include "threadgenesorter.h"
17 #include "sortaction.h"
18 #include "genealgorithms.h"
19 #include "model.h"
20
21 static bool g_cancel = false;
22
23 void handler(int signal)
24 {
25
26         if (signal == SIGINT){
27                 cerr << "Interrupted" << endl;
28                 g_cancel = true;
29         }
30
31         /* signal(SIGINT, handler); */
32 }
33
34 int main(int argc, char** argv){
35
36         signal(SIGINT, handler);
37         string ann = "default.ann";
38         Model model(0);
39         bool detectModel = true;
40         bool onlyIdentify = false;
41         bool printPerm = false;
42
43         //Parse command line arguments
44         int opt;
45         int threads = 0;
46         while ((opt = getopt(argc, argv, "im:n:t:hp")) != -1) {
47                 switch (opt) {
48                         case 'm':
49                                 model = Model::modelFactory(optarg);
50                                 detectModel = false;
51                                 break;
52                         case 'n':
53                                 ann = optarg;
54                                 break;
55                         case 't':
56                                 threads = atoi(optarg);
57                                 break;
58                         case 'i':
59                                 onlyIdentify = true;
60                                 break;
61                         case 'p':
62                                 printPerm = true;
63                                 break;
64                         case 'h':
65                                 cout << "Usage: " << argv[0] << " [OPTION] [FILE]" << endl
66                                         << endl << "  -m <model> Specifies which model to use for sorting: Whirl, X, Zipper, FatX or Cloud "
67                                         << endl << "  -n <ann>   Specifies which artificial neural network to use for identification. '" << ann << "' is used by default"
68                                         << endl << "  -i         Only identify the model, don't try to sort it"
69                                         << endl << "  -p         Print the resulting permutation at each sorting step"
70                                         << endl << "  -h         Prints this help message"
71                                         << endl << endl
72                                         << "With no FILE, or if FILE is '-', stdin will be used"
73                                         << endl;
74                                 exit(EXIT_SUCCESS);
75                                 break;
76                         default: /* '?' */
77                                 cerr << "Usage:  " << argv[0] << " [-n <ann>] [-h] [FILE]" << endl;
78                                 exit(EXIT_FAILURE);
79                 }
80         }
81
82         //Open file, or stdin
83         istream* in;
84         ifstream file;
85         if (optind == argc || *argv[optind] == '-'){
86                 in = &cin;
87         }else{
88                 file.open(argv[optind]);
89                 if (file.fail()){
90                         cerr << "Could not open file: '" << argv[optind] << "'" << endl;
91                         exit(EXIT_FAILURE);
92                 }
93                 in = &file;
94         }
95
96         //Parse the gene order permutation
97         vector<Gene> g;
98         copy(istream_iterator<int>(*in), istream_iterator<int>(),
99              back_inserter(g));
100         GeneOrder go(g.begin(),g.end());
101
102         //Identify the model
103         ModelIdentifier mi(ann);
104         priority_queue<pair<double,Model> > pq = mi.identify(go);
105         if (detectModel){
106                 model = pq.top().second;
107         }
108         while (pq.size() > 0){
109                 cout << "Model: " << pq.top().second.name() << " score: " << pq.top().first << endl;
110                 pq.pop();
111         }
112         cout << "Using model: " << model.name() << endl;
113
114         size_t dist = inversionDistance(go);
115         cout << "Distance: " << dist << endl;
116         //copy(go.begin(), go.end(), ostream_iterator<int>(cout, " "));
117         //cout << endl;
118
119         if (onlyIdentify){
120                 return EXIT_SUCCESS;
121         }
122         if (threads){
123                 ThreadGeneSorter so(model, threads);
124                 so.start(go);
125                 cout << "Press CTRL+C to stop" << endl;
126                 while (!g_cancel && so.running()){
127                         double score = so.wait(5,1000);
128                         cout << "\r" << "Solutions: " << so.size()
129                                 << " Best score: " << score / dist;
130                         cout.flush();
131                 }
132                 cout << endl << "DONE: Waiting for threads to stop." << endl;
133                 so.stop();
134                 so.join();
135
136                 ThreadGeneSorter::SolutionsQueue solutions = so.solutions();
137
138                 for (int i = 0; i < 10 && solutions.size() > 0; ++i){
139                         pair<double,GeneSorter::ActionList> s = solutions.top();
140                         solutions.pop();
141
142                         cout << "Actions: ";
143                         for (GeneSorter::ActionList::iterator sa = s.second.begin();
144                                         sa != s.second.end(); ++sa){
145                                 cout << sa->toString() << " ";
146                         }
147                         cout << endl << "Score: " << s.first / dist << endl;
148                 }
149         }else{
150                 //Sort
151                 GeneSorter so;
152                 GeneSorter::ActionList al = so.sort(go,model);
153
154                 //Print the result
155                 double score = 0;
156
157                 GeneOrder temp(go);
158                 for (GeneSorter::ActionList::iterator sa = al.begin(); sa != al.end(); ++sa){
159                         cout << "Action: " << sa->toString() << " model score: " << model.score(*sa,temp) << endl;
160                         (*sa)(temp);
161                         score += model.score(*sa,temp);
162
163                         if (printPerm){
164                                 copy(temp.begin(), temp.end(), ostream_iterator<int>(cout, " "));
165                                 cout << endl;
166                         }
167                 }
168                 cout << "Avg score: " << score / al.size() << endl;
169         }
170
171         return EXIT_SUCCESS;
172 }