コード例 #1
0
ファイル: main.c プロジェクト: PhilippeGeek/3TC-AGP-TP
int main() {
    TREE t1, t2, tree;
    srand((unsigned int) time(NULL));
    int i;
    tree = tree_create(0, NULL, NULL);
    tree_print_list(tree);
    printf("\nTree depth : %d\n", tree_depth(tree));
    printf("Tree is balanced : %d\n", tree_is_balanced(tree));

    tree_add(tree, 1);
    tree_print_list(tree);
    printf("\nTree depth : %d\n", tree_depth(tree));
    printf("Tree is balanced : %d\n", tree_is_balanced(tree));

    tree_add(tree, 2);
    tree_print_list(tree);
    printf("\nTree depth : %d\n", tree_depth(tree));
    printf("Tree is balanced : %d\n", tree_is_balanced(tree));

    tree_add(tree, -2);
    tree_print_list(tree);
    printf("\nTree depth : %d\n", tree_depth(tree));
    printf("Tree is balanced : %d\n", tree_is_balanced(tree));

    tree_add(tree, -1);
    tree_print_list(tree);
    printf("\nTree depth : %d\n", tree_depth(tree));
    printf("Tree is balanced : %d\n", tree_is_balanced(tree));
    return 0;
}
コード例 #2
0
/** Insert entry into the index tree. 
 *
 * Compares the value of the string with the value in the root node, then
 * either recursively inserts the value in the left or right sub-trees, or
 * adds the value to the root node.
 * 
 * @param[in] root_node - a pointer to the root of the (sub-)tree.
 * @param[in] value_str_len - length of the string to be inserted.
 * @param[in] value_str - A pointer to string to be inserted.
 * @param[in] p - The "location" value associated with the string.
 * 
 * @return New root node of the tree, or null if there is an error inserting
 *    the string value (memory allocation failure)
 */
static IndexTreeNode *index_tree_insert(
   IndexTreeNode *root_node,
   size_t value_str_len,
   const char *value_str,
   void *p)
{
   int cmp = compare_with_tree_node(value_str_len, value_str, root_node);
   if (cmp < 0)
   {
      /* Put it into the left-hand subtree */
      if (root_node->left_node)
      {
         IndexTreeNode *new_subtree_root = index_tree_insert(root_node->left_node, value_str_len, value_str, p);
         if (!new_subtree_root)
            /* Error return */
            return (IndexTreeNode *)0;
         root_node->left_node = new_subtree_root;
         root_node->left_depth = tree_depth(new_subtree_root);
      }
      else
      {
         IndexTreeNode *new_node = create_index_tree_node(root_node, value_str_len, value_str, p);
         if (!new_node)
            return (IndexTreeNode *)0;
         root_node->left_node = new_node;
         root_node->left_depth = 1;
      }
   }
   else if (cmp > 0)
   {
      /* Put it into the right-hand subtree */
      if (root_node->right_node)
      {
         IndexTreeNode *new_subtree_root = index_tree_insert(root_node->right_node, value_str_len, value_str, p);
         if (!new_subtree_root)
            /* Error return */
            return (IndexTreeNode *)0;
         root_node->right_node = new_subtree_root;
         root_node->right_depth = tree_depth(new_subtree_root);
      }
      else
      {
         IndexTreeNode *new_node = create_index_tree_node(root_node, value_str_len, value_str, p);
         if (!new_node)
            return (IndexTreeNode *)0;
         root_node->right_node = new_node;
         root_node->right_depth = 1;
      }
   }
   else
   {
      /* Add it to the current node */
      if (!index_node_insert_value(root_node, p))
         return (IndexTreeNode *)0;
   }

   /* Perform any re-balancing required */
   return rebalance_tree(root_node);
}
コード例 #3
0
ファイル: read-dict.c プロジェクト: dyne/AutOrg
/* Return tree height. XXX this is not tail-recursive! */
static int tree_depth (Dict_node *n)
{
	int l, r;
	if (NULL == n) return 0;
	if (NULL == n->left) return 1+tree_depth(n->right);
	if (NULL == n->right) return 1+tree_depth(n->left);
	l = tree_depth(n->left);
	r = tree_depth(n->right);
	if (l < r) return r+1;
	return l+1;
}
コード例 #4
0
ファイル: eg2.c プロジェクト: benzhemin/data-structure
int tree_depth(BiTree *T){
	if(T != NULL){
		int ldepth,rdepth;
		ldepth = tree_depth(T->lchild);
		rdepth = tree_depth(T->rchild);
		
		return ldepth > rdepth ? (ldepth+1) : (rdepth+1);

	}else{
		return 0;
	}
}
コード例 #5
0
/** Extract the rightmost entry of the given sub-tree.
 *
 * First locate the rightmost entry.  If this is the root node, then the new
 * root node is the node's left sub-tree.  Otherwise, the parent's right node
 * becomes the rightmost node's left sub-tree, and we traverse the tree to the
 * root node, rebalancing as we go.
 * 
 * @param[in] root_node - a pointer to the root of the (sub-)tree.
 * @param[in] rightmost_node - pointer to the location to store the rightmost node's pointer.
 * 
 * @return New root node of the (sub-)tree, or null if the tree is now empty
 */
