Beispiel #1
0
/*------------------------------------------------------------------------*/
VINDEX add_vertex(GRAPH* g, void *user)
{
    VINDEX new_vertex;
    MEM_POOL *m = GRAPH_m(g);

    if (GRAPH_vfree(g) == -1)
        grow_vertex(g);

    new_vertex = GRAPH_vfree(g);       /* get the free vertex  */

    /* set free vertex to next free vertex */
    GRAPH_vfree(g) = VERTEX_from(&GRAPH_v_i(g,new_vertex));

    /* no edges yet */
    VERTEX_from(&GRAPH_v_i(g,new_vertex)) = INVALID_EINDEX;
    VERTEX_to(&GRAPH_v_i(g,new_vertex)) = INVALID_EINDEX;

    /* add user information */
    VERTEX_user(&GRAPH_v_i(g,new_vertex)) = user;

    /* no from and to counts */
    VERTEX_fcnt(&GRAPH_v_i(g,new_vertex)) = 0;
    VERTEX_tcnt(&GRAPH_v_i(g,new_vertex)) = 0;

    /* no level yet */
    VERTEX_level(&GRAPH_v_i(g,new_vertex)) = -1;

    /* increment vertex count */
    GRAPH_vcnt(g)++;

    return new_vertex;
}
Beispiel #2
0
void grow_new_granule(int *c, int m,
		      int min_bound, int max_bound,
		      double (*cost_func)(int *)){
  int i;
  int simplexen = 1;
  int granules = 1;
  // Start by growing a new simplex by allowing each vertex to move
  // outward from the center (the local minimum). A vertex continues
  // moving so long as it is moving uphill. For this new simplex, the
  // allowed vertex movements are arbitrary (but must be orthogonal).

  int *movemask = calloc(m,sizeof(*movemask));
  int **new_c = malloc((m+1) * sizeof(*new_c));
  int **secondary_c = malloc((m+1) * sizeof(*secondary_c));

  for(i=0;i<(m+1);i++){
    new_c[i] = malloc(m * sizeof(**new_c));
    memcpy(new_c[i],c,sizeof(*c)*m);

    // set up orthogonal move mask for this vertex
    memset(movemask,0,sizeof(*movemask)*m);
    if(i>0)movemask[i-1]=-1;
    if(i<m)movemask[i]=1;

    // grow vertex to maximum
    grow_vertex(new_c[i], m, movemask, min_bound, max_bound, cost_func);
  }

  // this primary simplex almost certainly does not fill its
  // convergence zone; recursively spawn secondary simplexes with one
  // unconstrained vertex from the center of each face of this
  // simplex.  The new vertex must grow outward (reflect the simplex
  // through each face).
  secondary_c[0] = malloc(m * sizeof(**new_c));

  for(i=0;i<(m+1);i++){
    // build a new d-1-tope 'plane'; all the points in the current
    // simplex minus the i'th one.
    
    // fill in the fixed verticies [1 through m]
    for(j=1;j<m;j++)
      if(j<=i)
	secondary_c[j] = new_c[j-1];
      else
	secondary_c[j] = new_c[j];

    // first vertex is the unconstrained one
    center_of_tope(secondary_c[0], secondary_c+1, m);

    // set movemask; must be strictly away from local minimum
    movemask_away(c, movemask, m);

    // grow granule
    grow_secondary_granule(secondary_c, m, movemask, min_bound, max_bound, cost_func, simplexen);
  }

  // Each vertex is sitting on a ridge.  Pop over the ridge and
  // walk gradient down to a minimum. If it's a new minimum, grow a
  // new granule.

  // this is here and not above to allow each granule to fill out
  // completely before beginning work on another.

  
  for(i=0;i<(m+1);i++){
    // re-set up orthogonal move mask for this vertex
    memset(movemask,0,sizeof(*movemask)*m);
    if(i>0)movemask[i-1]=-1;
    if(i<m)movemask[i]=1;
    //crest_walk_and_recurse(new_c[i], m, movemask, min_bound, max_bound, cost_func, granules);
    free(new_c[i]);
  }
  
  free(movemask);
  free(new_c);
}
Beispiel #3
0
void grow_secondary_granule(int *minimumc,
			    int **c, int m,
			    int *movemask,
			    int min_bound, int max_bound,
			    double (*cost_func)(int *),
			    int *simplexen,
			    int *granules){
  int i;
  
  // grow the single free vertex
  int movement = grow_vertex(c[0], m, movemask, min_bound, max_bound, cost_func);

  if(movement<=1){ // 1 is roundoff error slack
    // we cannot grow a new simplex; the simplex facet is pressed flat
    // against a convergence ridge.

    // this is the correct point to crest the ridge and walk the granule
    // down the other side looking for a new minimum.  If it is indeed a new
    // minimum, grow a new granule.

    for(i=0;i<m;i++)
      c[0][i] += movemask[i];

    double cost = gradient_walk(c[0], m, min_bound, max_bound, cost_func);
    int min_num = lookup_minimum(c[0]);
    if(min_num!=-1){
      log_minimum(c[0],cost);
      grow_new_granule(c[0]); // enter recursion
    }
    
    return;
  }

  // continue recursively spawning secondary simplexes with one
  // unconstrained vertex from the center of each face of this
  // simplex.  The new vertex must grow outward (reflect the simplex
  // through each face).
  int **secondary_c = malloc((m+1) * sizeof(*secondary_c));
  secondary_c[0] = malloc(m * sizeof(**new_c));

  for(i=0;i<(m+1);i++){
    // build a new d-1-tope 'plane'; all the points in the current
    // simplex minus the i'th one.
    
    // fill in the fixed verticies [1 through m]
    for(j=1;j<m;j++)
      if(j<=i)
	secondary_c[j] = new_c[j-1];
      else
	secondary_c[j] = new_c[j];

    // first vertex is the unconstrained one
    center_of_tope(secondary_c[0], secondary_c+1, m);

    // set movemask [reverse of the i'th vertex's movemask]
    memset(movemask,0,sizeof(*movemask)*m);
    if(i>0)movemask[i-1]=1;
    if(i<m)movemask[i]=-1;

    grow_secondary_granule(secondary_c, m, movemask, min_bound, max_bound, cost_func, simplexen);
  }

  // Each vertex is sitting on a ridge.  Pop over the ridge and
  // walk gradient down to a minimum. If it's a new minimum, grow a
  // new granule.

  // this is here and not above to allow each granule to fill out
  // completely before beginning work on another.

  
  for(i=0;i<(m+1);i++){
    // re-set up orthogonal move mask for this vertex
    memset(movemask,0,sizeof(*movemask)*m);
    if(i>0)movemask[i-1]=-1;
    if(i<m)movemask[i]=1;
    //crest_walk_and_recurse(new_c[i], m, movemask, min_bound, max_bound, cost_func, granules);
    free(new_c[i]);
  }
  
  free(movemask);
  free(new_c);









}