Beispiel #1
0
// return all p3 in p3_set with (*,*,v)
set<t_3path> t_dir_graph::get_p3_by_third(const t_vertex& v) const{
	set<t_vertex> pred, predpred;
	set<t_3path> result;
	pred = get_predecessors(v);
	for(set<t_vertex>::const_iterator u = pred.begin(); u!= pred.end(); u++){
		predpred = get_predecessors(*u);
		for(set<t_vertex>::const_iterator w = predpred.begin(); w!= predpred.end(); w++)
			if(p3_set.find(t_3path(t_arc(*w,*u),t_arc(*u,v))) != p3_set.end())
				result.insert(t_3path(t_arc(*w,*u),t_arc(*u,v)));
	}
	return result;
}
Beispiel #2
0
// mark an arc forbidden/permanent,
// note that, if adjacent arcs are also forbidden/permanent, this mark may cascade
bool t_dir_graph::mark_arc(const t_arc& a, const uint mark){
	if(successors.find(a.first) == successors.end()) return false; // dont mark edges that are not in VxV
	if(successors.find(a.second) == successors.end()) return false; // dont mark edges that are not in VxV
	dbgcout << "marking " << a << (mark==MRK_NONE?"none":(mark==MRK_FORBIDDEN?"forbidden":"permanent")) << "\n";
	bool result = true;
	switch(mark){
		case MRK_NONE:
			return (forbidden_arcs.erase(a) || permanent_arcs.erase(a));
			break;
		case MRK_FORBIDDEN:
			if((!contains_arc(a)) && (forbidden_arcs.find(a) == forbidden_arcs.end())
					&& forbidden_arcs.insert(a).second) {
				set<t_vertex> belt = set_intersect(get_successors(a.first), get_predecessors(a.second));
				for(set<t_vertex>::iterator u = belt.begin(); u != belt.end(); u++){
					if(permanent_arcs.find(t_arc(a.first, *u)) != permanent_arcs.end())
						result &= mark_arc(t_arc(*u, a.second), MRK_FORBIDDEN);
					if(permanent_arcs.find(t_arc(*u, a.second)) != permanent_arcs.end())
						result &= mark_arc(t_arc(a.first, *u), MRK_FORBIDDEN);
				}
				return result;
			} else return false;
			break;
		case MRK_PERMANENT:
			if(contains_arc(a) && (permanent_arcs.find(a) == permanent_arcs.end())
					&& permanent_arcs.insert(a).second) {
				set<t_vertex> pred = get_predecessors(a.first);
				for(set<t_vertex>::iterator u = pred.begin(); u != pred.end(); u++){
					if(permanent_arcs.find(t_arc(*u, a.first)) != permanent_arcs.end())
						result &= mark_arc(t_arc(*u, a.second), MRK_PERMANENT);
				}
				pred = set_substract(get_vertices(), get_predecessors(a.second));
				for(set<t_vertex>::iterator u = pred.begin(); u != pred.end(); u++){
					if(forbidden_arcs.find(t_arc(*u, a.second)) != forbidden_arcs.end())
						result &= mark_arc(t_arc(*u, a.second), MRK_FORBIDDEN);
				}
				set<t_vertex> succ = get_successors(a.second);
				for(set<t_vertex>::iterator u = succ.begin(); u != succ.end(); u++){
					if(permanent_arcs.find(t_arc(a.second, *u)) != permanent_arcs.end())
						result &= mark_arc(t_arc(a.first, *u), MRK_PERMANENT);
				}
				succ = set_substract(get_vertices(), get_successors(a.first));
				for(set<t_vertex>::iterator u = succ.begin(); u != succ.end(); u++){
					if(forbidden_arcs.find(t_arc(a.first, *u)) != forbidden_arcs.end())
						result &= mark_arc(t_arc(a.second, *u), MRK_FORBIDDEN);
				}
				return result;
			} else return false;
			break;
		default: return false;
	}	
}
Beispiel #3
0
// return all p3 in p3_set with (*,v,*)
set<t_3path> t_dir_graph::get_p3_by_middle(const t_vertex& v) const{
	set<t_vertex> succ, pred;
	set<t_3path> result;
	succ = get_successors(v);
	pred = get_predecessors(v);
	for(set<t_vertex>::const_iterator u = pred.begin(); u!= pred.end(); u++)
		for(set<t_vertex>::const_iterator w = succ.begin(); w!= succ.end(); w++)
			if(p3_set.find(t_3path(t_arc(*u,v),t_arc(v,*w))) != p3_set.end())
				result.insert(t_3path(t_arc(*u,v),t_arc(v,*w)));
	return result;
}
Beispiel #4
0
// increase the belt size of the given diamond
// O(log n)
void t_dir_graph::increase_diamond(const t_diamond& diam){
	map<t_diamond, uint>::iterator d_iter = diamond_set.find(diam);
//	cout << "increasing diamond-belt of "<<diam<<"\n";
	if(d_iter != diamond_set.end()){
		d_iter->second++;
	} else {// if its not there, maybe it should be inserted...
		// this intersection can be calced in O(1), otherwise, diam would have been in diamond_set !
		set<t_vertex> belt = set_intersect(get_successors(diam.first), get_predecessors(diam.second));
//		cout << "oops, not yet there, "<<diam<<" is "<<(belt.size()>1?"":"not ")<<"inserted (size "<<belt.size()<<")\n";
		if(belt.size() > 1)
			diamond_set.insert(pair<t_diamond,uint>(diam, belt.size()));
	}
}
Beispiel #5
0
// insert an arc
// O(n log n)
bool t_dir_graph::insert_arc(const t_arc& a, const bool permanent){
	if(successors.find(a.second) == successors.end()) return false; // dont insert edges that are not in VxV
	if(predecessors.find(a.first) == predecessors.end()) return false; // dont insert edges that are not in VxV
	if(forbidden_arcs.find(a) != forbidden_arcs.end()) return false; // dont insert if the arc is forbidden
	t_adjtable::iterator i = successors.find(a.first);
	t_adjtable::iterator j = predecessors.find(a.second);
	if((i != successors.end()) && (j != predecessors.end()))
		if(i->second.insert(a.second).second)
			if(j->second.insert(a.first).second){
				if(permanent) mark_arc(a, MRK_PERMANENT);

				// update p3_set and diamond_set
				// first, remove all p3 destroyed by a
				set<t_vertex> belt = set_intersect(i->second,j->second);
				for(set<t_vertex>::const_iterator u = belt.begin(); u != belt.end(); u++)
					p3_set.erase(t_3path(t_arc(a.first, *u),t_arc(*u, a.second)));
				diamond_set.erase(t_diamond(a.first, a.second));

				// second, add new P3 and diamonds
				// u -> a.first -> a.second
				set<t_vertex> pred = set_substract(get_predecessors(a.first), j->second);
				pred.erase(a.second);
				for(set<t_vertex>::const_iterator u = pred.begin(); u != pred.end(); u++){
					increase_diamond(t_diamond(*u, a.second));
					p3_set.insert(t_3path(t_arc(*u,a.first),a));
				}

				// a.first -> a.second -> u
				set<t_vertex> succ = set_substract(get_successors(a.second), i->second);
				succ.erase(a.first);
				for(set<t_vertex>::const_iterator u = succ.begin(); u != succ.end(); u++){
					increase_diamond(t_diamond(a.first, *u));
					p3_set.insert(t_3path(a,t_arc(a.second, *u)));
				}
				return true;
			} else {// avoid inconsistency
				i->second.erase(a.second);
				return false;
			}
		else return false;
	else return false;
}
Beispiel #6
0
// calculate the reachability of v in D
// if undirected is true, all vertices can reach their predecessors
set<t_vertex> t_dir_graph::get_reachable(const t_vertex& v, bool undirected) const{
	if(contains_vertex(v)){
		set<t_vertex> to_check, checked, neighbors;
		t_vertex u;

		to_check.insert(v);
		while(!to_check.empty()){
			u = *(to_check.begin());
			to_check.erase(to_check.begin());
			
			neighbors = get_successors(u);
			if(undirected) neighbors = set_unite(neighbors, get_predecessors(u));
			
			neighbors = set_substract(neighbors, checked);
			to_check = set_unite(to_check, neighbors);

			checked.insert(u);
		}
		return checked;
	} else return set<t_vertex>();
}
Beispiel #7
0
// delete an arc
// O(n log n)
bool t_dir_graph::delete_arc(const t_arc& a, const bool forbidden){
	if(permanent_arcs.find(a) != permanent_arcs.end()) return false; // dont delete if the arc is permanent
	t_adjtable::iterator i = successors.find(a.first);
	t_adjtable::iterator j = predecessors.find(a.second);
	if((i != successors.end()) && (j != predecessors.end()))
		if(i->second.erase(a.second))
			if(j->second.erase(a.first)){
				if(forbidden) mark_arc(a, MRK_FORBIDDEN);
				// update p3_set and diamond_set

				// first, remove all p3 destroyed by a
				// u -> a.first -> a.second
				set<t_vertex> pred = set_substract(get_predecessors(a.first), j->second);
				pred.erase(a.second);
				for(set<t_vertex>::const_iterator u = pred.begin(); u != pred.end(); u++){
					decrease_diamond(t_diamond(*u,a.second));
					p3_set.erase(t_3path(t_arc(*u,a.first),t_arc(a.first, a.second)));
				}

				// a.first -> a.second -> u
				set<t_vertex> succ = set_substract(get_successors(a.second), i->second);
				succ.erase(a.first);
				for(set<t_vertex>::const_iterator u = succ.begin(); u != succ.end(); u++){
					decrease_diamond(t_diamond(a.first, *u));
					p3_set.erase(t_3path(t_arc(a.first, a.second),t_arc(a.second, *u)));
				}

				// second, add new P3 and diamonds
				set<t_vertex> belt = set_intersect(i->second,j->second);
				for(set<t_vertex>::const_iterator u = belt.begin(); u != belt.end(); u++)
					p3_set.insert(t_3path(t_arc(a.first, *u),t_arc(*u, a.second)));
				if(belt.size()>1)
					diamond_set.insert(
							pair<t_diamond,uint>(t_diamond(a.first,a.second),belt.size())
						);
				return true;
			} else return false;
		else return false;
	else return false;
}
Beispiel #8
0
// get all neighbors of v, that is successors and predecessors
set<t_vertex> t_dir_graph::get_neighbors(const t_vertex& v) const{
	return set_unite(get_predecessors(v), get_successors(v));
}
Beispiel #9
0
int main(int argc, char **argv) {
    char word[MAXWORDSIZE];
    char cmd[MAXWORDSIZE];   /* string to hold a command */
    char fname[MAXWORDSIZE]; /* name of input file */
    PAGENO i;
    int goOn;
    int  k;

    setparms(); /* reads the pagesize and the number of ptrs/postigs_record */
    dbopen();   /* opens or creates the three files (btree, postings, text) */

    goOn = TRUE;
    while (goOn) {
        printf("\n\t*** These are your commands .........\n");
        printf("\t\"C\" to scan the tree\n");
        printf("\t\"i\" to insert\n");
        printf("\t\"p\" to print a btree page\n");
        printf("\t\"s\" to search, and print the key\n");
        printf("\t\"S\" to search, and print the key, posting list pairs\n");
        printf("\t\">\" to print k successors\n");
        printf("\t\"<\" to print k predecessors\n");
        printf("\t\"T\" to print the btree in inorder format\n");
        printf("\t\"#\" to reset and print stats\n");
        printf("\t\"x\" to exit\n");
        /* printf("\"d\" to display statistics, \"c\" to clear them,\n"); */
        scanf("%s", cmd);
        assert(strlen(cmd) < MAXWORDSIZE);
        switch (cmd[0]) {
        case 'C':
            printf("\n*** Scanning... \n");
            scanTree(&printOcc);
            break;
        case 'i':
            printf("\tgive input file name: ");
            scanf("%s", fname);
            assert(strlen(fname) < MAXWORDSIZE);
            printf("\n*** Inserting %s\n", fname);
            insert(fname);
            break;
        case 's':
            printf("enter search-word: ");
            scanf("%s", word);
            assert(strlen(word) < MAXWORDSIZE);
            printf("\n*** Searching for word %s \n", word);
            search(word, FALSE);
            break;
        case 'S':
            printf("enter search-word: ");
            scanf("%s", word);
            assert(strlen(word) < MAXWORDSIZE);
            printf("\n*** Searching for word %s \n", word);
            search(word, TRUE);
            break;
        case 'p':
            printf("pagenumber=?\n");
            scanf("%s", cmd);
            assert(strlen(cmd) < MAXWORDSIZE);
            i = (PAGENO) atoi(cmd);
            printPage(i, fpbtree);
            break;
        case '>':
            printf("word=?\n");
            scanf("%s", word);
            printf("k=?\n");
            scanf("%d", &k);
            get_successors(word, k, NULL);
            break;
        case '<':
            printf("word=?\n");
            scanf("%s", word);
            printf("k=?\n");
            scanf("%d", &k);
            get_predecessors(word, k, NULL);
            break;
        case 'T':
            printf("\n*** Printing tree in order .........\n");
            PrintTreeInOrder(ROOT, 0);
            break;
        case '#':
            printf("\n");
            printFetchPageCnt();
            printf("\n...reseted FetchPage counter\n");
            break;
        case 'x':
            printf("\n*** Exiting .........\n");
            goOn = FALSE;
            break;
        default:
            printf("\n*** Illegal command \"%s\"\n", cmd);
            break;
        }
    }

    dbclose();
    return (0);
}