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; }
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; }