Esempio n. 1
0
	flowtype Graph<captype,tcaptype,flowtype>::maxflow(bool reuse_trees, Block<node_id>* _changed_list)
{
	node *i, *j, *current_node = NULL;
	arc *a;
	nodeptr *np, *np_next;

	if (!nodeptr_block)
	{
		nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function);
	}

	changed_list = _changed_list;
	if (maxflow_iteration == 0 && reuse_trees) { if (error_function) (*error_function)("reuse_trees cannot be used in the first call to maxflow()!"); exit(1); }
	if (changed_list && !reuse_trees) { if (error_function) (*error_function)("changed_list cannot be used without reuse_trees!"); exit(1); }

	if (reuse_trees) maxflow_reuse_trees_init();
	else             maxflow_init();

	// main loop
	while ( 1 )
	{
		// test_consistency(current_node);

		if ((i=current_node))
		{
			i -> next = NULL; /* remove active flag */
			if (!i->parent) i = NULL;
		}
		if (!i)
		{
			if (!(i = next_active())) break;
		}

		/* growth */
		if (!i->is_sink)
		{
			/* grow source tree */
			for (a=i->first; a; a=a->next)
			if (a->r_cap)
			{
				j = a -> head;
				if (!j->parent)
				{
					j -> is_sink = 0;
					j -> parent = a -> sister;
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
					set_active(j);
					add_to_changed_list(j);
				}
				else if (j->is_sink) break;
				else if (j->TS <= i->TS &&
				         j->DIST> i->DIST)
				{
					/* heuristic - trying to make the distance from j to the source shorter */
					j -> parent = a -> sister;
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
				}
			}
		}
		else
		{
			/* grow sink tree */
			for (a=i->first; a; a=a->next)
			if (a->sister->r_cap)
			{
				j = a -> head;
				if (!j->parent)
				{
					j -> is_sink = 1;
					j -> parent = a -> sister;
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
					set_active(j);
					add_to_changed_list(j);
				}
				else if (!j->is_sink) { a = a -> sister; break; }
				else if (j->TS <= i->TS &&
				         j->DIST> i->DIST)
				{
					/* heuristic - trying to make the distance from j to the sink shorter */
					j -> parent = a -> sister;
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
				}
			}
		}

		TIME ++;

		if (a)
		{
			i -> next = i; /* set active flag */
			current_node = i;

			/* augmentation */
			augment(a);
			/* augmentation end */

			/* adoption */
			while ((np=orphan_first))
			{
				np_next = np -> next;
				np -> next = NULL;

				while ((np=orphan_first))
				{
					orphan_first = np -> next;
					i = np -> ptr;
					nodeptr_block -> Delete(np);
					if (!orphan_first) orphan_last = NULL;
					if (i->is_sink) process_sink_orphan(i);
					else            process_source_orphan(i);
				}

				orphan_first = np_next;
			}
			/* adoption end */
		}
		else current_node = NULL;
	}
	// test_consistency();

	if (!reuse_trees || (maxflow_iteration % 64) == 0)
	{
		delete nodeptr_block; 
		nodeptr_block = NULL; 
	}

	maxflow_iteration ++;
	return flow;
}
Esempio n. 2
0
Graph::flowtype Graph::maxflow()
{
    node *i, *j, *current_node = NULL;
    arc *a;
    nodeptr *np, *np_next;

    maxflow_init();
    nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function);

    while ( 1 )
    {
        if (i=current_node)
        {
            i -> next = NULL; /* remove active flag */
            if (!i->parent) i = NULL;
        }
        if (!i)
        {
            if (!(i = next_active())) break;
        }

        /* growth */
        if (!i->is_sink)
        {
            /* grow source tree */
            for (a=i->first; a; a=a->next)
                if (a->r_cap)
                {
                    j = a -> head;
                    if (!j->parent)
                    {
                        j -> is_sink = 0;
                        j -> parent = a -> sister;
                        j -> TS = i -> TS;
                        j -> DIST = i -> DIST + 1;
                        set_active(j);
                    }
                    else if (j->is_sink) break;
                    else if (j->TS <= i->TS &&
                             j->DIST > i->DIST)
                    {
                        /* heuristic - trying to make the distance from j to the source shorter */
                        j -> parent = a -> sister;
                        j -> TS = i -> TS;
                        j -> DIST = i -> DIST + 1;
                    }
                }
        }
        else
        {
            /* grow sink tree */
            for (a=i->first; a; a=a->next)
                if (a->sister->r_cap)
                {
                    j = a -> head;
                    if (!j->parent)
                    {
                        j -> is_sink = 1;
                        j -> parent = a -> sister;
                        j -> TS = i -> TS;
                        j -> DIST = i -> DIST + 1;
                        set_active(j);
                    }
                    else if (!j->is_sink) {
                        a = a -> sister;
                        break;
                    }
                    else if (j->TS <= i->TS &&
                             j->DIST > i->DIST)
                    {
                        /* heuristic - trying to make the distance from j to the sink shorter */
                        j -> parent = a -> sister;
                        j -> TS = i -> TS;
                        j -> DIST = i -> DIST + 1;
                    }
                }
        }

        TIME ++;

        if (a)
        {
            i -> next = i; /* set active flag */
            current_node = i;

            /* augmentation */
            augment(a);
            /* augmentation end */

            /* adoption */
            while (np=orphan_first)
            {
                np_next = np -> next;
                np -> next = NULL;

                while (np=orphan_first)
                {
                    orphan_first = np -> next;
                    i = np -> ptr;
                    nodeptr_block -> Delete(np);
                    if (!orphan_first) orphan_last = NULL;
                    if (i->is_sink) process_sink_orphan(i);
                    else            process_source_orphan(i);
                }

                orphan_first = np_next;
            }
            /* adoption end */
        }
        else current_node = NULL;
    }

    delete nodeptr_block;

    return flow;
}
Esempio n. 3
0
Graph::flowtype Graph::maxflow()
{
	node *i, *j, *current_node = NULL, *s_start, *t_start;
	captype *cap_middle, *rev_cap_middle;
	arc_forward *a_for, *a_for_first, *a_for_last;
	arc_reverse *a_rev, *a_rev_first, *a_rev_last;
	nodeptr *np, *np_next;

	prepare_graph();
	maxflow_init();
	nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function);

	while ( 1 )
	{
		if (i=current_node)
		{
			i -> next = NULL; /* remove active flag */
			if (!i->parent) i = NULL;
		}
		if (!i)
		{
			if (!(i = next_active())) break;
		}

		/* growth */
		s_start = NULL;

		a_for_first = i -> first_out;
		if (IS_ODD(a_for_first))
		{
			a_for_first = (arc_forward *) (((char *)a_for_first) + 1);
			a_for_last = (arc_forward *) ((a_for_first ++) -> shift);
		}
		else a_for_last = (i + 1) -> first_out;
		a_rev_first = i -> first_in;
		if (IS_ODD(a_rev_first))
		{
			a_rev_first = (arc_reverse *) (((char *)a_rev_first) + 1);
			a_rev_last = (arc_reverse *) ((a_rev_first ++) -> sister);
		}
		else a_rev_last = (i + 1) -> first_in;

		if (!i->is_sink)
		{
			/* grow source tree */
			for (a_for=a_for_first; a_for<a_for_last; a_for++)
			if (a_for->r_cap)
			{
				j = NEIGHBOR_NODE(i, a_for -> shift);
				if (!j->parent)
				{
					j -> is_sink = 0;
					j -> parent = MAKE_ODD(a_for);
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
					set_active(j);
				}
				else if (j->is_sink)
				{
					s_start = i;
					t_start = j;
					cap_middle     = & ( a_for -> r_cap );
					rev_cap_middle = & ( a_for -> r_rev_cap );
					break;
				}
				else if (j->TS <= i->TS &&
				         j->DIST > i->DIST)
				{
					/* heuristic - trying to make the distance from j to the source shorter */
					j -> parent = MAKE_ODD(a_for);
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
				}
			}
			if (!s_start)
			for (a_rev=a_rev_first; a_rev<a_rev_last; a_rev++)
			{
				a_for = a_rev -> sister;
				if (a_for->r_rev_cap)
				{
					j = NEIGHBOR_NODE_REV(i, a_for -> shift);
					if (!j->parent)
					{
						j -> is_sink = 0;
						j -> parent = a_for;
						j -> TS = i -> TS;
						j -> DIST = i -> DIST + 1;
						set_active(j);
					}
					else if (j->is_sink)
					{
						s_start = i;
						t_start = j;
						cap_middle     = & ( a_for -> r_rev_cap );
						rev_cap_middle = & ( a_for -> r_cap );
						break;
					}
					else if (j->TS <= i->TS &&
							 j->DIST > i->DIST)
					{
						/* heuristic - trying to make the distance from j to the source shorter */
						j -> parent = a_for;
						j -> TS = i -> TS;
						j -> DIST = i -> DIST + 1;
					}
				}
			}
		}
		else
		{
			/* grow sink tree */
			for (a_for=a_for_first; a_for<a_for_last; a_for++)
			if (a_for->r_rev_cap)
			{
				j = NEIGHBOR_NODE(i, a_for -> shift);
				if (!j->parent)
				{
					j -> is_sink = 1;
					j -> parent = MAKE_ODD(a_for);
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
					set_active(j);
				}
				else if (!j->is_sink)
				{
					s_start = j;
					t_start = i;
					cap_middle     = & ( a_for -> r_rev_cap );
					rev_cap_middle = & ( a_for -> r_cap );
					break;
				}
				else if (j->TS <= i->TS &&
				         j->DIST > i->DIST)
				{
					/* heuristic - trying to make the distance from j to the sink shorter */
					j -> parent = MAKE_ODD(a_for);
					j -> TS = i -> TS;
					j -> DIST = i -> DIST + 1;
				}
			}
			for (a_rev=a_rev_first; a_rev<a_rev_last; a_rev++)
			{
				a_for = a_rev -> sister;
				if (a_for->r_cap)
				{
					j = NEIGHBOR_NODE_REV(i, a_for -> shift);
					if (!j->parent)
					{
						j -> is_sink = 1;
						j -> parent = a_for;
						j -> TS = i -> TS;
						j -> DIST = i -> DIST + 1;
						set_active(j);
					}
					else if (!j->is_sink)
					{
						s_start = j;
						t_start = i;
						cap_middle     = & ( a_for -> r_cap );
						rev_cap_middle = & ( a_for -> r_rev_cap );
						break;
					}
					else if (j->TS <= i->TS &&
							 j->DIST > i->DIST)
					{
						/* heuristic - trying to make the distance from j to the sink shorter */
						j -> parent = a_for;
						j -> TS = i -> TS;
						j -> DIST = i -> DIST + 1;
					}
				}
			}
		}

		TIME ++;

		if (s_start)
		{
			i -> next = i; /* set active flag */
			current_node = i;

			/* augmentation */
			augment(s_start, t_start, cap_middle, rev_cap_middle);
			/* augmentation end */

			/* adoption */
			while (np=orphan_first)
			{
				np_next = np -> next;
				np -> next = NULL;

				while (np=orphan_first)
				{
					orphan_first = np -> next;
					i = np -> ptr;
					nodeptr_block -> Delete(np);
					if (!orphan_first) orphan_last = NULL;
					if (i->is_sink) process_sink_orphan(i);
					else            process_source_orphan(i);
				}

				orphan_first = np_next;
			}
			/* adoption end */
		}
		else current_node = NULL;
	}

	delete nodeptr_block;

	return flow;
}
Esempio n. 4
0
static void nsecify (char *filename)
{
    isc_result_t result;

    dns_db_t *db;

    dns_dbversion_t *wversion;

    dns_dbnode_t *node, *nextnode;

    char *origintext;

    dns_fixedname_t fname, fnextname;

    dns_name_t *name, *nextname, *target;

    isc_buffer_t b;

    size_t len;

    dns_dbiterator_t *dbiter;

    char newfilename[1024];

    dns_fixedname_init (&fname);
    name = dns_fixedname_name (&fname);
    dns_fixedname_init (&fnextname);
    nextname = dns_fixedname_name (&fnextname);

    origintext = strrchr (filename, '/');
    if (origintext == NULL)
        origintext = filename;
    else
        origintext++;            /* Skip '/'. */
    len = strlen (origintext);
    isc_buffer_init (&b, origintext, len);
    isc_buffer_add (&b, len);
    result = dns_name_fromtext (name, &b, dns_rootname, 0, NULL);
    check_result (result, "dns_name_fromtext()");

    db = NULL;
    result = dns_db_create (mctx, "rbt", name, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db);
    check_result (result, "dns_db_create()");
    result = dns_db_load (db, filename);
    if (result == DNS_R_SEENINCLUDE)
        result = ISC_R_SUCCESS;
    check_result (result, "dns_db_load()");
    wversion = NULL;
    result = dns_db_newversion (db, &wversion);
    check_result (result, "dns_db_newversion()");
    dbiter = NULL;
    result = dns_db_createiterator (db, 0, &dbiter);
    check_result (result, "dns_db_createiterator()");
    result = dns_dbiterator_first (dbiter);
    check_result (result, "dns_dbiterator_first()");
    node = NULL;
    result = next_active (db, wversion, dbiter, name, &node);
    while (result == ISC_R_SUCCESS)
    {
        nextnode = NULL;
        result = dns_dbiterator_next (dbiter);
        if (result == ISC_R_SUCCESS)
            result = next_active (db, wversion, dbiter, nextname, &nextnode);
        if (result == ISC_R_SUCCESS)
            target = nextname;
        else if (result == ISC_R_NOMORE)
            target = dns_db_origin (db);
        else
        {
            target = NULL;        /* Make compiler happy. */
            fatal ("db iteration failed");
        }
        dns_nsec_build (db, wversion, node, target, 3600);    /* XXX BEW */
        dns_db_detachnode (db, &node);
        node = nextnode;
    }
    if (result != ISC_R_NOMORE)
        fatal ("db iteration failed");
    dns_dbiterator_destroy (&dbiter);
    /*
     * XXXRTH  For now, we don't increment the SOA serial.
     */
    dns_db_closeversion (db, &wversion, ISC_TRUE);
    len = strlen (filename);
    if (len + 4 + 1 > sizeof (newfilename))
        fatal ("filename too long");
    sprintf (newfilename, "%s.new", filename);
    result = dns_db_dump (db, NULL, newfilename);
    check_result (result, "dns_db_dump");
    dns_db_detach (&db);
}