Exemple #1
0
void dinic(Net net, output * out_p, int flags){
	uint an_flow = 0, x = 0, r = 0, t = 1, i = 0;
	bool end = false;
	output out = *out_p;
	path p = NULL;
	nodes_list nodes = NULL;

	nodes = net_get_nodes(net);
	out_set_net(out, net);

	for(i = 0; !end ; i++) {

		an_flow = 0;

		nodes_aux_reset(nodes);
		net_aux_new(net);

		end = is_t_in_an(nodes);
		
		if (!end) {
			
			while(true) {

				x = advance(net); /* ADVANCE */

				if (x == t) { /* AUGMENT */
					r = residual_capacity(net); 
					an_flow += r;
					p = path_new();
					augment(net, p, r);
					out_add_path(out, p);
				} 
				else break;
			}

			if((flags & VERBOSE)){
				out_print_paths(out, i+1);
			}
		}

		out_path_destroy(out);
	}
	*out_p = out;
}
Exemple #2
0
double
lap(arrow_problem *problem, int delta, int *x, int *y, 
    int *pi, int *d, int *pred, int *label, arrow_heap *heap)
{
    int i, j, t;
    int n = problem->size;
    
    /* Initialization */
    for(i = 0; i < 2 * n; i++)
    {
        x[i] = -1;
        y[i] = -1;
        pi[i] = 0;
    }
        
    for(i = 0; i < n; i++)
    {
        /* Find the shortest path from i to any demand node t */
        dijkstra(problem, delta, x, y, pi, i, &t, d, pred, label, heap);
        
        /* If we cannot reach a demand node then problem's infeasible */
        if(t == -1) return DBL_MAX;
        
        /* Update reduced costs */
        for(j = 0; j < 2 * n; j++)
        {
            if(label[j])
                pi[j] = pi[j] - d[j] + d[t];
        }
        
        /* Augment! */
        augment(problem, i, t, pred, x, y);
    }
    
    /* Calculate total cost of assignment, as well as fix final solution. */
    double cost = 0.0;
    for(i = 0; i < n; i++)
    {
        x[i] = x[i] - n;
        cost += problem->get_cost(problem, i, x[i]);
    }
    return cost;
}
Exemple #3
0
int main() {
    int a, b, c;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &a, &b, &c);
        newnode(a, b, c, 1);
        newnode(b, a, c, 1);
    }
    s = 1, t = n + 1;
    n = t;
    newnode(n - 1, t, 0, 2);
    do 
        do 
            memset(z,0,sizeof(z));
        while (augment(s,INF));
    while (relabel());    
    printf("%d\n", cost);
    return 0;
}
int main(){
    int N, K;
    scanf(" %d %d", &N, &K);
    for (int i=0; i<K; ++i) {
        int R, C;
        scanf(" %d %d", &R, &C);
        R--; C--;
        g[R].push_back(C);
    }
    std::fill(matchFrom, matchFrom+N, -1);

    int match = 0;
    for (int u=0; u<N; ++u) {
        visited.clear();
        visited.resize(N);
        if (augment(u))
            match++;
    }

    printf("%d\n", match);
}
/* find an augmenting path starting at column j and extend the match if found */
static
int augment (int k, cs *A, int *jmatch, int *cheap, int *w, int j)
{
    int found = 0, p, i = -1, *Ap = A->p, *Ai = A->i ;
    /* --- Start depth-first-search at node j ------------------------------- */
    w [j] = k ;                             /* mark j as visited for kth path */
    for (p = cheap [j] ; p < Ap [j+1] && !found ; p++)
    {
        i = Ai [p] ;                        /* try a cheap assignment (i,j) */
        found = (jmatch [i] == -1) ;
    }
    cheap [j] = p ;                         /* start here next time for j */
    /* --- Depth-first-search of neighbors of j ----------------------------- */
    for (p = Ap [j] ; p < Ap [j+1] && !found ; p++)
    {
        i = Ai [p] ;                        /* consider row i */
        if (w [jmatch [i]] == k) continue ; /* skip col jmatch [i] if marked */
        found = augment (k, A, jmatch, cheap, w, jmatch [i]) ;
    }
    if (found) jmatch [i] = j ;             /* augment jmatch if path found */
    return (found) ;
}
Exemple #6
0
// Find a maximum size matching in the graph graf and
// return it as a list of edges.
edmonds::edmonds(Graph& graf1, UiDlist& match1, int &size)
		 : graf(&graf1), match(&match1) {
	vertex u, v; edge e;
	blossoms = new Partition(graf->n()); // set per blossom
	augpath = new UiRlist(graf->m());    // reversible list
	origin = new vertex[graf->n()+1];    // original vertex for each blossom
	bridge = new BridgePair[graf->n()+1];// edge that formed a blossom
	state = new stype[graf->n()+1];	     // state used in path search
	pEdge = new edge[graf->n()+1];	     // edge to parent in tree
	mEdge = new edge[graf->n()+1];	     // incident matching edge (if any)
	mark = new bool[graf->n()+1];	     // mark bits used by nca
	
	mSize = stepCount = blossomCount = pathInitTime = pathFindTime = 0;
	int t1, t2, t3;
	t1 = Util::getTime();
	// Create initial maximal (not maximum) matching
	for (u = 1; u <= graf->n(); u++) {
		mEdge[u] = 0; mark[u] = false;
	}
	match->clear(); size = 0;
	for (e = graf->first(); e != 0; e = graf->next(e)) {
		u = graf->left(e); v = graf->right(e);
		if (mEdge[u] == 0 && mEdge[v] == 0) {
			mEdge[u] = mEdge[v] = e;
			match->addLast(e); mSize++;
		}
	}
	iSize = mSize;
		
	t2 = Util::getTime();
	imatchTime = (t2-t1);
	while((e = findpath()) != 0) { augment(e); mSize++; }
	size = mSize;
	t3 = Util::getTime();
	rmatchTime = (t3-t2);

	delete blossoms; delete augpath; delete [] origin;
	delete [] bridge; delete [] pEdge; delete [] mEdge; delete[] mark;
}
Exemple #7
0
Flow max_flow(FGraph<Flow> &g, int s, int t, Flow zero = 0) {
  const int V = g.size();
  Flow flow = zero;
  for (;;) {
    vector<Flow> d(V, -1);
    queue<int> que;
    d[s] = zero;
    que.push(s);
    while(!que.empty()) {
      int v = que.front(); que.pop();
      for (const auto &e: g[v]) {
        if (e.cap <= zero || d[e.to] >= zero) continue;
        d[e.to] = d[v] + 1;
        que.push(e.to);
      }
    }
    if (d[t] < zero) return flow;
    vector<int> iter(V, 0);
    Flow f;
    while ((f = augment(g, d, iter, s, t, inf<Flow>)) > 0) flow += f;
  }
}
// index^1 is reverse edge
Weight MaxFlow(const Graph &g, int e, int s, int t) {
  int n = g.size();
  Array capacity(e);
  for (int from = 0; from < n; from++) {
    for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
      capacity[it->index] += it->weight;
    }
  }
  int ans = 0;
  while (true) {
    vector<int> level(n, -1);
    level[s] = 0;
    queue<int> que;
    que.push(s);
    for (int d = n; !que.empty() && level[que.front()] < d; ) {
      int from = que.front();
      que.pop();
      if (from == t) { d = level[from]; }
      for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
        int to = it->dest;
        if (capacity[it->index] > 0 && level[to] == -1) {
          que.push(to);
          level[to] = level[from] + 1;
        }
      }
    }
    vector<bool> finished(n);
    bool end = true;
    while (true) {
      Weight f = augment(g, capacity, level, finished, s, t, 2000000000LL);
      if (f == 0) { break; }
      ans += f;
      end = false;
    }
    if (end) { break; }
  }
  return ans;
}
    void ImplicitSweeper<time>::sweep()
    {
      auto const dt = this->get_controller()->get_step_size();
      auto const t  = this->get_controller()->get_time();

      ML_CLOG(INFO, "Sweeper", "sweeping on step " << this->get_controller()->get_step() + 1
                               << " in iteration " << this->get_controller()->get_iteration()
                               << " (dt=" << dt << ")");

      this->s_integrals[0]->mat_apply(this->s_integrals, dt, this->quadrature->get_s_mat(), this->fs_impl, true);
      if (this->fas_corrections.size() > 0) {
        for (size_t m = 0; m < this->s_integrals.size(); m++) {
          this->s_integrals[m]->saxpy(1.0, this->fas_corrections[m]);
        }
      }

      for (size_t m = 0; m < this->s_integrals.size(); m++) {
        for (size_t n = 0; n < m; n++) {
          this->s_integrals[m]->saxpy(-dt*this->q_tilde(m, n), this->fs_impl[n]);
        }
      }

      shared_ptr<Encapsulation<time>> rhs = this->get_factory()->create(pfasst::encap::solution);

      auto const anodes = augment(t, dt, this->quadrature->get_nodes());
      for (size_t m = 0; m < anodes.size() - 1; ++m) {
        auto const ds = anodes[m+1] - anodes[m];
        rhs->copy(m == 0 ? this->get_start_state() : this->state[m-1]);
        rhs->saxpy(1.0, this->s_integrals[m]);
        rhs->saxpy(-ds, this->fs_impl[m]);
        for (size_t n = 0; n < m; n++) {
          rhs->saxpy(dt*this->q_tilde(m, n), this->fs_impl[n]);
        }
        this->impl_solve(this->fs_impl[m], this->state[m], anodes[m], ds, rhs);
      }
      this->set_end_state();
    }