static IndexTreeNode *extract_rightmost(IndexTreeNode *root_node, IndexTreeNode **rightmost_node)
{
   IndexTreeNode *parent_node, *current_node;
   *rightmost_node = root_node;
   while ((*rightmost_node)->right_node) {
      *rightmost_node = (*rightmost_node)->right_node;
   }
   /* Remove the rightmost node from the tree */
   if (*rightmost_node == root_node)
   {
      /* Just return the left sub-tree  - already balanced, or empty */
      return (*rightmost_node)->left_node;
   }
   else
   {
      /* Move the rightmost node's left sub-tree to the parent's right sub-tree */
      current_node = (*rightmost_node)->parent_node;
      current_node->right_node = (*rightmost_node)->left_node;
      if (current_node->right_node)
         current_node->right_node->parent_node = current_node;
      current_node->right_depth = tree_depth(current_node->right_node);
   }
   while (current_node != root_node)
   {
      parent_node = current_node->parent_node;
      parent_node->right_node = rebalance_tree(current_node);
      current_node = parent_node;
   }
   return rebalance_tree(current_node);
}
コード例 #6
0
ファイル: forktree_demo.c プロジェクト: 54shady/linuxc
int main(int argc, char **argv)
{
	/* 根据前序和中序遍历结果构造二叉树 */
	unsigned char pre_seq[] = { 4, 2, 1, 3, 6, 5, 7 };
	unsigned char in_seq[] = { 1, 2, 3, 4, 5, 6, 7 };
	/*
	 *		    4
	 *		   / \
	 *       2	   6
	 *      / \   / \
	 *     1   3  5  7
	 */

	printf("Create a tree with pre and in sequence\n");
	BiTree bTree = init(pre_seq, in_seq, 7);

	printf("Fork a tree\n");
	BiTree forkTree;
	forkTree = fork_tree(bTree);
	printf("pre: ");
	pre_order(forkTree, print_item);
	putchar('\n');
	printf("Tree count = %d depth = %d\n", tree_leavess(forkTree), tree_depth(forkTree));

	tree_destroy(bTree);
	tree_destroy(forkTree);

	return 0;
}
コード例 #7
0
ファイル: individ.c プロジェクト: Quamber/lil-gp-eclipse
int individual_depth ( individual *ind )
{
     int i, j, k = 0;

     for ( j = 0; j < tree_count; ++j )
     {
          if ( ( i = tree_depth ( ind->tr[j].data ) ) > k )
               k = i;
     }
     return k;
}
コード例 #8
0
ファイル: eg2.c プロジェクト: benzhemin/data-structure
int main(void){
	BiTree *T = NULL;
	create_bitree(&T);

	//traverse(T, 0);
	int d = tree_depth(T);

	printf("depth:%d\n", d);

	return 0;
}
コード例 #9
0
// number of nodes on the longest path
int tree_depth( SearchTree T )
{
  // returns -1 if T is NULL
  if (T == NULL)
  {
     return -1;
  } 
  else
  {
     int leftD, rightD;
     leftD = tree_depth (T -> left);
     rightD = tree_depth (T -> right);
     
     // select the larger
     if (leftD > rightD)
     {
         return (leftD + 1);
     }    
     else
     {
         return (rightD + 1);
     }
  }
}
コード例 #10
0
void print_tree(IndexTreeNode *root_node, unsigned depth)
{
   char *value_str;
   int i;
   char buffer[256];

   if (!root_node)
      return;
   print_tree(root_node->left_node, depth+1);
   for (i = 0; i < depth; i++)
      SLPDLog("   ");
   value_str = get_value_string(root_node);
   sprintf(buffer, "%03d %3d %s\n", tree_depth(root_node), count_values(root_node), value_str);
   SLPDLog(buffer);
   free(value_str);
   print_tree(root_node->right_node, depth+1);
}
コード例 #11
0
ファイル: tree.c プロジェクト: lchish/cosc
/**
 Calculates the greatest depth of the tree.
 @param t tree to find the depth of.
 @return maximum depth of the tree.
 */
