예제 #1
0
파일: node.cpp 프로젝트: UdeM-LBIT/SuGeT
void Node::BinarizeRandomly()
{
    TreeIterator* it = this->GetPostOrderIterator();
    while (Node* n = it->next())
    {
        if (n != this)
        {
            n->BinarizeRandomly();
        }
    }
    this->CloseIterator(it);

    while (this->GetNbChildren() > 2)
    {

        int ic1 = rand() % this->GetNbChildren();
        int ic2 = rand() % this->GetNbChildren();

        if (ic1 != ic2)
        {
            Node* c1 = this->GetChild(ic1);
            Node* c2 = this->GetChild(ic2);

            c1->InsertParentWith(c2);
        }
    }
}
예제 #2
0
string SADNADGraph::GetEdgeType(Node* n1, Node* n2, unordered_map<Node*, Node*> &lcaMapping)
{
    Node* s1 = lcaMapping[n1];
    Node* s2 = lcaMapping[n2];
    if (!s1->HasAncestor(s2) && !s2->HasAncestor(s1))
    {
        return "S";
    }
    else
    {
        bool hasOne = false;
        unordered_set<Node*> n1Species = GeneSpeciesTreeUtil::Instance()->GetGeneTreeSpecies(n1, lcaMapping);
        TreeIterator* it = n2->GetPostOrderIterator(true);
        while (Node* n2leaf = it->next())
        {
            if (n1Species.find(lcaMapping[n2leaf]) != n1Species.end())
            {
                hasOne = true;
                break;
            }
        }
        n2->CloseIterator(it);

        if (hasOne)
            return "AD";
        else
            return "NAD";

    }
}
예제 #3
0
파일: node.cpp 프로젝트: UdeM-LBIT/SuGeT
Node* Node::GetNodeWithLabel(string lbl, bool ignoreCase)
{
    TreeIterator* it = this->GetPostOrderIterator();

    Node* found = NULL;
    while (Node* n = it->next())
    {
        if (ignoreCase)
        {
            if (Util::ToUpper(lbl) == Util::ToUpper(n->GetLabel()))
            {
                found = n;
                break;
            }
        }
        else
        {
            if (lbl == n->GetLabel())
            {
                found = n;
                break;
            }
        }
    }
    this->CloseIterator(it);

    return found;
}
예제 #4
0
pair<Node*, unordered_map<Node*, Node*> > PolySolverNAD::PolytomizeNAD(Node* nadNode, Node* speciesTree, unordered_map<Node*, Node*> lcaMapping)
{
    set<Node*> leftSubtrees, rightSubtrees;
    Node* s = lcaMapping[nadNode];

    //TODO : there should be a way not to iterate uselessly into a taken subtree (preorder traversal that we stop)
    TreeIterator* it = nadNode->GetPostOrderIterator();
    while (Node* n = it->next())
    {
        if (n != nadNode)
        {
            //here we maximal subtree either on the left or right
            if (lcaMapping[n] != s && lcaMapping[n->GetParent()] == s)
            {
                if (lcaMapping[n]->HasAncestor(s->GetChild(0)))
                {
                    leftSubtrees.insert(n);
                }
                else    //if (lcaMapping[n]->HasAncestor(s->GetChild(1))) should be the only possibility here
                {
                    rightSubtrees.insert(n);
                }
            }
        }
    }
    nadNode->CloseIterator(it);


    Node* newShizzle = new Node(false);
    Node* left = newShizzle->AddChild();
    Node* right = newShizzle->AddChild();
    unordered_map<Node*, Node*> newMapping;

    for (set<Node*>::iterator itLeft = leftSubtrees.begin(); itLeft != leftSubtrees.end(); itLeft++)
    {
        Node* copy = GeneSpeciesTreeUtil::Instance()->CopyTreeWithNodeMapping((*itLeft), lcaMapping, newMapping);
        left->AddSubTree(copy);
    }

    for (set<Node*>::iterator itRight = rightSubtrees.begin(); itRight != rightSubtrees.end(); itRight++)
    {
        Node* copy = GeneSpeciesTreeUtil::Instance()->CopyTreeWithNodeMapping((*itRight), lcaMapping, newMapping);
        right->AddSubTree(copy);
    }

    newMapping[newShizzle] = s;
    if (left->GetNbChildren() > 1)
    {
        newMapping[left] = GeneSpeciesTreeUtil::Instance()->GetSingleNodeLCAMapping(left, speciesTree, newMapping);
    }
    if (right->GetNbChildren() > 1)
    {
        newMapping[right] = GeneSpeciesTreeUtil::Instance()->GetSingleNodeLCAMapping(right, speciesTree, newMapping);
    }

    newShizzle->DeleteSingleChildDescendants();

    return make_pair(newShizzle, newMapping);
}
예제 #5
0
파일: node.cpp 프로젝트: UdeM-LBIT/SuGeT
void Node::DeleteSingleChildDescendants()
{
    TreeIterator* it = this->GetPostOrderIterator();

    Node* n = it->next();
    while (n)
    {
        if (n->GetNbChildren() == 1)
        {
            n = it->DeleteCurrent();
        }
        else
        {
            n = it->next();
        }
    }
    this->CloseIterator(it);
}
예제 #6
0
/*---------------------------------------------------------------------*//**
	兄弟ノード取得
**//*---------------------------------------------------------------------*/
MenuTreeNode* Menu::getMenuTreeNodeSibling(MenuTreeNode* mtnode) const
{
	for(TreeIterator<MenuTreeNode> it = _tree->iterator(); it.has(); it.next())
	{
		if(it.object() == mtnode)
		{
			TreeNode<MenuTreeNode>* tnodeSibling = it.node()->sibling();
			return (tnodeSibling != 0L) ? tnodeSibling->object() : 0L;
		}
	}
	return 0L;
}
예제 #7
0
파일: node.cpp 프로젝트: UdeM-LBIT/SuGeT
vector<Node*> Node::GetPostOrderedNodes()
{
    vector<Node*> v;
    TreeIterator* it = this->GetPostOrderIterator();
    while (Node* n = it->next())
    {
        v.push_back(n);
    }
    this->CloseIterator(it);

    return v;
}
예제 #8
0
/*---------------------------------------------------------------------*//**
	子ノード取得
**//*---------------------------------------------------------------------*/
MenuTreeNode* Menu::getMenuTreeNodeChild(MenuTreeNode* mtnode) const
{
	for(TreeIterator<MenuTreeNode> it = _tree->iterator(); it.has(); it.next())
	{
		if(it.object() == mtnode)
		{
			TreeNode<MenuTreeNode>* tnodeChild = it.node()->child();
			return (tnodeChild != 0L) ? tnodeChild->object() : 0L;
		}
	}
	return 0L;
}
예제 #9
0
파일: node.cpp 프로젝트: UdeM-LBIT/SuGeT
void Node::Restrict(bool (*fncDelete)(Node*, void*), void* arg)
{
    TreeIterator* it = this->GetPostOrderIterator();

    Node* n = it->next();
    while (n)
    {
        bool ok = (*fncDelete)(n, arg);

        if (!ok)
        {
            n = it->DeleteCurrent();
        }
        else
        {
            n = it->next();
        }
    }

    this->CloseIterator(it);

}
예제 #10
0
파일: node.cpp 프로젝트: UdeM-LBIT/SuGeT
vector<Node*> Node::GetLeafVector()
{
    vector<Node*> leaves;
    TreeIterator* it = this->GetPostOrderIterator(true);

    while (Node* n = it->next())
    {
        leaves.push_back(n);
    }
    this->CloseIterator(it);

    return leaves;

}
예제 #11
0
파일: node.cpp 프로젝트: UdeM-LBIT/SuGeT
set<Node*> Node::GetLeafSet()
{
    set<Node*> leaves;
    TreeIterator* it = this->GetPostOrderIterator(true);

    while (Node* n = it->next())
    {
        leaves.insert(n);
    }
    this->CloseIterator(it);

    return leaves;

}
예제 #12
0
bool Menu::createFromXml(FileBase* fileXml, MenuFuncTable* functblRef, MenuPanelFactory* pnlfctryRef, void* objCreateParam)
{
	// XML ファイルをバッファに読み込む
	VcString bufFile;
	while(true)
	{
		const int SIZE_BUF = 100 * 1024;
		char buf[SIZE_BUF];
		int sizeRead = fileXml->read(buf, SIZE_BUF);
		bufFile.add(buf, sizeRead);
		if(sizeRead < SIZE_BUF)	{	break;	}
	}
	CMXML_TRACE(VcString::format("{Menu::createFromXml} menu xml : size=%d\n", bufFile.getLength()));
	
	// XML を解析する
	XmlParser xmlparser;
	xmlparser.parseXmlDocument(&bufFile);
	CMXML_TRACE("{Menu::createFromXml} XmlParser::parseXmlDocument end.\n");
	
	// ツリーを作成する
	_tree = new Tree<MenuTreeNode>(true);
	addTreeNode(_tree->addRootNode(), true, xmlparser.getRootNode());

	#if defined(_DEBUG)
		TRACE("{Menu::createFromXml} menu hierarchy\n");
		for(TreeIterator<MenuTreeNode> it = _tree->iterator(); it.has(); it.next())
		{
			if(it.object() != 0L)	{	for(int i = 0; i < it.getDepth(); i++) { CMXML_TRACE(" "); }	CMXML_TRACE( *it.object()->getName() + "\n" );	}
		}
	#endif

	// ファンクションテーブルを保存する
	_functblRef = functblRef;
	// パネルファクトリを保存する
	_pnlfctryRef = pnlfctryRef;
	// パラメータオブジェクトを保存する
	_objCreateParamRef = objCreateParam;
	
	return true;
}
예제 #13
0
/*---------------------------------------------------------------------*//**
	破棄
**//*---------------------------------------------------------------------*/
void Menu::destroy()
{
	if(_isShow)
	{
		closeMenu();
	}

	// ツリー削除
	if(_tree != 0L)
	{
		for(TreeIterator<MenuTreeNode> it = _tree->iterator(); it.has(); it.next())
		{
			MenuTreeNode* mtnode = it.object();
			if(mtnode != 0L)	// ルートは NULL
			{
				mtnode->destroy();
			}
		}
		delete _tree;
		_tree = 0L;
	}
}
예제 #14
0
Node* PolySolverNAD::SolvePolytomies(Node *geneTree, Node *speciesTree, unordered_map<Node*, Node*> geneLeavesSpeciesMapping)
{
    //TODO : THIS HASN'T BEEN TESTED AFTER SOME MODIFICATIONS !!
    Node* geneTreeCopy;

    unordered_map<Node*, Node*> mappingCopy;
    geneTreeCopy = GeneSpeciesTreeUtil::Instance()->CopyTreeWithNodeMapping(geneTree, geneLeavesSpeciesMapping, mappingCopy);

    unordered_map<Node*, Node*> lcaMapping = GeneSpeciesTreeUtil::Instance()->GetLCAMapping(geneTreeCopy, speciesTree, mappingCopy);

    TreeIterator* it = geneTreeCopy->GetPostOrderIterator();
    while (Node* g = it->next())
    {
        vector<Node*> curLeaves;
        for (int i = 0; i < g->GetNbChildren(); i++)
        {
            curLeaves.push_back(g->GetChild(i));
        }
        this->SolvePolytomy(curLeaves, speciesTree, lcaMapping);
    }

    return geneTreeCopy;
}
예제 #15
0
PolySolverCorrectionInfo PolySolverNAD::CorrectHighestNAD(Node* geneTree, Node* speciesTree, unordered_map<Node*, Node*> geneLeavesSpeciesMapping)
{



    unordered_map<Node*, Node*> oldlcaMapping = GeneSpeciesTreeUtil::Instance()->GetLCAMapping(geneTree, speciesTree, geneLeavesSpeciesMapping);
    unordered_map<Node*, Node*> lcaMapping;

    Node* geneTreeCopy = GeneSpeciesTreeUtil::Instance()->CopyTreeWithNodeMapping(geneTree, oldlcaMapping, lcaMapping);

    //GeneSpeciesTreeUtil::Instance()->PrintMapping(geneTreeCopy, lcaMapping);

    TreeIterator* it = geneTreeCopy->GetPreOrderIterator();
    while (Node* n = it->next())
    {
        if (!n->IsLeaf())
        {
            //first check if it's a duplication, lca mapping classic rule
            if (lcaMapping[n->GetChild(0)] == lcaMapping[n] || lcaMapping[n->GetChild(1)] == lcaMapping[n])
            {
                if (!GeneSpeciesTreeUtil::Instance()->HaveCommonSpecies(n->GetChild(0), n->GetChild(1), lcaMapping))
                {
                    vector<string> leafLabels;
                    vector<Node*> n_leaves = n->GetLeafVector();
                    for (int i = 0; i < n_leaves.size(); i++)
                    {
                        leafLabels.push_back(n_leaves[i]->GetLabel());
                    }

                    //there it is ! the highest NAD
                    pair<Node*, unordered_map<Node*, Node*> > polytomizedWithMapping = PolytomizeNAD(n, speciesTree, lcaMapping);
                    Node* polytomized = polytomizedWithMapping.first;


                    //HERE we do some not so clean stuff...because whatever we do, we'll exit this function
                    geneTreeCopy->CloseIterator(it);

                    //replace the subtree that just got polytomized
                    if (!n->IsRoot())
                    {
                        Node* parent = n->GetParent();
                        parent->RemoveChild(n);
                        parent->AddSubTree(polytomized);
                        delete n;
                    }
                    else
                    {
                        delete geneTreeCopy;
                        geneTreeCopy = polytomized;
                    }

                    //cout<<"COPY AFTER = "<<NewickLex::ToNewickString(geneTreeCopy)<<endl;


                    PolySolverCorrectionInfo info;
                    info.nadCladeGenes = leafLabels;
                    info.firstPolySize = polytomized->GetChild(0)->GetNbChildren();
                    info.secondPolySize = polytomized->GetChild(1)->GetNbChildren();
                    this->SolvePolytomy(polytomized->GetChild(0), speciesTree, polytomizedWithMapping.second);
                    this->SolvePolytomy(polytomized->GetChild(1), speciesTree, polytomizedWithMapping.second);

                    //cout<<"CORRECTED = "<<NewickLex::ToNewickString(geneTreeCopy)<<endl;

                    geneTreeCopy->DeleteSingleChildDescendants();

                    info.correction = geneTreeCopy;

                    return info;
                }
            }
        }
    }
    geneTreeCopy->CloseIterator(it);

    //if we got here, we found no NAD, and since we didn't do anything we return NULL
    delete geneTreeCopy;

    PolySolverCorrectionInfo info;
    info.correction = NULL;
    return info;
}
예제 #16
0
PolySolverCorrectionInfo PolySolverNAD::CorrectNodeByMultifurcation(Node* geneTree, Node* speciesTree, unordered_map<Node*, Node*> geneLeavesSpeciesMapping, Node* n)
{
    //TODO : code copied from above

    unordered_map<Node*, Node*> oldlcaMapping = GeneSpeciesTreeUtil::Instance()->GetLCAMapping(geneTree, speciesTree, geneLeavesSpeciesMapping);
    unordered_map<Node*, Node*> lcaMapping;

    //here we'll copy the original gene tree and manage to find the node of interest in this copy
    string prevLabel = n->GetLabel();
    string tempLabel = "temp-label-no-one-else-should-use";
    n->SetLabel(tempLabel);
    Node* geneTreeCopy = GeneSpeciesTreeUtil::Instance()->CopyTreeWithNodeMapping(geneTree, oldlcaMapping, lcaMapping);
    n->SetLabel(prevLabel);

    //find the node of interest
    Node* node_to_correct = NULL;
    TreeIterator* it = geneTreeCopy->GetPostOrderIterator();
    while (Node* ncopy = it->next())
    {
        if (ncopy->GetLabel() == tempLabel)
        {
            node_to_correct = ncopy;
            node_to_correct->SetLabel(prevLabel);
            break;
        }

    }
    geneTreeCopy->CloseIterator(it);

    vector<string> leafLabels;
    vector<Node*> n_leaves = node_to_correct->GetLeafVector();
    for (int i = 0; i < n_leaves.size(); i++)
    {
        leafLabels.push_back(n_leaves[i]->GetLabel());
    }

    pair<Node*, unordered_map<Node*, Node*> > polytomizedWithMapping = PolytomizeNAD(node_to_correct, speciesTree, lcaMapping);
    Node* polytomized = polytomizedWithMapping.first;


    //replace the subtree that just got polytomized
    if (!node_to_correct->IsRoot())
    {
        Node* parent = node_to_correct->GetParent();
        parent->RemoveChild(node_to_correct);
        parent->AddSubTree(polytomized);
        delete node_to_correct;
    }
    else
    {
        delete geneTreeCopy;
        geneTreeCopy = polytomized;
    }


    PolySolverCorrectionInfo info;
    info.nadCladeGenes = leafLabels;
    info.firstPolySize = polytomized->GetChild(0)->GetNbChildren();
    info.secondPolySize = polytomized->GetChild(1)->GetNbChildren();
    this->SolvePolytomy(polytomized->GetChild(0), speciesTree, polytomizedWithMapping.second);
    this->SolvePolytomy(polytomized->GetChild(1), speciesTree, polytomizedWithMapping.second);


    geneTreeCopy->DeleteSingleChildDescendants();

    info.correction = geneTreeCopy;

    return info;
}
예제 #17
0
Node* PolySolverNAD::SolvePolytomy(vector<Node*> leaves, Node* speciesTree, unordered_map<Node*, Node*> &lcaMapping)
{


    SADNADGraph graph;
    graph.BuildGraph(leaves, speciesTree, lcaMapping);



    //successively apply lowest useful speciations
    TreeIterator* sit = speciesTree->GetPostOrderIterator();
    while (Node* s = sit->next())
    {
        //gLeft : the nodes of leaves with a species on the left of s
        //gRight : the nodes of leaves with a species on the right of s
        //gTaken : the nodes already used in a speciation
        set<Node*> gLeftGuys, gRightGuys, gTaken;
        if (!s->IsLeaf())
        {
            Node* sLeft = s->GetChild(0);
            Node* sRight = s->GetChild(1);

            //This could be optimized, but code is simpler and more easily modifiable by just beginning by building sLeft and sRight
            const map<Node*, SADNADNode*> graphNodes = graph.GetNodes();
            for (map<Node*, SADNADNode*>::const_iterator graphIt = graphNodes.begin(); graphIt != graphNodes.end(); graphIt++)
            {
                Node* g = (*graphIt).first;
                if (!lcaMapping[g])
                {
                    cout<<"CRITICAL PROBLEM "<<g->GetLabel();
                    cout<<endl;
                }

                if (lcaMapping[g] == sLeft || lcaMapping[g]->HasAncestor(sLeft))
                {
                    gLeftGuys.insert(g);
                }
                else if (lcaMapping[g] == sRight || lcaMapping[g]->HasAncestor(sRight))
                {
                    gRightGuys.insert(g);
                }

            }


            //make speciations GREEDILY
            /*for (set<Node*>::iterator itLeft = gLeftGuys.begin(); itLeft != gLeftGuys.end(); itLeft++)
            {
                bool wasJoined = false;
                Node* gLeft = (*itLeft);
                for (set<Node*>::iterator itRight = gRightGuys.begin(); itRight != gRightGuys.end(); itRight++)
                {
                    if (!wasJoined)
                    {
                        Node* gRight = (*itRight);

                        //useful spec x y : x y not in same component, y not already used
                        if ( gTaken.find(gRight) == gTaken.end() && !graph.HaveSameADComponent(gLeft, gRight))
                        {
                            Node* newNode = gLeft->InsertParentWith(gRight);
                            lcaMapping[newNode] = s;
                            graph.MergeNodes(gLeft, gRight, newNode, lcaMapping);
                            gTaken.insert(gRight);
                            wasJoined = true;
                        }
                    }
                }
            }*/

            this->SpeciateCleverly(graph, gLeftGuys, gRightGuys, s, lcaMapping);
            gLeftGuys.clear();
            gRightGuys.clear();
        }
    }
    speciesTree->CloseIterator(sit);


    last_nb_ad_components = graph.GetNbADComponents();

    //OK then...from here, we've made all the useful speciations we could.
    //Next, we merge AD nodes
    //TODO : here, we do this the ugly way
    bool thereIsAnAD = true;
    while (thereIsAnAD)
    {
        thereIsAnAD = false;

        Node* chosenNode = NULL;
        Node* chosenFriend = NULL;
        const map<Node*, SADNADNode*> graphNodes = graph.GetNodes();
        for (map<Node*, SADNADNode*>::const_iterator it = graphNodes.begin(); it != graphNodes.end(); it++)
        {
            Node* n = (*it).first;
            SADNADNode* sad = (*it).second;

            if (sad->AD_Neighbors.size() > 0)
            {
                chosenFriend = (*sad->AD_Neighbors.begin());
                chosenNode = n;
                thereIsAnAD = true;
            }
        }

        if (thereIsAnAD)
        {
            Node* newNode = chosenNode->InsertParentWith(chosenFriend);
            lcaMapping[newNode] = lcaMapping[chosenNode]->FindLCAWith(lcaMapping[chosenFriend]);
            graph.MergeNodes(chosenNode, chosenFriend, newNode, lcaMapping);
        }

    }


    //TODO : the NAD
    //And then, if we get here, we don't have a choice but to create NADs
    while (graph.GetNodes().size() > 1)
    {
        const map<Node*, SADNADNode*> graphNodes = graph.GetNodes();
        map<Node*, SADNADNode*>::const_iterator it = graphNodes.begin();

        Node* n1 = (*it).first;
        it++;
        Node* n2 = (*it).first;
        Node* newNode = n1->InsertParentWith(n2);
        lcaMapping[newNode] = lcaMapping[n1]->FindLCAWith(lcaMapping[n2]);
        graph.MergeNodes(n1, n2, newNode, lcaMapping);
    }




    return (*graph.GetNodes().begin()).first;
}
예제 #18
0
pair<Node*, Node*> PolySolverNAD::GetRandomPolytomy(int k, int verbose)
{
    Node* speciesTree = new Node(false);

    double s_size_factor = 2.5 * (double)(rand() % 1000)/1000.0 + 0.5;  //between 0.5 and 3

    for (int i = 0; i < s_size_factor*k; i++)
    {
        Node* c = speciesTree->AddChild();
        c->SetLabel("S" + Util::ToString(i));
    }

    speciesTree->BinarizeRandomly();

    //get an ordering of the internal nodes...this will let us pick one at random
    vector<Node*> internalNodes;

    TreeIterator* it = speciesTree->GetPostOrderIterator(false);
    while (Node* s = it->next())
    {
        if (!s->IsLeaf())
        {
            internalNodes.push_back(s);
        }

    }
    speciesTree->CloseIterator(it);

    //generate k gene subtrees
    unordered_map<Node*, Node*> lcaMapping;
    vector<Node*> forest;
    map<Node*, Node*> geneLeftSpecies;
    map<Node*, Node*> geneRightSpecies;

    for (int i = 0; i < k; i++)
    {
        Node* g = new Node(false);
        g->SetLabel("G" + Util::ToString(i));

        //pick an lca for g at random
        Node* lca = internalNodes[rand() % internalNodes.size()];
        lca->SetLabel(lca->GetLabel() + "_" + Util::ToString(i));
        lcaMapping[g] = lca;

        //add something left and right to enforce s(g) = lca
        //by adding a species specific to g on both sides
        bool done = false;
        TreeIterator* itLeft = lca->GetChild(0)->GetPostOrderIterator();
        while (Node* s = itLeft->next())
        {
            if (!done)
            {
                string slbl = s->GetLabel();
                if (slbl[0] == 'S') //got an original species leaf
                {
                    Node* sg = s->AddChild();
                    sg->SetLabel("XL" + Util::ToString(i));

                    Node* gs = g->AddChild();
                    gs->SetLabel("XL" + Util::ToString(i));

                    lcaMapping[gs] = sg;
                    done = true;

                    geneLeftSpecies[g] = s;
                }
            }
        }
        lca->CloseIterator(itLeft);


        done = false;
        TreeIterator* itRight = lca->GetChild(1)->GetPostOrderIterator();
        while (Node* s = itRight->next())
        {
            if (!done)
            {
                string slbl = s->GetLabel();
                if (slbl[0] == 'S') //got an original species leaf
                {
                    Node* sg = s->AddChild();
                    sg->SetLabel("XR" + Util::ToString(i));

                    Node* gs = g->AddChild();
                    gs->SetLabel("XR" + Util::ToString(i));

                    lcaMapping[gs] = sg;
                    done = true;

                    geneRightSpecies[g] = s;
                }
            }
        }
        lca->CloseIterator(itRight);

        forest.push_back(g);
    }

    int AD_prob = rand() % 50 + 25; //between 25-75% chances of having a dup

    //ok, we have a forest.  Now, everything is either S or NAD (no species are shared since we created one specific to each gene)
    //so here we add a couple AD
    for (int i = 0; i < forest.size(); i++)
    {
        Node* g1 = forest[i];
        Node* s1 = lcaMapping[g1];
        for (int j = i + 1; j < forest.size(); j++)
        {
            Node* g2 = forest[j];
            Node* s2 = lcaMapping[g2];

            //they're related...make them AD if we're lucky enough
            if (s1->HasAncestor(s2) || s2->HasAncestor(s1))
            {
                int r = rand() % 100;

                //add a species near the g1left species s.t. g1 and g2 will share a gene of this species
                if (r < AD_prob)
                {
                    Node* s_to_add_to = geneLeftSpecies[g1];
                    if (!s1->HasAncestor(s2))
                        s_to_add_to = geneLeftSpecies[g2];

                    Node* dspecies = s_to_add_to->AddChild();
                    dspecies->SetLabel("AD_" + g1->GetLabel() + "_" + g2->GetLabel());

                    Node* newg1 = g1->AddChild();
                    newg1->SetLabel(dspecies->GetLabel());
                    lcaMapping[newg1] = dspecies;

                    Node* newg2 = g2->AddChild();
                    newg2->SetLabel(dspecies->GetLabel());
                    lcaMapping[newg2] = dspecies;
                }
            }
        }
    }



    //if everything was done correctly, binarizing S
    speciesTree->BinarizeRandomly();
    speciesTree->DeleteSingleChildDescendants();

    string sstr = NewickLex::ToNewickString(speciesTree);
    if (verbose > 0)
        cout<<"S="<<sstr<<endl;

    Node* poly = new Node(false);
    for (int i = 0; i < forest.size(); i++)
    {
        forest[i]->BinarizeRandomly();


        poly->AddSubTree(forest[i]);
    }

    string gstr = NewickLex::ToNewickString(poly);
    if (verbose > 0)
        cout<<"G="<<"="<<gstr<<endl;


    //we have to recreate the species tree, or later on lca mapping will get messed up FOR UNKNOWN REASONS !
    string spNewick = NewickLex::ToNewickString(speciesTree);
    delete speciesTree;

    speciesTree = NewickLex::ParseNewickString(spNewick, true);

    lcaMapping.clear();

    return make_pair(poly, speciesTree);
}