Exemple #10
0
void TailPlacer::add_red(int name) {
    Node *p = verts[name];
    assert(!p->red);

    // 1. deactivate all active edges
    Node *unred = p->deactivate_active(true);

    if(unred) {
        unmatched_reds.insert(unred->name);
        assert(unred->red);
    }

    // 2. put node in LHS
    p->red = true;

    contacts += p->adj.size();

    // 3. for each neighbor that isn't red...
    vector<DEdge*>::iterator it;
    for(it = p->adj.begin(); it != p->adj.end(); it++) {
        Node *nbr = (*it)->neighbor_of(p);
        assert(nbr != NULL);

        if(nbr->red) // if that neighbor is red ...
            continue;

        contacts--;
        // at this point nbr is a non-red neighbor

        // activate this edge and set capacity to 1 outward
        (*it)->activate();
        (*it)->set_cap_from(p, 1);
    }

    // 4. augment
    while(!unmatched_reds.empty() && augment());
}
Exemple #11
0
int main() {
	/* Build adjacency matrix res */
	scanf("%d %d", &s, &t);
	mf = 0;
	while (1) {
		f = 0;
		vi dist(n, INT_INF);
		dist[s] = 0;
		queue<int> q; q.push(s);
		p.assign(n, -1);
		while (!q.empty()) {
			int u = q.front(); q.pop();
			if (u == t) break;
			for (int v = 0; v < n; v++)
				if (res[u][v] > 0 && dist[v] == INT_INF)
					dist[v] = dist[u] + 1, q.push(v), p[v] = u;
		}
		augment(t, INT_INF);
		if (f == 0) break;
		mf += f;
	}
	DBG(mf);
	return 0;
}
Exemple #12
0
void TailPlacer::remove_red(int name) {
    Node *p = verts[name];
    assert(p->red);
    // 1. deactivate all active edges
    Node *unred = p->deactivate_active(false);

    if(unred)
    {
        unmatched_reds.insert(unred->name);
        assert(unred->red);
    }

    unmatched_reds.erase(name);

    // 2. remove node from LHS
    p->red = false;

    // 3. for each red neighbor ...
    vector<DEdge*>::iterator it;
    for(it = p->adj.begin(); it != p->adj.end(); it++) {
        Node *nbr = (*it)->neighbor_of(p);
        assert(nbr != NULL);

        if(!nbr->red)
            continue;
        --contacts;
        // at this point nbr is a red neighbor

        // activate this edge and set capacity 1 inward
        (*it)->activate();
        (*it)->set_cap_from(nbr, 1);        
    }

    // 4. augment
    while(!unmatched_reds.empty() && augment());
}
Exemple #13
0
//------------------------------------------------------------------------------
// Invert
//------------------------------------------------------------------------------
bool Matrix::invert()
{
   bool ok = mda != nullptr && rows > 0 && cols > 0 && isSquare();

   if (ok) {
      Matrix m(rows, cols);
      m.makeIdent();
      unsigned int origCols = cols;  // 'cols' is changed after augment()
      augment(m);

      for (unsigned int k = 0; k < origCols; k++) {
         pivotRow(k,k);
         mulRow(k, 1.0/getElem(k,k));
         for (unsigned int i=0; i<rows; i++) {
            if (i != k) {
               addRow(i, k, -getElem(i,k));
            }
         }
      }

      remCols(0, origCols-1);
   }
   return ok;
}
void Density::generate_valence(K_set& ks__)
{
    PROFILE_WITH_TIMER("sirius::Density::generate_valence");

    double wt = 0.0;
    double ot = 0.0;
    for (int ik = 0; ik < ks__.num_kpoints(); ik++)
    {
        wt += ks__[ik]->weight();
        for (int j = 0; j < ctx_.num_bands(); j++) ot += ks__[ik]->weight() * ks__[ik]->band_occupancy(j);
    }

    if (std::abs(wt - 1.0) > 1e-12) TERMINATE("K_point weights don't sum to one");

    if (std::abs(ot - unit_cell_.num_valence_electrons()) > 1e-8)
    {
        std::stringstream s;
        s << "wrong occupancies" << std::endl
          << "  computed : " << ot << std::endl
          << "  required : " << unit_cell_.num_valence_electrons() << std::endl
          << "  difference : " << std::abs(ot - unit_cell_.num_valence_electrons());
        WARNING(s);
    }

    /* swap wave functions */
    for (int ikloc = 0; ikloc < ks__.spl_num_kpoints().local_size(); ikloc++)
    {
        int ik = ks__.spl_num_kpoints(ikloc);
        auto kp = ks__[ik];

        for (int ispn = 0; ispn < ctx_.num_spins(); ispn++)
        {
            if (ctx_.full_potential())
            {
                kp->spinor_wave_functions<true>(ispn).swap_forward(0, kp->num_occupied_bands(ispn));
            }
            else
            {
                kp->spinor_wave_functions<false>(ispn).swap_forward(0, kp->num_occupied_bands(ispn), kp->gkvec_fft_distr());
            }
        }
    }

    /* zero density and magnetization */
    zero();

    ctx_.fft().prepare();

    /* interstitial part is independent of basis type */
    generate_valence_density_it(ks__);

    /* for muffin-tin part */
    switch (ctx_.esm_type())
    {
        case full_potential_lapwlo:
        {
            generate_valence_density_mt(ks__);
            break;
        }
        case full_potential_pwlo:
        {
            STOP();
        }
        default:
        {
            break;
        }
    }
    
    #if (__VERIFICATION > 0)
    for (int ir = 0; ir < ctx_.fft(0)->local_size(); ir++)
    {
        if (rho_->f_it(ir) < 0) TERMINATE("density is wrong");
    }
    #endif

    //== double nel = 0;
    //== for (int ir = 0; ir < ctx_.fft().local_size(); ir++)
    //== {
    //==     nel += rho_->f_rg(ir);
    //== }
    //== ctx_.mpi_grid().communicator(1 << _dim_row_).allreduce(&nel, 1);
    //== nel = nel * unit_cell_.omega() / ctx_.fft().size();
    //== printf("number of electrons: %f\n", nel);
    
    /* get rho(G) and mag(G) */
    rho_->fft_transform(-1);
    for (int j = 0; j < ctx_.num_mag_dims(); j++) magnetization_[j]->fft_transform(-1);

    //== printf("number of electrons: %f\n", rho_->f_pw(0).real() * unit_cell_.omega());
    //== STOP();

    ctx_.fft().dismiss();

    if (ctx_.esm_type() == ultrasoft_pseudopotential) augment(ks__);
}
NOX::Abstract::MultiVector&
LOCA::Extended::MultiVector::augment(const NOX::Abstract::MultiVector& source)
{
  return augment(dynamic_cast<const LOCA::Extended::MultiVector&>(source));
}
Exemple #16
0
tipo hungarian(){
	tipo ret = 0; max_match = 0, memset(xy, -1, sizeof(xy)); 
	memset(yx, -1, sizeof(yx)), init_labels(), augment(); //steps 1-3
	forn (x,n) ret += cost[x][xy[x]]; return ret;
}
Int BTF(maxtrans)   /* returns # of columns in the matching */
(
    /* --- input --- */
    Int nrow,	    /* A is nrow-by-ncol in compressed column form */
    Int ncol,
    Int Ap [ ],	    /* size ncol+1 */
    Int Ai [ ],	    /* size nz = Ap [ncol] */
    double maxwork, /* do at most maxwork*nnz(A) work; no limit if <= 0.  This
		     * work limit excludes the O(nnz(A)) cheap-match phase. */

    /* --- output --- */
    double *work,   /* work = -1 if maxwork > 0 and the total work performed
		     * reached the maximum of maxwork*nnz(A)).
		     * Otherwise, work = the total work performed. */

    Int Match [ ],  /* size nrow.  Match [i] = j if column j matched to row i */

    /* --- workspace --- */
    Int Work [ ]    /* size 5*ncol */
)
{
    Int *Cheap, *Flag, *Istack, *Jstack, *Pstack ;
    Int i, j, k, nmatch, work_limit_reached, result ;

    /* ---------------------------------------------------------------------- */
    /* get workspace and initialize */
    /* ---------------------------------------------------------------------- */

    Cheap  = Work ; Work += ncol ;
    Flag   = Work ; Work += ncol ;

    /* stack for non-recursive depth-first search in augment function */
    Istack = Work ; Work += ncol ;
    Jstack = Work ; Work += ncol ;
    Pstack = Work ;

    /* in column j, rows Ai [Ap [j] .. Cheap [j]-1] are known to be matched */
    for (j = 0 ; j < ncol ; j++)
    {
	Cheap [j] = Ap [j] ;
	Flag [j] = EMPTY ; 
    }

    /* all rows and columns are currently unmatched */
    for (i = 0 ; i < nrow ; i++)
    {
	Match [i] = EMPTY ;
    }

    if (maxwork > 0)
    {
	maxwork *= Ap [ncol] ;
    }
    *work = 0 ;

    /* ---------------------------------------------------------------------- */
    /* find a matching row for each column k */
    /* ---------------------------------------------------------------------- */

    nmatch = 0 ;
    work_limit_reached = FALSE ;
    for (k = 0 ; k < ncol ; k++)
    {
	/* find an augmenting path to match some row i to column k */
	result = augment (k, Ap, Ai, Match, Cheap, Flag, Istack, Jstack, Pstack,
	    work, maxwork) ;
	if (result == TRUE)
	{
	    /* we found it.  Match [i] = k for some row i has been done. */
	    nmatch++ ;
	}
	else if (result == EMPTY)
	{
	    /* augment gave up because of too much work, and no match found */
	    work_limit_reached = TRUE ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* return the Match, and the # of matches made */
    /* ---------------------------------------------------------------------- */

    /* At this point, row i is matched to j = Match [i] if j >= 0.  i is an
     * unmatched row if Match [i] == EMPTY. */

    if (work_limit_reached)
    {
	/* return -1 if the work limit of maxwork*nnz(A) was reached */
	*work = EMPTY ;
    }

    return (nmatch) ;
}
Exemple #18
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;
}
Exemple #19
0
mixture::mixture(bool fulltable,char* sublminfo,int depth,int prunefreq,char* ipfile,char* opfile):
  mdiadaptlm((char *)NULL,depth)
{

  prunethresh=prunefreq;
  ipfname=ipfile;
  opfname=opfile;
  usefulltable=fulltable;

  mfstream inp(sublminfo,ios::in );
  if (!inp) {
		std::stringstream ss_msg;
		ss_msg << "cannot open " << sublminfo;
		exit_error(IRSTLM_ERROR_IO, ss_msg.str());
  }

	char line[MAX_LINE];
	inp.getline(line,MAX_LINE);
	
	sscanf(line,"%d",&numslm);
	
  sublm=new interplm* [numslm];

  cerr << "WARNING: Parameters PruneSingletons (ps) and PruneTopSingletons (pts) are not taken into account for this type of LM (mixture); please specify the singleton pruning policy for each submodel using parameters \"-sps\" and \"-spts\" in the configuraton file\n";

  int max_npar=6;
  for (int i=0; i<numslm; i++) {
    char **par=new char*[max_npar];
    par[0]=new char[BUFSIZ];
    par[0][0]='\0';
		
		inp.getline(line,MAX_LINE);
		
		const char *const wordSeparators = " \t\r\n";
		char *word = strtok(line, wordSeparators);
		int j = 1;
		
		while (word){
			if (i>max_npar){
				std::stringstream ss_msg;
				ss_msg << "Too many parameters (expected " << max_npar << ")";
				exit_error(IRSTLM_ERROR_DATA, ss_msg.str());
			}
			par[j] = new char[MAX_LINE];
			strcpy(par[j],word);
//			std::cerr << "par[j]:|" << par[j] << "|" << std::endl;
		  word = strtok(0, wordSeparators);
			j++;
		}
	
    int actual_npar = j;	
		
    char *subtrainfile;
    int slmtype;
    bool subprunesingletons;
    bool subprunetopsingletons;
    int subprunefreq;

    DeclareParams((char*)
      "SubLanguageModelType",CMDENUMTYPE|CMDMSG, &slmtype, SLmTypeEnum, "type of the sub LM",
			"slm",CMDENUMTYPE|CMDMSG, &slmtype, SLmTypeEnum, "type of the sub LM",
			"sTrainOn",CMDSTRINGTYPE|CMDMSG, &subtrainfile, "training file of the sub LM",
      "str",CMDSTRINGTYPE|CMDMSG, &subtrainfile, "training file of the sub LM",
      "sPruneThresh",CMDSUBRANGETYPE|CMDMSG, &subprunefreq, 0, 1000, "threshold for pruning the sub LM",
      "sp",CMDSUBRANGETYPE|CMDMSG, &subprunefreq, 0, 1000, "threshold for pruning the sub LM",									
      "sPruneSingletons",CMDBOOLTYPE|CMDMSG, &subprunesingletons,  "boolean flag for pruning of singletons of the sub LM (default is true)",
      "sps",CMDBOOLTYPE|CMDMSG, &subprunesingletons, "boolean flag for pruning of singletons of the sub LM (default is true)",
      "sPruneTopSingletons",CMDBOOLTYPE|CMDMSG, &subprunetopsingletons, "boolean flag for pruning of singletons at the top level of the sub LM (default is false)",
      "spts",CMDBOOLTYPE|CMDMSG, &subprunetopsingletons, "boolean flag for pruning of singletons at the top level of the sub LM (default is false)",				
			(char *)NULL  );

    subtrainfile=NULL;
    slmtype=0;
    subprunefreq=-1;
    subprunesingletons=true;
    subprunetopsingletons=false;

		GetParams(&actual_npar, &par, (char*) NULL);
		

    if (!slmtype) {
			std::stringstream ss_msg;
			ss_msg << "The type (-slm) for sub LM number " << i+1 << "  is not specified" ;
			exit_error(IRSTLM_ERROR_DATA, ss_msg.str());
    }

		if (!subtrainfile) {
			std::stringstream ss_msg;
			ss_msg << "The file (-str) for sub lm number " << i+1 << " is not specified";
			exit_error(IRSTLM_ERROR_DATA, ss_msg.str());
    }

		if (subprunefreq==-1) {
			std::stringstream ss_msg;
			ss_msg << "The prune threshold (-sp) for sub lm number " << i+1 << "  is not specified";
			exit_error(IRSTLM_ERROR_DATA, ss_msg.str());
    }

		switch (slmtype) {

    case LINEAR_WB:
      sublm[i]=new linearwb(subtrainfile,depth,subprunefreq,MSHIFTBETA_I);
      break;

    case SHIFT_BETA:
      sublm[i]=new shiftbeta(subtrainfile,depth,subprunefreq,-1,SHIFTBETA_I);
      break;

    case SHIFT_ONE:
      sublm[i]=new shiftbeta(subtrainfile,depth,subprunefreq,SIMPLE_I);
      break;

    case MOD_SHIFT_BETA:
      sublm[i]=new mshiftbeta(subtrainfile,depth,subprunefreq,MSHIFTBETA_I);
      break;

    case MIXTURE:
      sublm[i]=new mixture(usefulltable,subtrainfile,depth,subprunefreq);
      break;

    default:
				exit_error(IRSTLM_ERROR_DATA, "not implemented yet");
    };

    sublm[i]->prunesingletons(subprunesingletons==true);
    sublm[i]->prunetopsingletons(subprunetopsingletons==true);

    if (subprunetopsingletons==true)
      //apply most specific pruning method
      sublm[i]->prunesingletons(false);


    cerr << "eventually generate OOV code of sub lm[" << i << "]\n";
    sublm[i]->dict->genoovcode();

    //create super dictionary
    dict->augment(sublm[i]->dict);

    //creates the super n-gram table
    if(usefulltable) augment(sublm[i]);

  }
	
	cerr << "eventually generate OOV code of the mixture\n";
  dict->genoovcode();
  cerr << "dict size of the mixture:" << dict->size() << "\n";
  //tying parameters
  k1=2;
  k2=10;
};
Exemple #20
0
void augment(const double cost[N][N]) //main function of the algorithm
{
    if (max_match == n) return;        //check wether matching is already perfect
    int x, y, root = 0;                //just counters and root vertex
    int q[N], wr = 0, rd = 0;          //q - queue for bfs, wr,rd - write and read
                                       //pos in queue
    memset(S, false, sizeof(S));       //init set S
    memset(T, false, sizeof(T));       //init set T
    memset(prev, -1, sizeof(prev));    //init set prev - for the alternating tree
    for (x = 0; x < n; x++)            //finding root of the tree
        if (xy[x] == -1)
        {
            q[wr++] = root = x;
            prev[x] = -2;
            S[x] = true;
            break;
        }

    for (y = 0; y < n; y++)            //initializing slack array
    {
        slack[y] = lx[root] + ly[y] - cost[root][y];
        slackx[y] = root;
    }
   while (true)                                                        //main cycle
    {
        while (rd < wr)                                                 //building tree with bfs cycle
        {
            x = q[rd++];                                                //current vertex from X part
            for (y = 0; y < n; y++)                                     //iterate through all edges in equality graph
                if (cost[x][y] == lx[x] + ly[y] &&  !T[y])
                {
                    if (yx[y] == -1) break;                             //an exposed vertex in Y found, so
                                                                        //augmenting path exists!
                    T[y] = true;                                        //else just add y to T,
                    q[wr++] = yx[y];                                    //add vertex yx[y], which is matched
                                                                        //with y, to the queue
                    add_to_tree(yx[y], x, cost);                              //add edges (x,y) and (y,yx[y]) to the tree
                }
            if (y < n) break;                                           //augmenting path found!
        }
        if (y < n) break;                                               //augmenting path found!

        update_labels();                                                //augmenting path not found, so improve labeling
        wr = rd = 0;
        for (y = 0; y < n; y++)
        //in this cycle we add edges that were added to the equality graph as a
        //result of improving the labeling, we add edge (slackx[y], y) to the tree if
        //and only if !T[y] &&  slack[y] == 0, also with this edge we add another one
        //(y, yx[y]) or augment the matching, if y was exposed
            if (!T[y] &&  slack[y] == 0)
            {
                if (yx[y] == -1)                                        //exposed vertex in Y found - augmenting path exists!
                {
                    x = slackx[y];
                    break;
                }
                else
                {
                    T[y] = true;                                        //else just add y to T,
                    if (!S[yx[y]])
                    {
                        q[wr++] = yx[y];                                //add vertex yx[y], which is matched with
                                                                        //y, to the queue
                        add_to_tree(yx[y], slackx[y],cost);                  //and add edges (x,y) and (y,
                                                                        //yx[y]) to the tree
                    }
                }
            }
        if (y < n) break;                                               //augmenting path found!
    }

    if (y < n)                                                          //we found augmenting path!
    {
        max_match++;                                                    //increment matching
        //in this cycle we inverse edges along augmenting path
        for (int cx = x, cy = y, ty; cx != -2; cx = prev[cx], cy = ty)
        {
            ty = xy[cx];
            yx[cy] = cx;
            xy[cx] = cy;
        }
        augment(cost);                                                      //recall function, go to step 1 of the algorithm
    }
}//end of augment() function
Exemple #21
0
void i_augment(pob o)
{
    if (o->blessing > -1)
        Objects[o->id].known = 1;
    augment(o->blessing);
}
Exemple #22
0
void phi(float c[50][50],float a[50][50],float d[50][50],float x[50][1],int n,int m) // points are stored by x
                                                                          //this function calculates the transformation of
{                                                                         //karmarkar's algorithm
    float cdash[50][50];                //need serious reviewing                                                    
    float cp[50][50];
    float z[50][50];
    float cpcap[50][50];
    int i,j;
    float value;
    float anot[50][50];
    float bprime[50][50];
    float e[50][50];
    float ddash[50][50];
    float constant;
    float b[50][50];
    float val,atemp[50][50];

    for(i=0;i<m;i++)                 //loop for input of constarints
        for(j=0;j<n;j++)
            atemp[i][j]=a[i][j];

    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            ddash[i][j]=d[i][j];             //copying d to ddash since d will b destroyed

    mul(d,c,n,n,n,1);                //d=d.c

    for(i=0;i<n;i++)
        cdash[i][0]=d[i][0];             //c'=d's first column

    mul(atemp,ddash,m,n,n,n);            //a=a.d 

    augment(atemp,m,n);                  //a=augment of a

    for(i=0;i<(m+1);i++)                //z is a m+1*n matrix so is a   
        for(j=0;j<n;j++)
            z[i][j]=atemp[i][j];                  //z=b

    transpose(atemp,m+1,n);               //atemp=bt

    mul(z,atemp,m+1,n,n,m+1);         //z=zztrans=BBtrans 


    inverse(z,m+1);               //z=zinverse

    transpose(atemp,n,m+1);           //taking the transpose of a ie Btrans to obtain back the original z or B ie a=B

    mul(z,atemp,m+1,m+1,m+1,n);       //z=inv(zztrans)z or z=inv(BBtrans)B

    mul(z,cdash,m+1,n,n,1);       //multiplying with cdash result in z

    transpose(atemp,m+1,n);           //taking transpose of a ie z or Btrans

    mul(atemp,z,n,m+1,m+1,1);         //m loses its effects from here onwards  


    subtraction(cdash,atemp,n,1);     //subtracting a from cdash result in cdash
    
    for(i=0;i<n;i++)
        cp[i][0]=cdash[i][0];         //copying cdash to  cp cp=n*1 matrix

    value=mod(cp,n,1);            //obtaining the mod of cp

    if(value==0)
    {
        for(i=0;i<n;i++)
        cpcap[i][0]=0;         //cpcap=0;for all zeros
    }

    else
    {
        value=1/value;
        for(i=0;i<n;i++)
        cpcap[i][0]=cp[i][0]*value;
    }                              //obtaing cpcap from formula, cpcap=n*1 matrix

    value=(float)n;
    value=1/value;

    for(i=0;i<n;i++)
        anot[i][0]=value;               //initializing anot to 1\n

    val=consradii(n);
    val=alpha*val;

    for(i=0;i<n;i++)
        cpcap[i][0]=(val*cpcap[i][0]);

    subtraction(anot,cpcap,n,1);  //subtracting anot from cpcap result in anot

    for(i=0;i<n;i++)
       bprime[i][0]=anot[i][0];      //copying anot to bprime

    for(i=0;i<n;i++)
        e[0][i]=1;                    //initializing the elements of the array e with 1

    mul(e,ddash,1,n,n,n);         //multiplying e with ddash or the original d
    mul(e,bprime,1,n,n,1);
    constant=e[0][0];             //the single element array in e is terrmed constant

    mul(ddash,bprime,n,n,n,1);

    for(i=0;i<n;i++)
    {
        b[i][0]=ddash[i][0];          //assigns the values of ddash to b
        b[i][0]=b[i][0]/constant;     //computes the value of b
    }

    for(i=0;i<n;i++)
        x[i][0]=b[i][0];
}
Exemple #23
0
void l_magic_pool(void)
{
  int possibilities=random_range(100);
  print1("This pool seems to be enchanted....");
  if (gamestatusp(MOUNTED)) {
    if (random_range(2)) {
      print2("Your horse is polymorphed into a fig newton.");
      resetgamestatus(MOUNTED);
    }
    else print2("Whatever it was, your horse enjoyed it....");
  }
  else  if (possibilities == 0) {
    print1("Oh no! You encounter the DREADED AQUAE MORTIS...");
    if (random_range(1000) < Player.level*Player.level*Player.level) {
      print2("The DREADED AQUAE MORTIS throttles you within inches....");
      print3("but for some reason chooses to let you escape.");
      gain_experience(500);
      Player.hp = 1;
    }
    else p_death("the DREADED AQUAE MORTIS!");
  }
  else if (possibilities < 25)
    augment(0);
  else if (possibilities < 30)
    augment(1);
  else if (possibilities < 60)
    augment(-1);
  else if (possibilities < 65)
    cleanse(1);
  else if (possibilities < 80) {
    if (Player.possessions[O_WEAPON_HAND] != NULL) {
      print1("You drop your weapon in the pool! It's gone forever!");
      dispose_lost_objects(1,Player.possessions[O_WEAPON_HAND]);
    }
    else print1("You feel fortunate.");
  }
  else if (possibilities < 90) {
    if (Player.possessions[O_WEAPON_HAND] != NULL) {
      print1("Your weapon leaves the pool with a new edge....");
      Player.possessions[O_WEAPON_HAND]->plus += random_range(10)+1;
      calc_melee();
    }
    else print1("You feel unfortunate.");
  }
  else if (possibilities < 95) {
    Player.hp += 10;
    print1("You feel healthier after the dip...");
  }
  else if (possibilities < 99) {
    print1("Oooh, a tainted pool...");
    p_poison(10);
  }
  else if (possibilities == 99) {
    print1("Wow! A pool of azoth!");
    heal(10);
    cleanse(1);
    Player.mana = calcmana()*3;
    Player.str = (Player.maxstr++)*3;
  }
  print2("The pool seems to have dried up.");
  Level->site[Player.x][Player.y].locchar = TRAP;
  Level->site[Player.x][Player.y].p_locf = L_TRAP_PIT;
  lset(Player.x, Player.y, CHANGED);
}
Exemple #24
0
int dinic()
{
    int f=0;
    while (relabel()) f+=augment(S,oo);
    return f;
}
Exemple #25
0
void augment()                         //main function of the algorithm
{
    if (verbose)
    {
        printf("\n\nAugment(.) call\n");
        printf("Current matching is as follows:\n");
        print_matching();
    }

    if (max_match == n) return;        //check wether matching is already perfect
    int x, y, root;                    //just counters and root vertex
    int q[N], wr = 0, rd = 0;          //q - queue for bfs, wr,rd - write and read

    root = 0;                          // stop warning, it will be assigned below before xy has
                                       // a bunch of -1's in it to start.

                                       //pos in queue
    memset(S, false, sizeof(S));       //init set S
    memset(T, false, sizeof(T));       //init set T
    memset(prev, -1, sizeof(prev));    //init set prev - for the alternating tree
    for (x = 0; x < n; x++)            //finding root of the tree
        if (xy[x] == -1)
        {
            q[wr++] = root = x;
            prev[x] = -2;
            S[x] = true;
            break;
        }


    for (y = 0; y < n; y++)            //initializing slack array
    {
        slack[y] = lx[root] + ly[y] - cost[root][y];
        slackx[y] = root;
    } //second part of augment() function

    
    while (true)                                                        //main cycle
    {
        while (rd < wr)                                                 //building tree with bfs cycle
        {
            x = q[rd++];                                                //current vertex from X part
            for (y = 0; y < n; y++)                                     //iterate through all edges in equality graph
                if (cost[x][y] == lx[x] + ly[y] &&  !T[y])
                {
                    if (yx[y] == -1) break;                             //an exposed vertex in Y found, so
                                                                        //augmenting path exists!
                    T[y] = true;                                        //else just add y to T,
                    q[wr++] = yx[y];                                    //add vertex yx[y], which is matched
                                                                        //with y, to the queue
                    add_to_tree(yx[y], x);                              //add edges (x,y) and (y,yx[y]) to the tree
                }
            if (y < n) break;                                           //augmenting path found!
        }
        if (y < n) break;                                               //augmenting path found!

        if (verbose)
        {
            printf("Augmenting path not found\n");

            print_S_T_sets();
        }

        update_labels();                                                //augmenting path not found, so improve labeling

        draw_all_bfs_trees(root);

        wr = rd = 0;                
        for (y = 0; y < n; y++)        
        //in this cycle we add edges that were added to the equality graph as a
        //result of improving the labeling, we add edge (slackx[y], y) to the tree if
        //and only if !T[y] &&  slack[y] == 0, also with this edge we add another one
        //(y, yx[y]) or augment the matching, if y was exposed
            if (!T[y] &&  slack[y] == 0)
            {
                if (yx[y] == -1)                                        //exposed vertex in Y found - augmenting path exists!
                {
                    x = slackx[y];
                    break;
                }
                else
                {
                    T[y] = true;                                        //else just add y to T,
                    if (!S[yx[y]])    
                    {
                        q[wr++] = yx[y];                                //add vertex yx[y], which is matched with
                                                                        //y, to the queue
                        add_to_tree(yx[y], slackx[y]);                  //and add edges (x,y) and (y,
                                                                        //yx[y]) to the tree
                    }
                }
            }
        if (y < n) break;                                               //augmenting path found!
    }


    if (y < n)                                                          //we found augmenting path!
    {

        if (verbose)
        {
            draw_graph(y); 

            printf("Augmenting path found\n");

            printf("Exposed vertex y%d (via x%d)\n", y, x);

            printf("Matching before is as follows:\n");
            print_matching();

            draw_all_bfs_trees(root);
            pause_for_user();

            printf("Augmenting path:\n");
            //printf("(y) y%d --> x%d (x) ", y, x);
            printf("y%d --> x%d ", y, x);
            fflush(stdout);
            int tx = x;
            while (prev[tx] != -2)
            {
                printf("<===> y%d ", xy[tx]);
                fflush(stdout);
                tx = prev[tx];
                printf("--> x%d ", tx);
                fflush(stdout);
                if (tx == -1)
                {
                    printf("error :-(\n");
                    break;
                }

            }
            printf("\n");

            
        }

        max_match++;                                                    //increment matching
        //in this cycle we inverse edges along augmenting path
        for (int cx = x, cy = y, ty; cx != -2; cx = prev[cx], cy = ty)
        {
            ty = xy[cx];
            yx[cy] = cx;
            xy[cx] = cy;
        }

        if (verbose)
        {

            draw_graph(y); 
            pause_for_user();

            printf("Matching after is as follows:\n");
            print_matching();
            
            printf("\n");

        }



        augment();                                                      //recall function, go to step 1 of the algorithm
    }
}//end of augment() function
Exemple #26
0
void dinic()
{
	maxflow=0;
	while(label())
		augment();
}
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;
}
template <typename captype, typename tcaptype, typename flowtype> flowtype IBFSGraph<captype, tcaptype, flowtype>::maxflowClean()
{
	node *x, *y, *xTmp, *prevTarget;
	arc *a, *aEnd, *aTmp;
	AugmentationInfo augInfo;

#ifdef STATS
	numAugs = 0;
	numOrphans = 0;
	grownSinkTree = 0;
	grownSourceTree = 0;

	numPushes = 0;
	orphanArcs1 = 0;
	orphanArcs2 = 0;
	orphanArcs3 = 0;
	growthArcs = 0;
	augLenMin = 999999;
	augLenMax = 0;
#endif

	//
	// init
	//
	orphanFirst = END_OF_ORPHANS;
	activeFirst1 = END_OF_LIST_NODE;
	activeLevel = 1;
	for (x=nodes; x<nodeLast; x++)
	{
		x->nextActive = NULL;
		x->firstSon = NULL;

		if (x->srcSinkCap == 0)
		{
			x->parent = NULL;
		}
		else
		{
			x->parent = PARENT_SRC_SINK;
			if (x->srcSinkCap > 0)
			{
				x->label = 1;
				SET_ACTIVE(x);
			}
			else
			{
				x->label = -1;
				SET_ACTIVE(x);
			}
		}
	}
	activeFirst0 = activeFirst1;
	activeFirst1 = END_OF_LIST_NODE;

	//
	// IBFS
	//
	prevTarget = NULL;
	augInfo.flowDeficit = 0;
	augInfo.flowExcess = 0;
	while (activeFirst0 != END_OF_LIST_NODE)
	{
		//
		// BFS level
		//
		while (activeFirst0 != END_OF_LIST_NODE)
		{
			x = activeFirst0;
			activeFirst0 = x->nextActive;
			x->nextActive = NULL;
			if (x->parent == NULL)
			{
				continue;
			}

			if (x->label > 0)
			{
				//
				// Source Tree
				//
				if (x->label != activeLevel)
				{
					SET_ACTIVE(x);
					continue;
				}

#ifdef STATS
				grownSourceTree++;
#endif
				aEnd = (x+1)->firstArc;
				for (a=x->firstArc; a != aEnd; a++)
				{
#ifdef STATS
					growthArcs++;
#endif
					if (a->rCap != 0)
					{
						y = a->head;
						if (y->parent == NULL)
						{
							y->label = x->label+1;
							y->parent = a->sister;
							y->nextSibling = NODE_PTR_TO_INDEX(x->firstSon);
							x->firstSon = y;
							SET_ACTIVE(y);
						}
						else if (y->label < 0)
						{
							x->nextActive = activeFirst0;
							activeFirst0 = x;
							if (prevTarget != y)
							{
								// clear deficit
								augInfo.remainingDeficit = 0;
								if (augInfo.flowDeficit != 0)
								{
									xTmp = prevTarget;
									for (; ; xTmp=aTmp->head)
									{
										aTmp = xTmp->parent;
										if (aTmp == PARENT_SRC_SINK) break;
										aTmp->sister->rCap += augInfo.flowDeficit;
										aTmp->sister_rCap = 1;
										aTmp->rCap -= augInfo.flowDeficit;
									}
									xTmp->srcSinkCap += augInfo.flowDeficit;
									augInfo.flowDeficit = 0;
								}
							}
							augment(a, &augInfo);
							prevTarget = y;
							if (x->parent == NULL || x->label != activeLevel)
							{
								break;
							}
							activeFirst0 = activeFirst0->nextActive;
							x->nextActive = NULL;
							a = ((x->firstArc)-1);
						}
					}
				}

				// clear excess
				augInfo.remainingExcess = 0;
				if (augInfo.flowExcess != 0)
				{
					xTmp = x;
					for (; ; xTmp=aTmp->head)
					{
						aTmp = xTmp->parent;
						if (aTmp == PARENT_SRC_SINK) break;
						aTmp->rCap += augInfo.flowExcess;
						aTmp->sister->sister_rCap = 1;
						aTmp->sister->rCap -= augInfo.flowExcess;
					}
					xTmp->srcSinkCap -= augInfo.flowExcess;
					augInfo.flowExcess = 0;
				}

				// clear deficit
				augInfo.remainingDeficit = 0;
				if (augInfo.flowDeficit != 0)
				{
					xTmp = prevTarget;
					for (; ; xTmp=aTmp->head)
					{
						aTmp = xTmp->parent;
						if (aTmp == PARENT_SRC_SINK) break;
						aTmp->sister->rCap += augInfo.flowDeficit;
						aTmp->sister_rCap = 1;
						aTmp->rCap -= augInfo.flowDeficit;
					}
					xTmp->srcSinkCap += augInfo.flowDeficit;
					augInfo.flowDeficit = 0;
				}
				prevTarget = NULL;
			}
			else
			{
				//
				// GROWTH SINK
				//
				if (-(x->label) != activeLevel)
				{
					SET_ACTIVE(x);
					continue;
				}

#ifdef STATS
				grownSinkTree++;
#endif
				aEnd = (x+1)->firstArc;
				for (a=x->firstArc; a != aEnd; a++)
				{
#ifdef STATS
					growthArcs++;
#endif
					if (a->sister_rCap != 0)
					{
						y = a->head;
						if (y->parent == NULL)
						{
							y->label = x->label-1;
							y->parent = a->sister;
							y->nextSibling = NODE_PTR_TO_INDEX(x->firstSon);
							x->firstSon = y;
							SET_ACTIVE(y);
						}
						else if (y->label > 0)
						{
							x->nextActive = activeFirst0;
							activeFirst0 = x;
//							if (prevTarget != j)
//							{
//								// clear excess
//								augInfo.remainingExcess = 0;
//								if (augInfo.flowExcess != 0)
//								{
//									i_tmp = prevTarget;
//									for (; ; i_tmp=a_tmp->head)
//									{
//										a_tmp = i_tmp->parent;
//										if (a_tmp == PARENT_SRC_SINK) break;
//										a_tmp->rCap += augInfo.flowExcess;
//										a_tmp->sister->sister_rCap = 1;
//										a_tmp->sister->rCap -= augInfo.flowExcess;
//									}
//									i_tmp->srcSinkCap -= augInfo.flowExcess;
//									augInfo.flowExcess = 0;
//								}
//							}
							augment(a->sister, &augInfo);
							prevTarget = y;
							if (x->parent == NULL || x->label != activeLevel)
							{
								break;
							}
							activeFirst0 = activeFirst0->nextActive;
							x->nextActive = NULL;
							a = ((x->firstArc)-1);
						}
					}
				}

				// clear excess
				augInfo.remainingExcess = 0;
				if (augInfo.flowExcess != 0)
				{
					xTmp = prevTarget;
					for (; ; xTmp=aTmp->head)
					{
						aTmp = xTmp->parent;
						if (aTmp == PARENT_SRC_SINK) break;
						aTmp->rCap += augInfo.flowExcess;
						aTmp->sister->sister_rCap = 1;
						aTmp->sister->rCap -= augInfo.flowExcess;
					}
					xTmp->srcSinkCap -= augInfo.flowExcess;
					augInfo.flowExcess = 0;
				}
				prevTarget = NULL;

				// clear deficit
				augInfo.remainingDeficit = 0;
				if (augInfo.flowDeficit != 0)
				{
					xTmp = x;
					for (; ; xTmp=aTmp->head)
					{
						aTmp = xTmp->parent;
						if (aTmp == PARENT_SRC_SINK) break;
						aTmp->sister->rCap += augInfo.flowDeficit;
						aTmp->sister_rCap = 1;
						aTmp->rCap -= augInfo.flowDeficit;
					}
					xTmp->srcSinkCap += augInfo.flowDeficit;
					augInfo.flowDeficit = 0;
				}
			}
		}

		//
		// switch to next level
		//
		activeFirst0 = activeFirst1;
		activeFirst1 = END_OF_LIST_NODE;
		activeLevel++;
	}
	
	return flow;
}
	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;
}
Exemple #30
0
template <typename captype, typename tcaptype, typename flowtype> flowtype IBFSGraph<captype, tcaptype, flowtype>::maxflow()
{
	node *i, *j, *i_tmp, *prevSrc, *prevSink;
	arc *a, *a_end, *a_tmp;
	AugmentationInfo augInfo;

	prepareGraph();

#ifdef STATS
	numAugs = 0;
	numOrphans = 0;
	grownSinkTree = 0;
	grownSourceTree = 0;

	numPushes = 0;
	orphanArcs1 = 0;
	orphanArcs2 = 0;
	orphanArcs3 = 0;
	growthArcs = 0;

	skippedGrowth = 0;
	numOrphans0 = 0;
	numOrphans1 = 0;
	numOrphans2 = 0;
	augLenMin = 999999;
	augLenMax = 0;
#endif

	//
	// init
	//
	orphanFirst = END_OF_ORPHANS;
	activeFirst1 = END_OF_LIST_NODE;
	activeLevel = 1;
	for (i=nodes; i<nodeLast; i++)
	{
		i->nextActive = NULL;
		i->firstSon = NULL;

		if (i->terminalCap == 0)
		{
			i->parent = NULL;
		}
		else
		{
			i->parent = TERMINAL;
			if (i->terminalCap > 0)
			{
				i->label = 1;
				SET_ACTIVE(i);
			}
			else
			{
				i->label = -1;
				SET_ACTIVE(i);
			}
		}
	}
	activeFirst0 = activeFirst1;
	activeFirst1 = END_OF_LIST_NODE;

	//
	// growth + augment
	//
	prevSrc = NULL;
	prevSink = NULL;
	augInfo.flowDeficit = 0;
	augInfo.flowExcess = 0;
	while (activeFirst0 != END_OF_LIST_NODE)
	{
		//
		// BFS level
		//
		while (activeFirst0 != END_OF_LIST_NODE)
		{
			/*
			i = active_src_first0;
			while (i->nextActive != END_OF_LIST_NODE)
			{
				if (i->parent &&
					i->nextActive->parent &&
					i->label > 0 &&
					i->label != activeLevel_src &&
					i->label != activeLevel_src+1)
				{
					i = active_src_first0;
					printf("flow=%d, active_label=%d, src active ",
						flow, activeLevel_src);
					while (i != END_OF_LIST_NODE)
					{
						if (i->parent &&
							(i->nextActive == END_OF_LIST_NODE ||
							i->nextActive->parent == NULL ||
							i->label != i->nextActive->label))
						{
							printf("%d ", i->label);
						}
						i = i->nextActive;
					}
					printf("\n");
					break;
				}
				i = i->nextActive;
			}
			*/

			i = activeFirst0;
			activeFirst0 = i->nextActive;
			i->nextActive = NULL;
			if (i->parent == NULL)
			{
#ifdef STATS
				skippedGrowth++;
#endif
				continue;
			}
			//if (ABS(i->label) != activeLevel &&
			//	ABS(i->label) != (activeLevel+1))
			//{
//#ifdef FLOATS
			//	printf("ERROR, flow=%f, label=%d, active_label=%d\n",
			//		flow, i->label, activeLevel);
//#else
			//	printf("ERROR, flow=%d, label=%d, active_label=%d\n",
			//		flow, i->label, activeLevel);
//#endif
			//	exit(1);
			//}

			if (i->label > 0)
			{
				//
				// GROWTH SRC
				//
				if (i->label != activeLevel)
				{
#ifdef STATS
					skippedGrowth++;
#endif
					SET_ACTIVE(i);
					continue;
				}

#ifdef STATS
				grownSourceTree++;
#endif
				a_end = (i+1)->firstArc;
				for (a=i->firstArc; a != a_end; a++)
				{
#ifdef STATS
					growthArcs++;
#endif
					if (a->rCap != 0)
					{
						j = a->head;
						if (j->parent == NULL)
						{
							j->label = i->label+1;
							j->parent = a->sister;
							j->nextSibling = NODE_PTR_TO_INDEX(i->firstSon);
							i->firstSon = j;
							SET_ACTIVE(j);
						}
						else if (j->label < 0)
						{
							i->nextActive = activeFirst0;
							activeFirst0 = i;
							if (prevSrc != i)
							{
								augInfo.remainingExcess = 0;
								if (augInfo.flowExcess != 0)
								{
									i_tmp = prevSrc;
									for (; ; i_tmp=a_tmp->head)
									{
										a_tmp = i_tmp->parent;
										if (a_tmp == TERMINAL) break;
										a_tmp->rCap += augInfo.flowExcess;
										a_tmp->sister->sister_rCap = 1;
										a_tmp->sister->rCap -= augInfo.flowExcess;
									}
									i_tmp->terminalCap -= augInfo.flowExcess;
									augInfo.flowExcess = 0;
								}
							}
							if (prevSrc != i || prevSink != j)
							{
								augInfo.remainingDeficit = 0;
								if (augInfo.flowDeficit != 0)
								{
									i_tmp = prevSink;
									for (; ; i_tmp=a_tmp->head)
									{
										a_tmp = i_tmp->parent;
										if (a_tmp == TERMINAL) break;
										a_tmp->sister->rCap += augInfo.flowDeficit;
										a_tmp->sister_rCap = 1;
										a_tmp->rCap -= augInfo.flowDeficit;
									}
									i_tmp->terminalCap += augInfo.flowDeficit;
									augInfo.flowDeficit = 0;
								}
							}
							augment(a, &augInfo);
							prevSrc = i;
							prevSink = j;
							break;
						}
					}
				}
			}
			else
			{
				//
				// GROWTH SINK
				//
				if (-(i->label) != activeLevel)
				{
#ifdef STATS
					skippedGrowth++;
#endif
					SET_ACTIVE(i);
					continue;
				}

#ifdef STATS
				grownSinkTree++;
#endif
				a_end = (i+1)->firstArc;
				for (a=i->firstArc; a != a_end; a++)
				{
#ifdef STATS
					growthArcs++;
#endif
					if (a->sister_rCap != 0)
					{
						j = a->head;
						if (j->parent == NULL)
						{
							j->label = i->label-1;
							j->parent = a->sister;
							j->nextSibling = NODE_PTR_TO_INDEX(i->firstSon);
							i->firstSon = j;
							SET_ACTIVE(j);
						}
						else if (j->label > 0)
						{
							i->nextActive = activeFirst0;
							activeFirst0 = i;
							if (prevSink != i)
							{
								augInfo.remainingDeficit = 0;
								if (augInfo.flowDeficit != 0)
								{
									i_tmp = prevSink;
									for (; ; i_tmp=a_tmp->head)
									{
										a_tmp = i_tmp->parent;
										if (a_tmp == TERMINAL) break;
										a_tmp->sister->rCap += augInfo.flowDeficit;
										a_tmp->sister_rCap = 1;
										a_tmp->rCap -= augInfo.flowDeficit;
									}
									i_tmp->terminalCap += augInfo.flowDeficit;
									augInfo.flowDeficit = 0;
								}
							}
							if (prevSink != i || prevSrc != j)
							{
								augInfo.remainingExcess = 0;
								if (augInfo.flowExcess != 0)
								{
									i_tmp = prevSrc;
									for (; ; i_tmp=a_tmp->head)
									{
										a_tmp = i_tmp->parent;
										if (a_tmp == TERMINAL) break;
										a_tmp->rCap += augInfo.flowExcess;
										a_tmp->sister->sister_rCap = 1;
										a_tmp->sister->rCap -= augInfo.flowExcess;
									}
									i_tmp->terminalCap -= augInfo.flowExcess;
									augInfo.flowExcess = 0;
								}
							}
							augment(a->sister, &augInfo);
							prevSrc = j;
							prevSink = i;
							break;
						}
					}
				}
			}
		}

		augInfo.remainingDeficit = 0;
		if (augInfo.flowDeficit != 0)
		{
			i_tmp = prevSink;
			for (; ; i_tmp=a_tmp->head)
			{
				a_tmp = i_tmp->parent;
				if (a_tmp == TERMINAL) break;
				a_tmp->sister->rCap += augInfo.flowDeficit;
				a_tmp->sister_rCap = 1;
				a_tmp->rCap -= augInfo.flowDeficit;
			}
			i_tmp->terminalCap += augInfo.flowDeficit;
			augInfo.flowDeficit = 0;
			prevSink = NULL;
		}
		augInfo.remainingExcess = 0;
		if (augInfo.flowExcess != 0)
		{
			i_tmp = prevSrc;
			for (; ; i_tmp=a_tmp->head)
			{
				a_tmp = i_tmp->parent;
				if (a_tmp == TERMINAL) break;
				a_tmp->rCap += augInfo.flowExcess;
				a_tmp->sister->sister_rCap = 1;
				a_tmp->sister->rCap -= augInfo.flowExcess;
			}
			i_tmp->terminalCap -= augInfo.flowExcess;
			augInfo.flowExcess = 0;
			prevSrc = NULL;
		}

		//
		// switch to next level
		//
#ifdef COUNT_RELABELS
		for (int k=0; k<scanIndices.size(); k++)
		{
			total++;
			if (scans[scanIndices[k]] <= 10)
			{
				counts[scans[scanIndices[k]]-1]++;
			}
		}
#endif

		activeFirst0 = activeFirst1;
		activeFirst1 = END_OF_LIST_NODE;
		activeLevel++;
	}
	
	return flow;
}