int tree_depth(tree t)
{
  if(t->left != NULL && t->right != NULL){
    return tree_depth(t->left) > tree_depth(t->right) 
      ? tree_depth(t->left)+1 : tree_depth(t->right)+1;
   }else if(t->left != NULL){
    return tree_depth(t->left)+1;
  }else if(t->right != NULL){
    return tree_depth(t->right)+1;
  }else{
    return 0;
  }
}
コード例 #12
0
ファイル: p4_e5.c プロジェクト: OscarGB/Prog-2
int main (int argc, char *argv[]){
	FILE *f = NULL;
	Tree *tree = NULL;
	EleTree *pele = NULL;
	Cadena* cad = NULL;
	int numnodos, profundidad;
	char cadena[MAX], buscar[MAX];


	if(argc != 2){ /*Comprobamos argumentos*/
	printf("Faltan argumentos\n");
	return -1;
	}

	f = fopen (argv[1], "r"); /*Abrimos el fichero recibido como argumento*/
	if (!f){
		return -1;
	}

	tree = tree_ini(); /*Inicializamos el árbol en el que vamos a guardar las cadenas*/
	if (!tree){
		fclose(f);
		return -1;
	}

	while (feof(f) == 0){ /*Bucle que lee uno a uno las cadenas del fichero*/
		fscanf (f, "%s\n", cadena); /*Guardamos el dato leido en cadena*/
		pele = eletree_ini(); /*Inicializamos un EleTree*/
		if (!pele){
			fclose(f);
			tree_free(tree);
			return -1;
		}
		cad = cadena_ini(); /*Inicializamos una cadena*/
		if(!cad){
			eletree_free(pele);
			fclose(f);
			tree_free(tree);
			return -1;
		}
		if(!cadena_setInfo(cad, cadena)){
			fclose(f);
			tree_free(tree);
			eletree_free(pele);
			cadena_free(cad);
			return -1;
		}
		if (!eletree_setInfo (pele, cad)){ /*Asignamos al EleTree la cadena guardada*/
			fclose(f);
			tree_free(tree);
			eletree_free(pele);
			cadena_free(cad);
			return -1;
		}
		tree_insert (tree, pele); /*Insertamos el EleTree en el árbol*/
		eletree_free(pele);
		cadena_free(cad);
	}
	numnodos = tree_numNodes (tree);
	profundidad = tree_depth (tree);
	printf ("Número de nodos: %d\n", numnodos);
	printf ("Profundidad: %d\n", profundidad);
	if(tree_inOrder(stdout, tree) == ERROR){
		fclose (f);
		tree_free(tree);
		return -1;
	}
	printf ("Introduce una cadena para buscar en el árbol (siguiendo el mismo formato que en el fichero de entrada): ");
	scanf ("%s", buscar);
	pele = eletree_ini(); /*Inicializamos un EleTree*/
	if (!pele){
		fclose (f);
		tree_free(tree);
		return -1;
	}
	cad = cadena_ini(); /*Inicializamos una cadena*/
	if(!cad){
		fclose (f);
		tree_free(tree);
		eletree_free(pele);
		return -1;		
	}
	if(!cadena_setInfo(cad, buscar)){
		fclose(f);
		tree_free(tree);
		eletree_free(pele);
		cadena_free(cad);
		return -1;
	}
	if (!eletree_setInfo(pele, cad)){ /*Asignamos al EleTree la cadena "buscar"*/
		fclose (f);
		tree_free(tree);
		eletree_free(pele);
		return -1;
	}
	if (tree_findEleTree (tree, pele) == TRUE){ /*Buscamos en el árbol el entero introducido previamente*/
		printf ("El dato %s se encuentra dentro del árbol\n", buscar);
	}
	else {
		printf ("El dato %s NO se encuentra dentro del árbol\n", buscar);
	}
	tree_free(tree); /*Liberamos toda la memoria*/
	eletree_free(pele);
	fclose (f);
	cadena_free(cad);
	return -1;
}
コード例 #13
0
/** Delete entry from the index tree.
 *
 * Compares the value of the string with the value in the root node, then
 * either recursively deletes the value in the left or right sub-trees, or
 * deletes the value from the root node.
 * If the root_node needs to be deleted, then create a new tree from its
 * subtrees, re-balancing where necessary.
 * 
 * @param[in] root_node - a pointer to the root of the (sub-)tree.
 * @param[in] value_str_len - length of the string to be removed.
 * @param[in] value_str - A pointer to string to be removed.
 * @param[in] p - The "location" value associated with the string.
 * 
 * @return New root node of the tree, or null if the tree is now empty
 */
