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; }
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; }
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) ; }
// 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; }
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(); }
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()); }
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; }
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()); }
//------------------------------------------------------------------------------ // 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)); }
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) ; }
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; }
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; };
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
void i_augment(pob o) { if (o->blessing > -1) Objects[o->id].known = 1; augment(o->blessing); }
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]; }
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); }
int dinic() { int f=0; while (relabel()) f+=augment(S,oo); return f; }
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
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; }
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; }