]> ruin.nu Git - germs.git/blobdiff - src/main.cpp
Added progress information for the search
[germs.git] / src / main.cpp
index 2e074957b459fbd72c3b5b2ada38fd7ca96753bb..9b39eb27d67d7f619608cf90e71aedadd5171157 100644 (file)
@@ -3,26 +3,47 @@
 #include <queue>
 #include <iterator>
 #include <fstream>
+#include <cstdlib>
 
 using namespace std;
 
 #include <unistd.h>
+#include <signal.h>
 
 #include "geneorder.h"
 #include "modelidentifier.h"
 #include "genesorter.h"
+#include "threadgenesorter.h"
 #include "sortaction.h"
 #include "genealgorithms.h"
 #include "model.h"
 
+static bool g_cancel = false;
+
+void handler(int signal)
+{
+
+       if (signal == SIGINT){
+               cerr << "Interrupted" << endl;
+               g_cancel = true;
+       }
+
+       /* signal(SIGINT, handler); */
+}
+
 int main(int argc, char** argv){
 
+       signal(SIGINT, handler);
        string ann = "default.ann";
        Model model(0);
        bool detectModel = true;
+       bool onlyIdentify = false;
+       bool printPerm = false;
 
+       //Parse command line arguments
        int opt;
-       while ((opt = getopt(argc, argv, "m:n:h")) != -1) {
+       int threads = 0;
+       while ((opt = getopt(argc, argv, "im:n:t:hp")) != -1) {
                switch (opt) {
                        case 'm':
                                model = Model::modelFactory(optarg);
@@ -31,10 +52,21 @@ int main(int argc, char** argv){
                        case 'n':
                                ann = optarg;
                                break;
+                       case 't':
+                               threads = atoi(optarg);
+                               break;
+                       case 'i':
+                               onlyIdentify = true;
+                               break;
+                       case 'p':
+                               printPerm = true;
+                               break;
                        case 'h':
                                cout << "Usage: " << argv[0] << " [OPTION] [FILE]" << endl
                                        << endl << "  -m <model> Specifies which model to use for sorting: Whirl, X, Zipper, FatX or Cloud "
                                        << endl << "  -n <ann>   Specifies which artificial neural network to use for identification. '" << ann << "' is used by default"
+                                       << endl << "  -i         Only identify the model, don't try to sort it"
+                                       << endl << "  -p         Print the resulting permutation at each sorting step"
                                        << endl << "  -h         Prints this help message"
                                        << endl << endl
                                        << "With no FILE, or if FILE is '-', stdin will be used"
@@ -47,6 +79,7 @@ int main(int argc, char** argv){
                }
        }
 
+       //Open file, or stdin
        istream* in;
        ifstream file;
        if (optind == argc || *argv[optind] == '-'){
@@ -59,13 +92,14 @@ int main(int argc, char** argv){
                }
                in = &file;
        }
-       //TODO: Parse
+
+       //Parse the gene order permutation
        vector<Gene> g;
        copy(istream_iterator<int>(*in), istream_iterator<int>(),
-                    back_inserter(g));   
+            back_inserter(g));
        GeneOrder go(g.begin(),g.end());
 
-       //TODO: Identify
+       //Identify the model
        ModelIdentifier mi(ann);
        priority_queue<pair<double,Model> > pq = mi.identify(go);
        if (detectModel){
@@ -77,21 +111,62 @@ int main(int argc, char** argv){
        }
        cout << "Using model: " << model.name() << endl;
 
-       cout << "Distance: " << inversionDistance(go) << endl;
+       size_t dist = inversionDistance(go);
+       cout << "Distance: " << dist << endl;
        //copy(go.begin(), go.end(), ostream_iterator<int>(cout, " "));
        //cout << endl;
 
-       //TODO: Chose a sorter
-       GeneSorter so;
-       //TODO: Sort
-       GeneSorter::ActionList al = so.sort(go,model);
+       if (onlyIdentify){
+               return EXIT_SUCCESS;
+       }
+       if (threads){
+               ThreadGeneSorter so(model, threads);
+               so.start(go);
+               cout << "Press CTRL+C to stop" << endl;
+               while (!g_cancel && so.running()){
+                       double score = so.wait(5,1000);
+                       cout << "\r" << "Solutions: " << so.size()
+                               << " Best score: " << score / dist;
+                       cout.flush();
+               }
+               cout << endl << "DONE: Waiting for threads to stop." << endl;
+               so.stop();
+               so.join();
+
+               ThreadGeneSorter::SolutionsQueue solutions = so.solutions();
+
+               for (int i = 0; i < 10 && solutions.size() > 0; ++i){
+                       pair<double,GeneSorter::ActionList> s = solutions.top();
+                       solutions.pop();
+
+                       cout << "Actions: ";
+                       for (GeneSorter::ActionList::iterator sa = s.second.begin();
+                                       sa != s.second.end(); ++sa){
+                               cout << sa->toString() << " ";
+                       }
+                       cout << endl << "Score: " << s.first / dist << endl;
+               }
+       }else{
+               //Sort
+               GeneSorter so;
+               GeneSorter::ActionList al = so.sort(go,model);
+
+               //Print the result
+               double score = 0;
+
+               GeneOrder temp(go);
+               for (GeneSorter::ActionList::iterator sa = al.begin(); sa != al.end(); ++sa){
+                       cout << "Action: " << sa->toString() << " model score: " << model.score(*sa,temp) << endl;
+                       (*sa)(temp);
+                       score += model.score(*sa,temp);
 
-       double score = 0;
-       for (GeneSorter::ActionList::iterator sa = al.begin(); sa != al.end(); ++sa){
-               cout << "Action: " << sa->toString() << " model score: " << model.score(*sa,go) << endl;
-               score += model.score(*sa,go);
+                       if (printPerm){
+                               copy(temp.begin(), temp.end(), ostream_iterator<int>(cout, " "));
+                               cout << endl;
+                       }
+               }
+               cout << "Avg score: " << score / al.size() << endl;
        }
-       cout << "Avg score: " << score / al.size() << endl;
-       //TODO: Print result
+
        return EXIT_SUCCESS;
 }