IndexTreeNode *index_tree_delete(
   IndexTreeNode *root_node,
   size_t value_str_len,
   const char *value_str,
   void *p)
{
   int cmp;
   
   if (!root_node)
      /* Shouldn't really happen, but nothing to do */
      return root_node;

   cmp = compare_with_tree_node(value_str_len, value_str, root_node);
   if (cmp < 0)
   {
      root_node->left_node = index_tree_delete(root_node->left_node, value_str_len, value_str, p);
      root_node->left_depth = tree_depth(root_node->left_node);
      if (root_node->left_node)
         root_node->left_node->parent_node = root_node;
   }
   else if (cmp > 0)
   {
      root_node->right_node = index_tree_delete(root_node->right_node, value_str_len, value_str, p);
      root_node->right_depth = tree_depth(root_node->right_node);
      if (root_node->right_node)
         root_node->right_node->parent_node = root_node;
   }
   else
   {
      IndexTreeNode *replacement_node;

      /* Find the given location in the value list */
      IndexTreeValue *entry = find_in_value_set(root_node->value, p);
      if (!entry)
         /* Shouldn't really happen, but nothing to do */
         return root_node;

      root_node->value = remove_from_value_set(root_node->value, entry);
      free_index_tree_value(entry);

      if (root_node->value)
         /* All we've done is remove one of the values in the set for this node,
          * so the tree structure does not need to be changed
          */
         return root_node;

      /* The node needs to be deleted, so replace this node by the leftmost
       * node of the right sub-tree, or the rightmost mode of the left
       * sub-tree, depending on which has the greater depth
       */
      if (root_node->left_depth > root_node->right_depth)
      {
         root_node->left_node = extract_rightmost(root_node->left_node, &replacement_node);
         root_node->left_depth = tree_depth(root_node->left_node);
      }
      else if (root_node->right_node)
      {
         root_node->right_node = extract_leftmost(root_node->right_node, &replacement_node);
         root_node->right_depth = tree_depth(root_node->right_node);
      }
      else
      {
         /* Both sub-trees are empty  ie. this is a leaf node */
         free_index_tree_node(root_node);
         return (IndexTreeNode *)0;
      }
      replacement_node->right_node = root_node->right_node;
      replacement_node->right_depth = root_node->right_depth;
      if (replacement_node->right_node)
         replacement_node->right_node->parent_node = replacement_node;
      replacement_node->left_node = root_node->left_node;
      replacement_node->left_depth = root_node->left_depth;
      if (replacement_node->left_node)
         replacement_node->left_node->parent_node = replacement_node;
      free_index_tree_node(root_node);
      root_node = replacement_node;
   }
   root_node = rebalance_tree(root_node);
#if defined(DEBUG) && defined(CHECKING)
   if (!check_tree(root_node))
   {
      SLPDLog("Index tree check fails deleting from tree %p\n", root_node);
   }
#endif
   return root_node;
}
コード例 #14
0
/** Re-balance the (sub-)tree, if necessary. 
 *
 * Checks whether the tree is balanced, and performs rotations as required to
 * re-balance if necessary.
 * 
 * @param[in] root_node - a pointer to the root of the (sub-)tree.
 * 
 * @return New root node of the tree
 */
