Exemple #1
0
void testParse2()
{
    IntegerSet a;

    a.parse(" [-3,2] 5  8-9 10- ");  // insert(-3,2); insert(5); insert(8,9); insert(10,INT_MAX);

    unit_assert(a.intervalCount() == 3);
    unit_assert(a.size() == 9ul + numeric_limits<int>::max()-10+1);

    vector<int> b;
    IntegerSet::const_iterator it = a.begin();
    for (int i=0; i<11; ++i, ++it) // don't copy to the end() unless you have lots of time and space ;)
        b.push_back(*it);

    unit_assert(b.size() == 11);
    unit_assert(b[0] == -3);
    unit_assert(b[1] == -2);
    unit_assert(b[2] == -1);
    unit_assert(b[3] == 0);
    unit_assert(b[4] == 1);
    unit_assert(b[5] == 2);
    unit_assert(b[6] == 5);
    unit_assert(b[7] == 8);
    unit_assert(b[8] == 9);
    unit_assert(b[9] == 10);
    unit_assert(b[10] == 11);
}
Exemple #2
0
void testParse()
{
    IntegerSet a;

    a.parse(" [-3,2] [5,5] [8,9] booger ");  // insert(-3,2); insert(5); insert(8,9);

    unit_assert(a.intervalCount() == 3);
    unit_assert(a.size() == 9);

    vector<int> b;
    copy(a.begin(), a.end(), back_inserter(b));
    unit_assert(b.size() == 9);
    unit_assert(b[0] == -3);
    unit_assert(b[1] == -2);
    unit_assert(b[2] == -1);
    unit_assert(b[3] == 0);
    unit_assert(b[4] == 1);
    unit_assert(b[5] == 2);
    unit_assert(b[6] == 5);
    unit_assert(b[7] == 8);
    unit_assert(b[8] == 9);
}
Exemple #3
0
SetRelations Relationship (IntegerSet &one, IntegerSet &two)
{
	SetRelations result;

/*        cout << " {";
        std::copy (one.begin(), one.end(),
                std::ostream_iterator<int>(cout, " "));
        cout << "}";

       cout << " {";
        std::copy (two.begin(), two.end(),
                std::ostream_iterator<int>(cout, " "));
        cout << "}";
*/
    if (one == two)
    	result = IDENTITY;
    else if (std::includes (two.begin(), two.end(), one.begin(), one.end()))
    	result = SUBSET; // one is a subset of two
    else if (std::includes (one.begin(), one.end(), two.begin(), two.end()))
    	result = SUPERSET; // two is a subset of one
    else
    {
        IntegerSet common;
        std::set_intersection (one.begin(), one.end(),
            two.begin(), two.end(),
            std::inserter (common, common.end()));
        if (common.size() == 0)
        	result = DISJOINT;
        else
        	result = OVERLAPPING;
    }

//    cout << "result=" << result << endl;

    return result;
}
Exemple #4
0
//------------------------------------------------------------------------------
// Add cluster to a tree
int NTree::AddCluster (IntegerSet &b, char *label)
{
	Error = 0;
	int n = b.size();
	if (n > 1 && n < ((NNodePtr)Root)->Cluster.size())
	{
		// non trivial set
		NNodePtr p = (NNodePtr)Root;
		NNodePtr q = (NNodePtr)(p->GetChild());
        bool done = false;
		SetRelations r;

		// locate insertion point
		while (q && !done)
		{
			r = Relationship (b, q->Cluster);

			switch (r)
			{
				case IDENTITY:
					done = true;
					Error = 1; // we already have this cluster
					break;

				case SUBSET:
					p = q;
					q = (NNodePtr)(q->GetChild());
					break;

				case DISJOINT:
					p = q;
					q = (NNodePtr)(q->GetSibling());
					break;

				case SUPERSET:
					done = true;
					break;

				case OVERLAPPING:
					done = true;
					Error = 2; // can't be a part of a tree
					break;

				default:
					break;
			}
		}

		if (Error == 0)
		{
			// Create node
			NNodePtr nunode = (NNodePtr)NewNode ();
			Internals++;
			nunode->SetWeight(n);
			nunode->Cluster = b;

			if (label)
				nunode->SetLabel (label);


			// Insert node in tree
			switch (r)
			{
				case SUBSET:
                	p->SetChild (nunode);
                    nunode->SetAnc (p);
					break;

				case DISJOINT:
					p->SetSibling (nunode);
                    nunode->SetAnc (p->GetAnc());
					break;

				case SUPERSET:
					if (q == p->GetChild())
					{
                    	p->SetChild (nunode);
                        nunode->SetChild (q);
                        nunode->SetAnc (p);
                        q->SetAnc (nunode);
					}
					else
					{
	                   	p->SetSibling (nunode);
                        nunode->SetChild (q);
                        nunode->SetAnc (p->GetAnc());
                        q->SetAnc (nunode);
					}

                    NNodePtr tmp = q;
                    NNodePtr s = (NNodePtr)(q->GetSibling());
                    NNodePtr t = (NNodePtr)(q->GetAnc());

                    while (s)
                    {
                    	r = Relationship (s->Cluster, b);
                        if ((r == IDENTITY) || (r == SUBSET))
                        {
                        	s->SetAnc(nunode);
                            tmp = s;
                            s = (NNodePtr)(s->GetSibling());
                        }
                        else
                        {
                        	t->SetSibling (s);
                            tmp->SetSibling (s->GetSibling());
                            t = s;
                            t->SetSibling (NULL);
                            s = (NNodePtr)(tmp->GetSibling());
                       }
                    }
                    break;

//					checkSiblings (q, nunode->cluster);
				}
//			nunode->GetDegreeOf ();
//			nunode->anc->degree = nunode->degree - nunode->degree - 1;
		}
	}
	return Error;
}
Exemple #5
0
int MAST (NTree &T1, NTree &T2)
{
	int result = 0;

	// 1. create lists of the nodes in T1 and T2 in postorder
    int count = 0;
    NodeVector pot1;
    NodeIterator <Node> n1 (T1.GetRoot());
    Node *q = n1.begin();
    while (q)
    {
    	q->SetIndex (count);
		pot1.push_back ((NNode *)q);
		count++;
		q = n1.next();
    }

    count = 0;
    NodeVector pot2;
    NodeIterator <Node> n2 (T2.GetRoot());
    q = n2.begin();
    while (q)
    {
    	q->SetIndex (count);
		pot2.push_back ((NNode *)q);
		count++;
        q = n2.next();
    }

	// Matrix to hold solutions
    int **m;

    m = new int *[T1.GetNumNodes()];
    for (int i = 0; i < T1.GetNumNodes(); i++)
    	m[i] = new int [T2.GetNumNodes()];

    for (int i = 0; i < T1.GetNumNodes(); i++)
    	for (int j = 0; j <T2.GetNumNodes(); j++)
        	m[i][j] = 0;


	// 2. Visit all pairs of nodes in T1 and T2
     for (int i = 0; i < T1.GetNumNodes(); i++)
     {
    	for (int j = 0; j <T2.GetNumNodes(); j++)
        {
			if (pot1[i]->IsLeaf() || pot2[j]->IsLeaf())
            {
            	// Both are leaves, so MAST[i,j] is 1 if labels are identical
            	if (pot1[i]->IsLeaf() && pot2[j]->IsLeaf())
				{
                	if ( pot1[i]->GetLabel() == pot2[j]->GetLabel())
                    	m[i][j] = 1;
				}
				else
				{
            		// Only one is a leaf, so MAST[i,j] is 1 if leaf is element in cluster
					IntegerSet common;
					std::set_intersection (pot1[i]->Cluster.begin(), pot1[i]->Cluster.end(),
						pot2[j]->Cluster.begin(), pot2[j]->Cluster.end(),
						std::inserter (common, common.end()));
					int w = common.size();
                	m[i][j] = w;
				}
        	}
            else
            {
            	// Both are internals so MAST[i,j] is MAX (diag, match)
                std::vector <NodePtr> pchildren, qchildren;

                // diag
                int diag = 0;

                // Get MAST of base of subtree in t1 and immediate children of
                // base of subtree in t2, and at the same time store list of
                // immediate children
                NodePtr p = pot2[j]->GetChild();
                while (p)
                {
                	qchildren.push_back(p);
                	diag = std::max (diag, m[i][p->GetIndex()]);
                    p = p->GetSibling();
                }
                // get MAST of base of subtree in t2 and immediate children of
                // base of subtree in t1, and at the same time store list of
                // immediate children
                NodePtr q = pot1[i]->GetChild();
                while (q)
                {
                	pchildren.push_back(q);
                	diag = std::max (diag, m[q->GetIndex()][j]);
                    q = q->GetSibling();
                }

                // maximum weighted bipartite matching
				
#if USE_MATCHING
				int match = 0;
				graph g;
				g.make_directed();
				
				// Nodes for p and q children
				map <int, node, less <int> > p_node;
				map <int, node, less <int> > q_node;
				for (int k = 0; k < pchildren.size(); k++)
                {
					node n = g.new_node();
					p_node[k] = n;
                }
				for (int k = 0; k < qchildren.size(); k++)
                {
					node n = g.new_node();
					q_node[k] = n;
                }
				// Edges
				edge_map<int> weights(g, 0);

				
				for (int k = 0; k < pchildren.size(); k++)
				{
					for (int r = 0; r < qchildren.size(); r++)
					{
						int v = pchildren[k]->GetIndex();
                        int w = qchildren[r]->GetIndex();
						
						// It seems that if the partition "from" is much larger than "to,
						// the matching algorithm can blow up with a memory access error
						// in fheap.c. Reversing the graph seems to help.
						
						edge e;
						if (pchildren.size() < qchildren.size())
							e = g.new_edge (p_node[k], q_node[r]);
						else
							e = g.new_edge (q_node[r], p_node[k]);
						
						weights[e] = m[v][w];
					}
				}
				
//				cout << "g" << endl;
//				cout << g;
//				g.save();
//				cout << "Start matching...";
				
				if (g.number_of_nodes() == 0)
				{
					match = 0;
				}
				
				else
				{
				
				mwbmatching mwbm;
				mwbm.set_vars (weights);
				
				if (mwbm.check(g) != algorithm::GTL_OK)
				{
					cout << "Maximum weight bipartite matching algorithm check failed" << endl;
					exit(1);
				}
				else
				{
					if (mwbm.run(g) != algorithm::GTL_OK)
					{
						cout << "Error running maximum weight bipartite matching algorithm" << endl;
						exit(1);
					}
					else
					{
						match = mwbm.get_mwbm();
					}
				}
				}
//				cout << "matching done (" << match << ")" << endl;
#else
                // For now (sigh) brute force generation of all matchings. Eventually
                // will need to do this more efficiently
                int n = std::max (pchildren.size(), qchildren.size());

                // Store a vector of indices of children of subtree in t2.
                // We will permute this to generate all matchings. If t2
                // has fewer children than subtree in t1, vector will contain
                // one or more "null" (-1) values.
                std::vector <int> perm;
                for (int k = 0; k < n; k++)
                {
                	if (k < qchildren.size())
	                	perm.push_back (k);
                    else
                    	perm.push_back (-1);
                }

                // Generate all matchings

                // First matching
                int match = 0;
               	for (int k = 0; k < n; k++)
                {
                    if ((k < pchildren.size()) && (perm[k] != -1))
                    {
                    	int v = pchildren[k]->GetIndex();
                        int w = qchildren[perm[k]]->GetIndex();
                        match += m[v][w];
                    }
                }

                // Remaining matchings
                while  (next_permutation (perm.begin(), perm.end()) )
                {
                	int this_match = 0;
                    for (int k = 0; k < n; k++)
                    {
                        if ((k < pchildren.size()) && (perm[k] != -1))
                        {
                            int v = pchildren[k]->GetIndex();
                            int w = qchildren[perm[k]]->GetIndex();
                            this_match += m[v][w];
                        }
                    }
                    match = std::max (match, this_match);
                }
#endif
                m[i][j] = std::max (diag, match);
            }
		}
     }

     result = m[T1.GetNumNodes() - 1][T2.GetNumNodes() - 1];
	 
	 // Show matrix
/*	 for (int i = 0; i < T1.GetNumNodes(); i++)
	 {
	 	cout << setw(3) << i << "|";
		for (int j = 0; j < T2.GetNumNodes(); j++)
			cout << setw(3) << m[i][j];
		cout << endl;
	}
*/

     // clean up
    for (int i = 0; i < T1.GetNumNodes(); i++)
       	delete [] m[i];

    delete [] m;

	return result;
}