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;
    }
}
Esempio n. 2
0
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);
}
Esempio n. 4
0
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];
}