static IndexTreeNode *rebalance_tree(
   IndexTreeNode *root_node)
{
   /* Check whether we need to re-balance the (sub-)tree */
   if (root_node->left_depth - root_node->right_depth == 2)
   {
      /* Need to perform a right-rotation */
      IndexTreeNode *parent_node;
      IndexTreeNode *pivot = root_node->left_node;
      if (tree_depth(pivot->right_node) > tree_depth(pivot->left_node))
      {
         /* Rotate the pivot tree left first, as the right subtree will be
          * going beneath the current root node which will be going beneath
          * the pivot node, so will increase the depth.  By rotating the
          * subtrees, we ensure that the shallower sub-tree has its depth
          * increased, to minimise the difference in depth
          */
         IndexTreeNode *new_pivot = pivot->right_node;
         parent_node = pivot->parent_node;
         pivot->right_node = new_pivot->left_node;
         if (pivot->right_node)
            pivot->right_node->parent_node = pivot;
         pivot->right_depth = new_pivot->left_depth;
         pivot->parent_node = new_pivot;
         new_pivot->left_node = pivot;
         new_pivot->left_depth = tree_depth(pivot);
         new_pivot->parent_node = parent_node;
         pivot = new_pivot;
      }
      /* Now perform the right rotation */
      parent_node = root_node->parent_node;
      root_node->left_node = pivot->right_node;
      if (root_node->left_node)
         root_node->left_node->parent_node = root_node;
      root_node->left_depth = pivot->right_depth;
      root_node->parent_node = pivot;
      pivot->right_node = root_node;
      pivot->right_depth = tree_depth(root_node);
      pivot->parent_node = parent_node;
      root_node = pivot;
   }
   else if (root_node->right_depth - root_node->left_depth == 2)
   {
      /* Need to perform a left-rotation */
      IndexTreeNode *parent_node;
      IndexTreeNode *pivot = root_node->right_node;
      if (tree_depth(pivot->left_node) > tree_depth(pivot->right_node))
      {
         /* Rotate the pivot tree right first, as the left subtree will be
          * going beneath the current root node which will be going beneath
          * the pivot node, so will increase the depth.  By rotating the
          * subtrees, we ensure that the shallower sub-tree has its depth
          * increased, to minimise the difference in depth
          */
         IndexTreeNode *new_pivot = pivot->left_node;
         parent_node = pivot->parent_node;
         pivot->left_node = new_pivot->right_node;
         if (pivot->left_node)
            pivot->left_node->parent_node = pivot;
         pivot->left_depth = new_pivot->right_depth;
         pivot->parent_node = new_pivot;
         new_pivot->right_node = pivot;
         new_pivot->right_depth = tree_depth(pivot);
         new_pivot->parent_node = parent_node;
         pivot = new_pivot;
      }
      /* Now perform the left rotation */
      parent_node = root_node->parent_node;
      root_node->right_node = pivot->left_node;
      if (root_node->right_node)
         root_node->right_node->parent_node = root_node;
      root_node->right_depth = pivot->left_depth;
      root_node->parent_node = pivot;
      pivot->left_node = root_node;
      pivot->left_depth = tree_depth(root_node);
      pivot->parent_node = parent_node;
      root_node = pivot;
   }
#if defined(DEBUG) && defined(CHECKING)
   if (!check_tree(root_node)) {
      SLPDLog("Index tree check fails after rebalancing tree %p\n", root_node);
   }
#endif
   return root_node;
}
コード例 #15
0
ファイル: crossovr.c プロジェクト: Quamber/lil-gp-eclipse
void operator_crossover ( population *oldpop, population *newpop,
                         void *data )
{
     crossover_data * cd;
     int p1, p2;
     int ps1, ps2;
     int l1, l2;
     lnode *st[3];
     int sts1, sts2;
     int ns1, ns2;
     int badtree1, badtree2;
     double total;
     int forceany1, forceany2;
     int repcount;
     int f, t1, t2, j;
     double r, r2;
     int totalnodes1, totalnodes2;
     int i;

     /* get the crossover-specific data structure. */
     cd = (crossover_data *)data;
     total = cd->internal + cd->external;

     /* choose a function set. */
     r = random_double() * cd->treetotal;
     for ( f = 0; r >= cd->func[f]; ++f );

     /* fill in the "treecumul" array, zeroing all trees which
	don't use the selected function set. */
     r = 0.0;
     t1 = 0;
     for ( j = 0; j < tree_count; ++j )
     {
          if ( tree_map[j].fset == f )
               r = (cd->treecumul[j] = r + cd->tree[j]);
          else
               cd->treecumul[j] = r;
     }

     /* select the first and second trees. */
     r2 = random_double() * r;
     for ( t1 = 0; r2 >= cd->treecumul[t1]; ++t1 );
     r2 = random_double() * r;
     for ( t2 = 0; r2 >= cd->treecumul[t2]; ++t2 );

#ifdef DEBUG_CROSSOVER
     printf ( "selected function set %d --> t1: %d; t2: %d\n", f, t1, t2 );
#endif
     
     /* choose two parents */
     p1 = cd->sc->select_method ( cd->sc );
     ps1 = oldpop->ind[p1].tr[t1].nodes;
     /* if the tree only has one node, we obviously can't do
	fucntionpoint crossover.  use anypoint instead. */
     forceany1 = (ps1==1||total==0.0);
     
     p2 = cd->sc2->select_method ( cd->sc2 );
     ps2 = oldpop->ind[p2].tr[t2].nodes;
     forceany2 = (ps2==1||total==0.0);

#ifdef DEBUG_CROSSOVER
     fprintf ( stderr, "parent 1 is:\n" );
     print_individual ( oldpop->ind+p1, stderr );
     fprintf ( stderr, "parent 2 is:\n" );
     print_individual ( oldpop->ind+p2, stderr );
#endif

     while(1)
     {
          
          /* choose two crossover points */

          if ( forceany1 )
          {
	       /* choose any point. */
               l1 = random_int ( ps1 );
               st[1] = get_subtree ( oldpop->ind[p1].tr[t1].data, l1 );
          }
          else if ( total*random_double() < cd->internal )
          {
	       /* choose an internal point. */
               l1 = random_int ( tree_nodes_internal (oldpop->ind[p1].tr[t1].data) );
               st[1] = get_subtree_internal ( oldpop->ind[p1].tr[t1].data, l1 );
          }
          else
          {
	       /* choose an external point. */
               l1 = random_int ( tree_nodes_external (oldpop->ind[p1].tr[t1].data) );
               st[1] = get_subtree_external ( oldpop->ind[p1].tr[t1].data, l1 );
          }
                                
          if ( forceany2 )
          {
	       /* choose any point on second parent. */
               l2 = random_int ( ps2 );
               st[2] = get_subtree ( oldpop->ind[p2].tr[t2].data, l2 );
          }
          else if ( total*random_double() < cd->internal )
          {
	       /* choose internal point. */
               l2 = random_int ( tree_nodes_internal (oldpop->ind[p2].tr[t2].data) );
               st[2] = get_subtree_internal ( oldpop->ind[p2].tr[t2].data, l2 );
          }
          else
          {
	       /* choose external point. */
               l2 = random_int ( tree_nodes_external (oldpop->ind[p2].tr[t2].data) );
               st[2] = get_subtree_external ( oldpop->ind[p2].tr[t2].data, l2 );
          }

#ifdef DEBUG_CROSSOVER
          printf ( "subtree 1 is: " );
          print_tree ( st[1], stdout );
          printf ( "subtree 2 is: " );
          print_tree ( st[2], stdout );
#endif

	  /* count the nodes in the selected subtrees. */
          sts1 = tree_nodes ( st[1] );
          sts2 = tree_nodes ( st[2] );

	  /* calculate the sizes of the offspring. */
          ns1 = ps1 - sts1 + sts2;
          ns2 = ps2 - sts2 + sts1;

          totalnodes1 = ns1;
          totalnodes2 = ns2;

#ifdef DEBUG_CROSSOVER
          printf ( "newtree 1 has size %d; limit is %d\n",
                  ns1, tree_map[t1].nodelimit );
#endif

	  /** validate the first offspring against the tree node and depth
	    limits; set "badtree1" if any are violated. **/
	  
          badtree1 = 0;
          if ( tree_map[t1].nodelimit > -1 && ns1 > tree_map[t1].nodelimit )
               badtree1 = 1;
          else if ( tree_map[t1].depthlimit > -1 )
          {
               ns1 = tree_depth_to_subtree ( oldpop->ind[p1].tr[t1].data, st[1] ) +
                     tree_depth ( st[2] );
#ifdef DEBUG_CROSSOVER
               printf ( "newtree 1 has depth %d; limit is %d\n",
                       ns1, tree_map[t1].depthlimit );
#endif
               if ( ns1 > tree_map[t1].depthlimit )
                    badtree1 = 1;
          }

	  /* if we're supposed to keep trying, skip up and choose new crossover
	     points. */
          if ( cd->keep_trying && badtree1 )
               continue;

	  /** validate the second offspring against the tree node and depth
	    limits; set "badtree2" if any are violated. **/
	  
          badtree2 = 0;
          if ( tree_map[t2].nodelimit > -1 && ns2 > tree_map[t2].nodelimit )
               badtree2 = 1;
          else if ( tree_map[t2].depthlimit > -1 )
          {
               ns2 = tree_depth_to_subtree ( oldpop->ind[p2].tr[t2].data, st[2] ) +
                     tree_depth ( st[1] );
               if ( ns2 > tree_map[t2].depthlimit )
                    badtree2 = 1;
          }

	  /* if we're supposed to keep trying, skip up and choose new crossover
	     points. */
	  
          if ( cd->keep_trying && badtree2 )
               continue;

	  /* check both offspring against the individual node limits, set
	     badtree1 and/or badtree2 if either is too big. */
	  
          if ( ind_nodelimit > -1 )
          {
               for ( i = 0; i < tree_count; ++i )
               {
                    if ( i != t1 )
                         totalnodes1 += oldpop->ind[p1].tr[i].nodes;
                    if ( i != t2 )
                         totalnodes2 += oldpop->ind[p2].tr[i].nodes;
               }
               badtree1 |= (totalnodes1 > ind_nodelimit);
               badtree2 |= (totalnodes2 > ind_nodelimit);
#ifdef DEBUG_CROSSOVER
               printf ( "newind 1 has %d nodes; limit is %d\n",
                       totalnodes1, ind_nodelimit );
#endif
          }

	  /* choose new crossover points if either tree is too big. */
          if ( cd->keep_trying && (badtree1 || badtree2) )
               continue;
          
          /* copy the first parent to the first offspring position */
          duplicate_individual ( newpop->ind+newpop->next,
                                oldpop->ind+p1 );
          if ( !badtree1 )
          {
	       /* if the first offspring is allowable... */
	       
#ifdef DEBUG_CROSSOVER
               fprintf ( stderr, "offspring 1 is allowable.\n" );
#endif
	       
	       /* make a copy of the crossover tree, replacing the
		  selected subtree with the crossed-over subtree. */
               copy_tree_replace_many ( 0, oldpop->ind[p1].tr[t1].data,
                                       st+1, st+2, 1, &repcount );
               if ( repcount != 1 )
               {
		    /* this can't happen, but check anyway. */
                    error ( E_FATAL_ERROR,
                           "botched crossover:  this can't happen" );
               }

               /* free the appropriate tree of the new individual */
               free_tree ( newpop->ind[newpop->next].tr+t1 );
               /* copy the crossovered tree to the freed space */
               gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t1 );

	       /* the new individual's fitness fields are of course invalid. */
               newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID;
               newpop->ind[newpop->next].flags = FLAG_NONE;
          }
          else
          {
	       /* offspring too big but keep_trying not set, just leave the copied
		  parent 1 in the offspring position. */
#ifdef DEBUG_CROSSOVER
               fprintf ( stderr, "offspring 1 is too big; copying parent 1.\n" );
#endif
          }

	  /* we've just filled in one member of the new population. */
          ++newpop->next;
          
#ifdef DEBUG_CROSSOVER
          fprintf ( stderr, "offspring 1:" );
          if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID )
               fprintf ( stderr, "  (valid)\n" );
          else
               fprintf ( stderr, "  (invalid)\n" );
          print_individual ( newpop->ind+(newpop->next-1), stderr );
