예제 #1
0
파일: BellmanFord.C 프로젝트: flavioc/ligra
void Compute(graph<vertex>& GA, commandLine P) {
  long ratio = P.getOptionLongValue("-r",1000);
  long n = GA.n;
  printf("Nodes: %d Ratio %d\n", n, ratio);

  for(size_t i(0); i < n; ++i) {
     if(i % ratio != 0)
        continue;
     intE* ShortestPathLen = newA(intE,n);
     int* Visited = newA(int,n);

     //initialize ShortestPathLen to "infinity"
     {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = INT_MAX/2;}
     ShortestPathLen[i] = 0;

     {parallel_for(long i=0;i<n;i++) Visited[i] = 0;}

     vertexSubset Frontier(n,i); //initial frontier

     long round = 0;
     while(!Frontier.isEmpty()){
        if(round == n) {
           //negative weight cycle
           {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = -(INT_E_MAX/2);}
           break;
        }
        vertexSubset output = edgeMap(GA, Frontier, BF_F(ShortestPathLen,Visited), GA.m/20, DENSE_FORWARD);
        vertexMap(output,BF_Vertex_F(Visited));
        Frontier.del();
        Frontier = output;
        round++;
     } 
예제 #2
0
void Compute(graph<vertex>& GA, commandLine P) {
  t1.start();
  long start = P.getOptionLongValue("-r",0);
  if(GA.V[start].getOutDegree() == 0) { 
    cout << "starting vertex has degree 0" << endl;
    return;
  }
  const uintE K = P.getOptionIntValue("-K",10);
  const uintE N = P.getOptionIntValue("-N",10);
  const double t = P.getOptionDoubleValue("-t",3);
  srand (time(NULL));
  uintE seed = rand();
  const intE n = GA.n;

  //walk length probabilities
  double* fact = newA(double,K);
  fact[0] = 1;
  for(long k=1;k<K;k++) fact[k] = k*fact[k-1];
  double* probs = newA(double,K);
  for(long k=0;k<K;k++) probs[k] = exp(-t)*pow(t,k)/fact[k];

  unordered_map<uintE,double> p;
  for(long i=0;i<N;i++) {
    double randDouble = (double) hashInt(seed++) / UINT_E_MAX;
    long j = 0;
    double mass = 0;
    uintE x = start;
    do {
      mass += probs[j];
      if(randDouble < mass) break;
      x = walk(x,GA.V,seed++);
      j++;
    } while(j <= K);
    p[x]++;
  }
  for(auto it=p.begin();it!=p.end();it++) {
    p[it->first] /= N;
  }

  free(probs); free(fact);
  t1.stop();
  pairIF* A = newA(pairIF,p.size());

  long numNonzerosQ = 0;
  for(auto it = p.begin(); it != p.end(); it++) {
    A[numNonzerosQ++] = make_pair(it->first,it->second);
  }
  sweepObject sweep = sweepCut(GA,A,numNonzerosQ,start);
  free(A);
  cout << "number of vertices touched = " << p.size() << endl;
  cout << "number of edges touched = " << sweep.vol << endl;
  cout << "conductance = " << sweep.conductance << " |S| = " << sweep.sizeS << " vol(S) = " << sweep.volS << " edgesCrossing = " << sweep.edgesCrossing << endl; 
  t1.reportTotal("computation time");
}
예제 #3
0
파일: BellmanFord.C 프로젝트: mindis/ligra
void Compute(graph<vertex>& GA, commandLine P) {
  long start = P.getOptionLongValue("-r",0);
  long n = GA.n;
  //initialize ShortestPathLen to "infinity"
  intE* ShortestPathLen = newA(intE,n);
  {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = INT_MAX/2;}
  ShortestPathLen[start] = 0;

  int* Visited = newA(int,n);
  {parallel_for(long i=0;i<n;i++) Visited[i] = 0;}

  vertexSubset Frontier(n,start); //initial frontier

  long round = 0;
  while(!Frontier.isEmpty()){
    if(round == n) {
      //negative weight cycle
      {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = -(INT_E_MAX/2);}
      break;
    }
예제 #4
0
void Compute(graph<vertex>& GA, commandLine P) {
  long start = P.getOptionLongValue("-r",0);
  long n = GA.n;
  //creates Parents array, initialized to all -1, except for start
  uintE* Parents = newA(uintE,n);
  parallel_for(long i=0;i<n;i++) Parents[i] = UINT_E_MAX;
  Parents[start] = start;
  //create bitvector to mark visited vertices
  long numWords = (n+63)/64;
  long* Visited = newA(long,numWords);
  {parallel_for(long i=0;i<numWords;i++) Visited[i] = 0;}
  Visited[start/64] = (long)1 << (start % 64);
  vertexSubset Frontier(n,start); //creates initial frontier

  while(!Frontier.isEmpty()){ //loop until frontier is empty
    vertexSubset output = edgeMap(GA, Frontier, BFS_F(Parents,Visited),GA.m/20);    
    Frontier.del();
    Frontier = output; //set new frontier
  } 
  Frontier.del();
  free(Parents); free(Visited);
}
예제 #5
0
void Compute(graph<vertex>& GA, commandLine P) {
  t1.start();
  long start = P.getOptionLongValue("-r",0);
  if(GA.V[start].getOutDegree() == 0) { 
    cout << "starting vertex has degree 0" << endl;
    return;
  }
  const int procs = P.getOptionIntValue("-p",0);
  if(procs > 0) setWorkers(procs);
  const double t = P.getOptionDoubleValue("-t",3);
  const double epsilon = P.getOptionDoubleValue("-e",0.000000001);
  const uintE N = P.getOptionIntValue("-N",1);
  const intE n = GA.n;
  const double constant = exp(t)*epsilon/(2*(double)N);
  double* psis = newA(double,N);
  double* fact = newA(double,N);
  fact[0] = 1;
  for(long k=1;k<N;k++) fact[k] = k*fact[k-1];
  double* tm = newA(double,N);
  {parallel_for(long m=0;m<N;m++) tm[m]  = pow(t,m);}
  {parallel_for(long k=0;k<N;k++) {
    psis[k] = 0;
    for(long m=0;m<N-k;m++)
      psis[k] += fact[k]*tm[m]/(double)fact[m+k];
    }}

  sparseAdditiveSet<float> x = sparseAdditiveSet<float>(10000,1,0.0);
  sparseAdditiveSet<float> r = sparseAdditiveSet<float>(2,1,0.0);
  x.insert(make_pair(start,0.0));
  r.insert(make_pair(start,1.0));
  vertexSubset Frontier(n,start);

  long j = 0, totalPushes = 0;
  while(Frontier.numNonzeros() > 0){
    totalPushes += Frontier.numNonzeros();
    uintT* Degrees = newA(uintT,Frontier.numNonzeros());
    {parallel_for(long i=0;i<Frontier.numNonzeros();i++) Degrees[i] = GA.V[Frontier.s[i]].getOutDegree();}
    long totalDegree = sequence::plusReduce(Degrees,Frontier.numNonzeros());
    free(Degrees);
    if(j+1 < N) {
      long rCount = r.count();
      //make bigger hash table initialized to 0.0's
      sparseAdditiveSet<float> new_r = sparseAdditiveSet<float>(max(100L,min((long)n,totalDegree+rCount)),LOAD_FACTOR,0.0); 
      vertexMap(Frontier,Local_Update(x,r));
      vertexSubset output = edgeMap(GA, Frontier, HK_F<vertex>(x,r,new_r,GA.V,t/(double)(j+1)));
      r.del(); 
      r = new_r;
      if(x.m < ((uintT) 1 << log2RoundUp((uintT)(LOAD_FACTOR*min((long)n,rCount+output.numNonzeros()))))) {
	sparseAdditiveSet<float> new_x = sparseAdditiveSet<float>(LOAD_FACTOR*min((long)n,rCount+output.numNonzeros()),LOAD_FACTOR,0.0); //make bigger hash table
	new_x.copy(x);
	x.del();
	x = new_x;
      }
      output.del();

      //compute active set (faster in practice to just scan over r)
      _seq<ACLpair> vals = r.entries(activeF<vertex>(GA.V,constant/psis[j+1]));
      uintE* Active = newA(uintE,vals.n);
      parallel_for(long i=0;i<vals.n;i++) Active[i] = vals.A[i].first;
      Frontier.del(); vals.del();
      Frontier = vertexSubset(n,vals.n,Active);
      j++;
    } else { //last iteration
예제 #6
0
파일: kBFS-Ecc.C 프로젝트: cequencer/ligra
void Compute(graph<vertex>& GA, commandLine P) {
  t5.start();
  long length = P.getOptionLongValue("-r",0); //number of words per vertex
  char* oFile = P.getOptionValue("-out"); //file to write eccentricites
  srand (time(NULL));
  uintT seed = rand();
  cout << "seed = " << seed << endl;
  t0.start();
  long n = GA.n;
  
  uintE* ecc = newA(uintE,n);
  uintE* ecc2 = newA(uintE,n);
  {parallel_for(long i=0;i<n;i++) {
      ecc[i] = ecc2[i] = 0;
    }}

  t0.stop();

  //BEGIN COMPUTE CONNECTED COMPONENTS
  t1.start();
  intE* Labels = newA(intE,n);
  {parallel_for(long i=0;i<n;i++) {
    if(GA.V[i].getOutDegree() == 0) Labels[i] = -i-1; //singletons
    else Labels[i] = INT_E_MAX;
    }}

  //get max degree vertex
  uintE maxV = sequence::reduce<uintE>((intE)0,(intE)n,maxF<intE>(),getDegree<vertex>(GA.V));

  //visit large component with BFS
  CCBFS(maxV,GA,Labels);
  //visit small components with label propagation
  Components(GA, Labels);

  //sort by component ID
  intPair* CCpairs = newA(intPair,n);
  {parallel_for(long i=0;i<n;i++)
    if(Labels[i] < 0)
      CCpairs[i] = make_pair(-Labels[i]-1,i);
    else CCpairs[i] = make_pair(Labels[i],i);
  }
  free(Labels);

  intSort::iSort(CCpairs, n, n+1,firstF<uintE,uintE>());

  uintE* changes = newA(uintE,n);
  changes[0] = 0;
  {parallel_for(long i=1;i<n;i++) 
      changes[i] = (CCpairs[i].first != CCpairs[i-1].first) ? i : UINT_E_MAX;}

  uintE* CCoffsets = newA(uintE,n);
  uintE numCC = sequence::filter(changes, CCoffsets, n, nonMaxF());
  CCoffsets[numCC] = n;
  free(changes);
  t1.stop();
  //END COMPUTE CONNECTED COMPONENTS

  //init data structures
  t0.start();
  length = max((long)1,min((n+63)/64,(long)length));
  long* VisitedArray = newA(long,n*length);
  long* NextVisitedArray = newA(long,n*length); 
  int* flags = newA(int,n);
  {parallel_for(long i=0;i<n;i++) flags[i] = -1;}
  uintE* starts = newA(uintE,n);
  intPair* pairs = newA(intPair,n);
  t0.stop();

  //BEGIN COMPUTE ECCENTRICITES PER COMPONENT
  for(long k = 0; k < numCC; k++) {
    t2.start();
    uintE o = CCoffsets[k];
    uintE CCsize = CCoffsets[k+1] - o;
    if(CCsize == 2) { //size 2 CC's have ecc of 1
      ecc[CCpairs[o].second] = ecc[CCpairs[o+1].second] = 1;
      t2.stop();
    } else if(CCsize > 1) { //size 1 CC's already have ecc of 0
      //do main computation
      long myLength = min((long)length,((long)CCsize+63)/64);

      //initialize bit vectors for component vertices
      {parallel_for(long i=0;i<CCsize;i++) {
	uintT v = CCpairs[o+i].second;
	parallel_for(long j=0;j<myLength;j++)
	  VisitedArray[v*myLength+j] = NextVisitedArray[v*myLength+j] = 0;
	}}

      long sampleSize = min((long)CCsize,(long)64*myLength);

      uintE* starts2 = newA(uintE,sampleSize);

      //pick random vertices (could have duplicates)
      {parallel_for(ulong i=0;i<sampleSize;i++) {
	uintT index = hashInt(i+seed) % CCsize;
	if(flags[index] == -1 && CAS(&flags[index],-1,(int)i)) {
	  starts[i] = CCpairs[o+index].second;
	  NextVisitedArray[CCpairs[o+index].second*myLength + i/64] = (long) 1<<(i%64);
	} else starts[i] = UINT_E_MAX;
	}}

      //remove duplicates
      uintE numUnique = sequence::filter(starts,starts2,sampleSize,nonMaxF());

      //reset flags
      parallel_for(ulong i=0;i<sampleSize;i++) {
	uintT index = hashInt(i+seed) % CCsize;
	if(flags[index] == i) flags[index] = -1;
      }

      //first phase
      vertexSubset Frontier(n,numUnique,starts2); //initial frontier
      //note: starts2 will be freed inside the following loop
      uintE round = 0;
      while(!Frontier.isEmpty()){
	round++;
	vertexMap(Frontier, Ecc_Vertex_F(myLength,VisitedArray,NextVisitedArray));
	vertexSubset output = 
	  edgeMap(GA, Frontier, 
		  Ecc_F(myLength,VisitedArray,NextVisitedArray,ecc,round),
		  GA.m/20);
	Frontier.del();
	Frontier = output;
      }
      Frontier.del();
      t2.stop();
      //second phase if size of CC > 64
      if(CCsize > 1024) {
	//sort by ecc
	t3.start();
	{parallel_for(long i=0;i<CCsize;i++) {
	  pairs[i] = make_pair(ecc[CCpairs[o+i].second],CCpairs[o+i].second);
	  }}
	intPair maxR = sequence::reduce(pairs,CCsize,maxFirstF());
	intSort::iSort(pairs, CCsize, 1+maxR.first, firstF<uintE,uintE>());
	t3.stop();

	t4.start();

	//reset bit vectors for component vertices
	{parallel_for(long i=0;i<CCsize;i++) {
	  uintT v = CCpairs[o+i].second;
	  parallel_for(long j=0;j<myLength;j++)
	    VisitedArray[v*myLength+j] = NextVisitedArray[v*myLength+j] = 0;
	  }}

	starts2 = newA(uintE,sampleSize);
	//pick starting points with highest ecc ("fringe" vertices)
	{parallel_for(long i=0;i<sampleSize;i++) {
	  intE v = pairs[CCsize-i-1].second;
	  starts2[i] = v;
	  NextVisitedArray[v*myLength + i/64] = (long) 1<<(i%64);
	  }}

	vertexSubset Frontier2(n,sampleSize,starts2); //initial frontier
	//note: starts2 will be freed inside the following loop
	round = 0;
	while(!Frontier2.isEmpty()){
	  round++;
	  vertexMap(Frontier2, Ecc_Vertex_F(myLength,VisitedArray,NextVisitedArray));
	  vertexSubset output = 
	    edgeMap(GA, Frontier2,Ecc_F(myLength,VisitedArray,NextVisitedArray,ecc2,round), GA.m/20);
	  Frontier2.del();
	  Frontier2 = output;
	}
	Frontier2.del();
	{parallel_for(long i=0;i<n;i++) ecc[i] = max(ecc[i],ecc2[i]);}
	t4.stop();
      }
    }