示例#1
0
static ColorData*
find_in_cache (int *insert_index)
{
	HashEntry *bucket;
	int i, hash, size, index;

	size = dyn_array_ptr_size (&color_merge_array);
	/* Cache checking is very ineficient with a lot of elements*/
	if (size > 3)
		return NULL;

	hash = 0;
	for (i = 0 ; i < size; ++i)
		hash += mix_hash ((size_t)dyn_array_ptr_get (&color_merge_array, i));
	if (!hash)
		hash = 1;

	index = hash & (COLOR_CACHE_SIZE - 1);
	bucket = merge_cache [index];
	for (i = 0; i < ELEMENTS_PER_BUCKET; ++i) {
		if (bucket [i].hash != hash)
			continue;
		if (match_colors (&bucket [i].color->other_colors, &color_merge_array)) {
			++cache_hits;
			return bucket [i].color;
		}
	}

	//move elements to the back
	for (i = ELEMENTS_PER_BUCKET - 1; i > 0; --i)
		bucket [i] = bucket [i - 1];
	++cache_misses;
	*insert_index = index;
	bucket [0].hash = hash;
	return NULL;
}
示例#2
0
int weisfeiler_lehman1(graph G1, graph G2, int *iso)
{
  int i, j;

  // G1 and G2 must have the same number of vertices
  int size = G1.size;
  if(size != G2.size) {  
    return 0;
  }
  
  // G1 and G2 must have the same number of edges
  int edges1 = 0;
  int edges2 = 0;
  for(i=0 ; i<size ; i++) {
    list neighbors = G1.neighbors[i];
    while(neighbors != NULL) {
      edges1++;
      neighbors = neighbors->tail;
    }
    neighbors = G2.neighbors[i];
    while(neighbors != NULL) {
      edges2++;
      neighbors = neighbors->tail;
    }
  }
  if(edges1 != edges2) {
    return 0;
  }

  // this vars and tables will be important for the main loop of this algorithm. (don't forget to free() :p )

  // the reciprocical isomorphism. usefull to keep it in memory
  int *iso_inv = malloc(size*sizeof(int));

  // the color (between 0 and size-1) for each vertex in G1 and G2
  int *colors1 = malloc(size*sizeof(int));
  int *colors2 = malloc(size*sizeof(int));

  // the big_colors for each vertex in G1 and G2 after a coloration step. direct translated into int with 'match_colors'
  big_color *bc1 = malloc(size*sizeof(big_color));
  big_color *bc2 = malloc(size*sizeof(big_color));

  // contains the number of vertices for each color (in G1)
  int *V = malloc(size*sizeof(int));

  // this boolean gets true when the coloration becomes stable
  int stable = 0;

  // number of matched vertices by 'iso'. also used as stack pointer in our backtracking main loop
  int matched = 0;

  // this stack contains the vertices chronologically matched by 'iso'
  int *stack = malloc(size*sizeof(int));

  // a table used as history for the backtracking. history[i] (for 0<=i<=matched) contains for each vertex in G1 the last candidate image in G2 tested before, at this step
  // so keep more information in memory about what we have already tested than the algo described in the paper (but erasing history[matched] when backtracking also keep time !
  int **history = malloc(size*sizeof(int*));;

  // receives the easiest vertex in G1 to match (see 'vertex_to_match') and the candidate image for it in G2
  int vertex, vertex_img; 

  // initialization loop
  for(i=0 ; i<size ; i++) {
    iso[i] = -1;
    iso_inv[i] = -1;
    colors1[i] = 0;
    colors2[i] = 0;
    bc1[i] = new_big_color(size);
    bc2[i] = new_big_color(size);
    V[i] = 0;
    stack[i] = -1;
    history[i] = malloc(size*sizeof(int));
    for(j=0 ; j<size ; j++)
      history[i][j] = -1;
  }
  V[0] = size;

  
  // the main loop of the weisfeiler-lehman heuristic.
  // Contrary to what was proposed in the paper, we have chosen an iterative method,
  // so we can do more checks and detect more contradictions and easily backtrack an arbitrary number of steps in case of contradiction.

  while((matched >= 0) && (matched < size)) {


    int match_flag  = vertex_to_match(G1, colors1, iso, V, &vertex, size);

    
    if((!stable) && (match_flag==0)) { // there is no free vertex alone in its color --> coloration step now !

      refine_coloration(G1, colors1, bc1);
      refine_coloration(G2, colors2, bc2);
      int flag = match_colors(bc1, bc2, colors1, colors2, iso, V, size);
      if(flag == 0) { 
        matched = -1;
        break; // G1 and G2 are not isomorph, that is sure and we stop now !
      }
      if(flag == 2)
	stable = 1;

      int errmin; // finds the possible first error in 'iso' detected by the new coloration
      for(errmin=0 ; errmin<matched ; errmin++)
	if(colors1[stack[errmin]] != colors2[iso[stack[errmin]]])
	  break;
      if(errmin < matched) { // a previous matching in 'iso' is no proved uncorrect !!
	for(i=matched-1 ; i>=errmin ; i--) {
	  for(j=0 ; j<size ; j++)
	    history[i+1][j] = -1; // cleaning history
	  iso_inv[iso[stack[i]]] = -1;
	  iso[stack[i]] = -1;
	  stack[i] = -1;
	}
	matched = errmin; // we have erased all choices made after the false matching
      }

      // after this new coloration, we determine the now easiest vertex to find
      vertex_to_match(G1, colors1, iso, V, &vertex, size);
    }
     
    // find next candidate image for 'vertex' in G2
    for(i=history[matched][vertex]+1 ; i<size ; i++)
      if((iso_inv[i] == -1) && (colors2[i]  == colors1[vertex])) {
        vertex_img = i;
        break;
      }

    if(i == size) { // no more possibility for 'vertex' : it's time to backtrack !!
      for(j=0 ; j<size ; j++)
        history[matched][j] = -1; // cleaning history
      matched--;
      if(matched == -1)
        break;
      else {       
        iso_inv[iso[stack[matched]]] = -1;
        iso[stack[matched]] = -1;
        stack[matched] = -1;
      }
    }

    else { // 'vertex' (in G1) and 'vertex_img' (in G2) have same color
      iso[vertex] = vertex_img;
      iso_inv[vertex_img] = vertex;
      if(find_contradiction(G1, G2, iso, iso_inv, vertex)) { // but 'vertex' -> 'vertex_img' leads to a contradiction
        iso[vertex] = -1;
        iso_inv[vertex_img] = -1;
        history[matched][vertex] = vertex_img; // storing this negative test in history
      }
      else { // for now, 'vertex' -> 'vertex_img' is OK. So, assume iso(vertex)=vertex_img
	history[matched][vertex] = vertex_img; // storing this possibility in history (it will be usefull if later we backtrack :) )
	stack[matched] = vertex;
	matched++;
      }
    }


  }



  free(iso_inv);
  free(colors1);
  free(colors2);
  for(i=0 ; i<size ; i++) {
    delete_big_color(bc1[i]);
    delete_big_color(bc2[i]);
  }
  free(bc1);
  free(bc2);
  free(V);
  free(stack);
  for(i=0 ; i<size ; i++)
    free(history[i]);
  free(history);



  return (matched == size);

}