#endif          

	  /* if the new population needs another member (it's not full) */
          if ( newpop->next < newpop->size )
          {
	       /* copy the second parent to the second offspring position. */
               duplicate_individual ( newpop->ind+newpop->next,
                                     oldpop->ind+p2 );
               if ( !badtree2 )
               {
		    /* if the second offspring is allowable... */
#ifdef DEBUG_CROSSOVER
                    fprintf ( stderr, "offspring 2 is allowable.\n" );
#endif
		    /* then make a copy of the tree, replacing the crossover
		       subtree. */
                    copy_tree_replace_many ( 0, oldpop->ind[p2].tr[t2].data,
                                            st+2, st+1, 1, &repcount );
                    if ( repcount != 1 )
                    {
                         error ( E_FATAL_ERROR,
                                "bad crossover:  this can't happen" );
                    }

		    /* free the old tree in the new individual, and replace
		       it with the crossover tree. */
                    free_tree ( newpop->ind[newpop->next].tr+t2 );
                    gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t2 );
                    
                    newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID;
                    newpop->ind[newpop->next].flags = FLAG_NONE;
               }
               else
               {
		    /* offspring too big but keep_trying not set; just leave
		       the copy of parent 2 where it is. */
#ifdef DEBUG_CROSSOVER
                    fprintf ( stderr, "offspring 2 is big; copying parent 2.\n" );
#endif
               }
               
               ++newpop->next;
               
