FordFulkerson::FordFulkerson(FSgraph * g) { graph = g; src = g->source; tgt = g->target; parent = (unsigned *) malloc(g->numVerts*sizeof(unsigned)); visited = (bool *) calloc(graph->numVerts,sizeof(bool)); //Find path unsigned u,p; flow = 0; expanded_verts=0; paths_searched=0; while(findPath()) { paths_searched++; unsigned pathFlow = getResidual(parent[tgt-1],tgt); for(p=tgt;p!=src;p=parent[p-1]) { u = parent[p-1]; if(getResidual(u,p)<pathFlow) pathFlow=getResidual(u,p); } for(p=tgt;p!=src;p=parent[p-1]) { u = parent[p-1]; subResidual(u,p,pathFlow); addResidual(p,u,pathFlow); } flow+=pathFlow; } }
int main ( long argc, char *argv[] ) { long N = atoi(argv[1]); double h = 1; h = h/(N+1); double h2 = h*h; double d1 = 2/h2; double d2 = -1/h2; double* pre_u; double* u; double* residuals; long i; double residual; pre_u = (double*) calloc (N+2,sizeof(double)); u = (double*) calloc (N+2,sizeof(double)); residuals = (double*) calloc (N,sizeof(double)); residual = getResidual(pre_u,residuals,N,d1,d2); double threshold = residual; threshold /= 1000000; //Jacobi long k; int j; for(k=0;;k++){ for(j=0;j<2;j++){ #pragma omp parallel for for(i=1+j;i<=N;i += 2){ u[i] = (1 - d2*(u[i-1] + pre_u[i+1]))/d1; } } #pragma omp parallel for for(i=1;i<=N;i++){ pre_u[i] = u[i]; } if((N<1000 && k%100!=0) || (N>=1000&&k%100000!=0)){ continue; } residual = getResidual(u,residuals,N,d1,d2); if(residual<=threshold){ printf("%ld iterations\n",k+1); break; } } free(u); free(pre_u); free(residuals); }
/* Maxflow / mincut algorithm : * while has augmenting path * find augmenting path * calculate new capacities */ void MaxFlow(graphtp & g, int src, int dest) { out("Maxflow: entering\n"); float flowvalue = 0; vpe P(g.size()); //parent node for node e.to is e.from while(hasAugmentingPath(g, src, dest, P)) { float capacity = INFINITY; //find capacity for(int v = dest; v != src; v = P[v]->from) { out("v=%d\n", v); assert(P[v] != NULL && "address of edge is null"); float resid_capac = getResidual(*P[v], P[v]->from, v); capacity = std::min(capacity, resid_capac); assert(capacity > 0 && "Capacity is negative "); out("reading P[%d] (0x %ld), from=%d,to=%d,flow/cap=%f/%f residcap %f, capacity=%f\n",v, P[v], P[v]->from, P[v]->to, P[v]->flow, P[v]->capacity, resid_capac, capacity); } //augment flow by capacity for(int v = dest; v != src; v = P[v]->from) { float cap = capacity; if(P[v]->backedge) cap = -cap; out("augment P[%d]->flow = %f by %f\n",v, P[v]->flow, cap); P[v]->flow += cap; } flowvalue += capacity; out("flowvalue = %f\n\n", flowvalue); } printf("Maxflow = %f\n", flowvalue); }
double CTDLearner::getTemporalDifference(CStateCollection *oldState, CAction *action, double reward, CStateCollection *newState) { double newQ = 0.0, oldQ = 0.0; double temporalDiff = 0.0; int duration = 1; if (action->isType(MULTISTEPACTION)) { duration = dynamic_cast<CMultiStepAction *>(action)->getDuration(); } // assert(lastEstimatedAction->getIndex() >= 0); oldQ = qfunction->getValue(oldState, action); // Save old prediction: Q(st,at) if (!newState->isResetState()) { if (lastEstimatedAction == NULL) { lastEstimatedAction = qfunction->getMax(newState, qfunction->getActions(), actionDataSet); } newQ = qfunction->getValue(newState, lastEstimatedAction, actionDataSet->getActionData(lastEstimatedAction)); } else { DebugPrint('t', "TD Learner: Last State of Episode, Action %d\n", qfunction->getActions()->getIndex(action)); } temporalDiff = getResidual(oldQ, reward, duration, newQ); DebugPrint('t', "OldQValue: %f\n", oldQ); DebugPrint('t', "NewQValue: %f\n", newQ); DebugPrint('t', "Reward: %f\n", reward); DebugPrint('t', "TemporalDiff: %f\n", temporalDiff); sendErrorToListeners(temporalDiff, oldState, action, NULL); return temporalDiff; }
//this is a shortest path algorithm to find an aumenting path //if an edge can carry more flow, or if a backedge can diminish more flow //that is the residual capacity, and that node gets marked and put in the que. // //to find the nodes in the mincut side, we look at the marked nodes, //ie the nodes that are reachable from source are in one side, and mincut //is the connections to the other side of the graph. bool hasAugmentingPath(graphtp & g, int src, int dest, vpe & P) { out("hasAugmentingPath: entering\n"); P.clear(); P.reserve(g.size()); vi marked(g.size()); std::queue<int> q; q.push(src); marked[src] = true; while(!q.empty()) { int node = q.front(); q.pop(); out("q.top=%d\n", node); for(ve::iterator it = g[node].begin(); it != g[node].end(); ++it) { out("edge %d-%d(%.2f/%.2f) \n", it->from, it->to, it->flow, it->capacity); assert(node == it->from && "Edge does not have same from as node"); int w = it->to; float resid_capac_to_w = getResidual(*it, it->from, it->to); out("resid cap %d -> %d = %f (%f - %f)\n", node, w, resid_capac_to_w, it->capacity, it->flow); if(resid_capac_to_w > 0 && !marked[w]) { P[w] = const_cast<edge *> (&(*it)); out("setting P[%d] to = %ld\n",w, P[w]); assert(P[w] != NULL && "address of edge is null"); marked[w] = true; q.push(w); } } } out("hasAugmentingPath: returning %d\n\n", marked[dest]); return marked[dest]; }