예제 #1
0
int mfl_get_sttreelen(tree *testtree, charstate *tipdata, int ntax, int nchar, int *besttreelen)
{
    int treelen = 0;
    int *treelen_p = &treelen;
    
    mfl_apply_tipdata(testtree, tipdata, ntax, nchar);
    //mfl_subtree_postorder(testtree->root, treelen_p, nchar);
    mfl_count_postorder(testtree->root, treelen_p, nchar, NULL);
    treelen = 0;
    mfl_fitch_preorder(testtree->root, nchar, treelen_p);
    
    return *treelen_p;
}
예제 #2
0
bool mfl_heuristic_search(mfl_handle_s *mfl_handle)
{
    int ntax = mfl_handle->n_taxa, nchar = mfl_handle->n_chars;
    int numnodes = mfl_calc_numnodes(ntax);
    long int i = 0, j = 0;
    long int nreps = mfl_handle->n_iterations;
    double timein = 0;
    double timeout = 0;
    bool quit = false;
    
    void (*branch_swapper)(node*, tree*, tree**, int, int, int, mfl_searchrec*) = NULL;
    
    tree **savedtrees = (tree**) malloc(TREELIMIT * sizeof(tree*));
    
    tree *newreptree;
    
    charstate *tipdata = mfl_convert_tipdata(mfl_handle->input_data, mfl_handle->n_taxa, mfl_handle->n_chars, mfl_handle->gap_as_missing);
    
    mfl_searchrec *searchrec = mfl_create_searchrec();
    
    mfl_handle->resultant_data = (mfl_resultant_data_s*) malloc(sizeof(mfl_resultant_data_s));
    memset(mfl_handle->resultant_data, 0, sizeof(mfl_resultant_data_s));
    
    if (mfl_handle->resultant_data == NULL) {
        dbg_printf("error in allocating mfl_resultant_data_s\n");
    }
        
    timein = (double)(clock() / (double)CLOCKS_PER_SEC);
    
    /* This outer loop makes it possible to do multiple replicates of random
     * addition sequence. The variable nreps is the number of times an initial
     * tree is generated using random addition sequence. */
    
    branch_swapper = mfl_swap_controller(mfl_handle);
    
    for (i = 0; i < nreps; ++i) {
        
        newreptree = mfl_addseq_randasis(ntax, nchar, numnodes, tipdata, mfl_handle->addseq_type, savedtrees);
        searchrec->currentreplicate = i;
        
        //printNewick(newreptree->trnodes[0]);
        dbg_printf("\n");
        
        if (i == 0) {
            dbg_printf("Replicate: %li\n", i + 1);
            /* The particular addition sequence will have to be selected by the user */
            savedtrees[0] = newreptree;
            savedtrees[0]->compressedtr = mfl_compress_tree(savedtrees[0], ntax, numnodes);
            searchrec->bestinrep = mfl_all_views(savedtrees[0], ntax, nchar, &searchrec->bestinrep);
            searchrec->bestlength = searchrec->bestinrep;
            j = 0;
            dbg_printf("The length of the starting tree: %i steps\n\n", searchrec->bestinrep);
            //printNewick(newreptree->trnodes[0]);
            //dbg_printf("\n");
        }
        else {
            dbg_printf("Replicate: %li\n", i + 1);
            dbg_printf("next in buff at start of rep: %li\n", searchrec->nextinbuffer);
            
            savedtrees[searchrec->nextinbuffer] = newreptree;
            searchrec->bestinrep = mfl_all_views(savedtrees[searchrec->nextinbuffer], ntax, nchar, &searchrec->bestinrep);
            dbg_printf("Best length in replicate: %i\n", searchrec->bestinrep);
            j = searchrec->nextinbuffer;
            searchrec->trbufstart = searchrec->nextinbuffer;
            searchrec->foundbettertr = false;
            //dbg_printf("j = %li\n", searchrec->nextinbuffer);
            quit = false;
            //break;
        }
        
        do {
            mfl_part_reset_searchrec(searchrec);
            mfl_reset_nodes1(savedtrees[j]->trnodes, numnodes, nchar);
            mfl_apply_tipdata(savedtrees[j], tipdata, ntax, nchar);
            mfl_all_views(savedtrees[j], ntax, nchar, &searchrec->bestinrep);
            //mfl_devisit_tree(savedtrees[j]->trnodes, numnodes);

            /* The branch swapper is the specific type of heuristic search 
             * routine: either TBR, SPR, or NNI. TBR by default */
            mfl_save_origstates(savedtrees[j], ntax, numnodes, nchar);
            branch_swapper(savedtrees[j]->trnodes[0], savedtrees[j], savedtrees, 
                                  ntax, nchar, numnodes, searchrec);
            
            if (searchrec->foundbettertr) {
                if (i > 0) {
                    //dbg_printf("trbuf start %li\n", searchrec->trbufstart);
                }
                j = searchrec->trbufstart;
            }
            else {
                savedtrees[j]->swapped = true;
                //if (savedtrees[j]->trnodes) {
                    savedtrees[j]->newick_tree = mfl_newick_cstring(savedtrees[j], ntax);
                    //dbg_printf("%s\n",savedtrees[j]->newick_tree);
                    mfl_free_trnodes(savedtrees[j], numnodes);
                //}
                if (searchrec->success) {
                    mfl_freetree(savedtrees[j], numnodes);
                }
                ++j;
            }
            
            if (j >= searchrec->nextinbuffer || !searchrec->undertreelimit) {
                dbg_printf("number of rearrangements tried: %li\n", searchrec->niter_total);
                quit = true;
            }
            
        } while (!quit);
        
        dbg_printf("Next in buffer at end of rep: %li\n", searchrec->nextinbuffer);
        
        //dbg_printf("best in rep: %i\n", searchrec->bestinrep);
        //dbg_printf("best overall: %i\n", searchrec->bestlength);
        
        if (i != 0) {
            if (searchrec->bestinrep > searchrec->bestlength) {
                mfl_reinit_tbinrange(savedtrees, savedtrees[0], searchrec->trbufstart, &searchrec->nextinbuffer, numnodes);
            }
        }
    }
    
    timeout = (double)(clock() / (double)CLOCKS_PER_SEC);
    
    mfl_handle->resultant_data->bestlength = searchrec->bestlength;
    mfl_handle->resultant_data->n_rearrangements = searchrec->niter_total;
    mfl_handle->resultant_data->n_savetrees = searchrec->nextinbuffer;
    mfl_handle->resultant_data->searcht = (timeout - timein);
    mfl_handle->resultant_data->newicktrees = mfl_store_results(mfl_handle, savedtrees, ntax);
    
    /* TESTING ONLY. This is just for checking output as I build up the heuristic
     * search procedure. Eventually, all this stuff will be written to a struct
     * and handed over to the interface for outputting to screen. */
    
    /*for (j = 0; mfl_handle->resultant_data->newicktrees[j]; ++j) {
        dbg_printf("%s\n", mfl_handle->resultant_data->newicktrees[j]);
    }*/
    
    dbg_printf("Total search time: %g\n", timeout - timein);
    
    dbg_printf("Number of saved trees: %li\n", searchrec->nextinbuffer);
    
    dbg_printf("\nThe optimal tree(s) found by heuristic search:\n");
    //for (j = 0; j < searchrec->nextinbuffer; ++j) {
        //dbg_printf("TREE str_%li = [&U] ", j+1);
        //mfl_root_tree(savedtrees[j], 0, ntax);
        //printNewick(savedtrees[j]->root);
        //cout << "TREE str_" << j+1 << " = [&U] ";// << mfl_handle->resultant_data->newicktrees[i] << endl;
        //dbg_printf("%s\n", savedtrees[j]->newick_tree);
    //}
    //dbg_printf("\n");
    
    /* END OF TESTING-ONLY SECTION */
    
    mfl_clear_treebuffer(savedtrees, &searchrec->nextinbuffer, numnodes);
    free(savedtrees);
    free(tipdata);
    mfl_destroy_searchrec(searchrec);
    
    return true;
}