#ifdef DEBUG_CROSSOVER
               fprintf ( stderr, "offspring 2:" );
               if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID )
                    fprintf ( stderr, "  (valid)\n" );
               else
                    fprintf ( stderr, "  (invalid)\n" );
               print_individual ( newpop->ind+(newpop->next-1), stderr );
#endif          
          
          }
#ifdef DEBUG_CROSSOVER
          else
          {
	       /* the first offspring filled the population, discard the
		  second. */
               fprintf ( stderr, "offspring 2 not needed.\n\n" );
          }
#endif

          break;
     }

#ifdef DEBUG_CROSSOVER
     printf ( "CROSSOVER COMPLETE.\n\n\n" );
#endif
     
}
コード例 #16
0
ファイル: read-dict.c プロジェクト: dyne/AutOrg
static int tree_balance(Dict_node *n)
{
	int l = tree_depth(n->left);
	int r = tree_depth(n->right);
	return r-l;
}
コード例 #17
0
ファイル: tree-main.c プロジェクト: Mr-Binary/C_Playground
/**
 * Gathers input from the command line and responds to the given
 * arguments.
 * Refer to help menu (-h) for more information.
 *
 * @param argc count the number of arguments on the command line. 
 * @param argv[] array of arguments.
 *
 * @return exit success or exit failure.
 */
int main (int argc, char *argv[]){

    char word[256];
    const char *optstring = "c:df:orh";
    char option;
    tree h;

    tree_t tree_type = BST;
    FILE *outfile;
    char* out = NULL;

    FILE *filename;
    int unknown = 0;
    clock_t fill_start,fill_end, search_start, search_end;

    int cflag = 0;
    int dflag = 0;
    int oflag = 0;

    while ((option = getopt(argc,argv,optstring)) != EOF){
        switch(option){
            case'f':
                out = optarg;
                break;

            case 'o':
                oflag = 1;
                break;

            case 'r':
                tree_type = RBT;
                break;

            case 'd':
                dflag = 1;
                break;

            case 'c':
                if (NULL == (filename = fopen(optarg, "r"))) {
                    fprintf(stderr, "%s: can't find file %s\n", argv[0], argv[1]);
                    return EXIT_FAILURE;
                }
                cflag = 1;
                break;

            case 'h':
                print_usage(argv[0]);
                exit(EXIT_FAILURE);
                break;

            default:
                print_usage(argv[0]);
                exit(EXIT_FAILURE);
        }
    }
    if (out == NULL){
        out = "tree-view.dot";
    }

    h = tree_new(tree_type);

    fill_start = clock();
    while (getword(word, sizeof word, stdin) != EOF){
        h = tree_insert(h,word);
    }
    fill_end = clock();

    if (oflag == 1){
        outfile = fopen(out, "w");
        tree_output_dot(h, outfile);
        fprintf(stderr,"Creating dot file '%s'\n",out );
        fclose(outfile);
    }

    if (cflag == 1){
        dflag = 0;
        oflag = 0;
        search_start = clock();
        while (getword(word, sizeof word, filename) != EOF){
            if (tree_search(h, word) == 0){
                printf("%s\n", word);
                unknown++;
            }
        }

        search_end = clock();
        fclose(filename);

        fprintf(stderr, "Fill time     : %7f\nSearch time   : %7f\nUnknown words = %d\n", \
                (fill_end-fill_start)/(double)CLOCKS_PER_SEC,           \
                (search_end-search_start)/(double)CLOCKS_PER_SEC, unknown);
    }

    if (dflag == 1){
        printf("%d\n",tree_depth(h));
    }else if (dflag == 0 && cflag == 0 && oflag == 0){
        tree_preorder(h, print_info);
    }

    tree_free(h);
    return EXIT_SUCCESS;
}
コード例 #18
0
ファイル: list_check.c プロジェクト: biochem-fan/CrystFEL
static int test_lists(int num_items)
{
	struct refltemp *check;
	RefList *list;
	int i;
	signed int h, k, l;
	Reflection *refl;
	RefListIterator *iter;

	check = malloc(num_items * sizeof(struct refltemp));
	list = reflist_new();

	h = RANDOM_INDEX;
	k = RANDOM_INDEX;
	l = RANDOM_INDEX;

	for ( i=0; i<num_items; i++ ) {

		int j;
		int num;

		if ( random() > RAND_MAX/2 ) {
			h = RANDOM_INDEX;
			k = RANDOM_INDEX;
			l = RANDOM_INDEX;
		} /* else use the same as last time */

		/* Count the number of times this reflection appeared before */
		num = 1;
		for ( j=0; j<i; j++ ) {
			if ( (check[j].h == h)
			  && (check[j].k == k)
			  && (check[j].l == l) ) {
				num++;
			}
		}

		/* Update all copies with this number */
		for ( j=0; j<i; j++ ) {
			if ( (check[j].h == h)
			  && (check[j].k == k)
			  && (check[j].l == l) ) {
				check[j].num = num;
			}
		}

		add_refl(list, h, k, l);
		check[i].h = h;
		check[i].k = k;
		check[i].l = l;
		check[i].num = num;
		check[i].found = 0;

	}

	printf("Created %i items, num_reflections is %i, tree depth is %i\n",
	       num_items, num_reflections(list), tree_depth(list));

	/* Iterate over the list and check we find everything */
	int count = 0;
	for ( refl = first_refl(list, &iter);
	      refl != NULL;
	      refl = next_refl(refl, iter) ) {

		signed int h, k, l;

		get_indices(refl, &h, &k, &l);

		for ( i=0; i<num_items; i++ ) {
			if ( (check[i].h == h)
			  && (check[i].k == k)
			  && (check[i].l == l)
			  && (check[i].found == 0) ) {
				check[i].found = 1;
				break;
			}
		}

		count++;

	}
	if ( count != num_reflections(list) ) {
		fprintf(stderr, "num_reflections gave %i, iteration gave %i\n",
		        num_reflections(list), count);
		return 1;
	}

	for ( i=0; i<num_items; i++ ) {
		if ( check[i].found == 0 ) {

			Reflection *test;

			fprintf(stderr, "Iteration didn't find %3i %3i %3i %i\n",
			        check[i].h, check[i].k, check[i].l, i);
			test = find_refl(list, check[i].h, check[i].k,
			                 check[i].l);
			if ( test == NULL ) {
				fprintf(stderr, "Not in list\n");
			} else {
				fprintf(stderr, "But found in list.\n");
			}
			return 1;

		}
	}

	/* Check that all the reflections can be found */
	for ( i=0; i<num_items; i++ ) {

		signed int h, k, l;
		Reflection *refl;

		h = check[i].h;
		k = check[i].k;
		l = check[i].l;

		refl = find_refl(list, h, k, l);
		if ( refl == NULL ) {
			fprintf(stderr, "Couldn't find %3i %3i %3i\n", h, k, l);
			return 1;
		}

	}

	reflist_free(list);
	free(check);

	return 0;
}