//查找并更正后缀surffix  
void SuffixTrie::fix_surffix(TrieNode *parent, std::string surffix) {  
  TrieNode *pNode = parent->lchild;
  if (NULL == pNode) {
    return;
  }  
  
  //找出可能包含此后缀的分支
  while(pNode) { 
    if(surffix[0] == pNode->text[0]) {
      break;
    }
    pNode = pNode->sibling;
  }
  
  //情况二:没有分支,直接添加,后缀surffix处理结束
  if (NULL == pNode) {
    add_to_tree(parent, surffix);
    return;
  }

  //找出了所属的分支
  int i = 1;
  int surffix_len = surffix.size();
  int branch_len = pNode->text.size();
  while(1) {
    //情况一:发现后缀已经包含在其中了,增加一个节点
    if (surffix_len < i+1) {
      if (i < branch_len) {
        TrieNode *pOld = pNode->lchild;
        add_to_tree(pNode, pNode->text.substr(i));
        pNode->lchild->sibling = NULL;
        pNode->lchild->lchild = pOld;
        pNode->text= pNode->text.substr(0,i);
      }
      return;
    }
    
    //一个分直节点已经检查完,用后缀剩下的子串递归检查子节点中下一个可能分支
    if (branch_len < i+1) {
      fix_surffix(pNode, surffix.substr(i));
      return;
    }
    
    if (surffix[i] != pNode->text[i]) {
      // 保存当前节点的孩子
      TrieNode *pOld = pNode->lchild;
      //当前节点字符串中断点及以后的子串作为其子节点
      add_to_tree(pNode, pNode->text.substr(i));
      //当前节点的原有子节点作为刚添加的节点的子节点
      pNode->lchild->sibling = NULL;
      pNode->lchild->lchild = pOld;
      //当前后缀剩下的子串作为其子节点
      add_to_tree(pNode, surffix.substr(i));
      //当前节点去掉其中断点及以后的子串
      pNode->text= pNode->text.substr(0,i);
      return;
    }
    i++;
  }
}
Пример #2
0
void augment() {
	if (max_match == n) return; 
	int x, y, root, q[N], wr = 0, rd = 0; 
	memset(S, false, sizeof(S)), memset(T, false, sizeof(T)); 
	memset(prev2, -1, sizeof(prev2)); 
	forn (x, n) if (xy[x] == -1){
		q[wr++] = root = x, prev2[x] = -2;
		S[x] = true; break; }
	forn (y, n) slack[y] = lx[root] + ly[y] - cost[root][y], slackx[y] = root;
	while (true){
		while (rd < wr){
			x = q[rd++];
			for (y = 0; y < n; y++) if (cost[x][y] == lx[x] + ly[y] && !T[y]){
				if (yx[y] == -1) break; T[y] = true; 
				q[wr++] = yx[y], add_to_tree(yx[y], x); }
			if (y < n) break; }
		if (y < n) break; 
		update_labels(), wr = rd = 0; 
		for (y = 0; y < n; y++) if (!T[y] && slack[y] == 0){
			if (yx[y] == -1){x = slackx[y]; break;}
			else{
				T[y] = true; 
				if (!S[yx[y]]) q[wr++] = yx[y], add_to_tree(yx[y], slackx[y]);
			}}
		if (y < n) break; }
	if (y < n){
		max_match++; 
		for (int cx = x, cy = y, ty; cx != -2; cx = prev2[cx], cy = ty)
			ty = xy[cx], yx[cy] = cx, xy[cx] = cy;
		augment(); }
}
Пример #3
0
void add_to_tree(bst *node, bst *ptr)
{
  if(node == NULL)
    return;

  if(node->left != NULL && ptr->data < node->data)
  {
    add_to_tree(node->left, ptr);
  }

  if(node->right != NULL && ptr->data >= node->data)
  {
    add_to_tree(node->right, ptr);
  }

  if(node->left == NULL && ptr->data < node->data)
  {
      node->left = ptr;
  }

  if(node->right == NULL && ptr->data >= node->data)
  {
    node->right = ptr;
  }
}
Пример #4
0
void add_to_tree(tree *root_node, int data) {
  if(data < root_node->data) {
    if(NULL == root_node->left) {
      tree *new_node;
      new_node = malloc(sizeof(tree)); // Give me some memory, bitch!

      root_node->left = new_node;
      new_node->parent = root_node;
      new_node->data = data;
    } else {
      add_to_tree(root_node->left, data); // Monkey down the tree
    }
  } else {
    if(NULL == root_node->right) {
      tree *new_node;
      new_node = malloc(sizeof(tree)); // Give me some memory, bitch!

      root_node->right = new_node;
      new_node->parent = root_node;
      new_node->data = data;
    } else {
      add_to_tree(root_node->right, data); // Monkey down the tree
    }
  }

}
Пример #5
0
int pdt_add_to_tree(pdt_tree_t **dpt, str *sdomain, str *code, str *domain)
{
	pdt_tree_t *ndl, *it, *prev;

	if( sdomain==NULL || sdomain->s==NULL
			|| code==NULL || code->s==NULL
			|| domain==NULL || domain->s==NULL)
	{
		LM_ERR("bad parameters\n");
		return -1;
	}
	
	ndl = NULL;
	
	it = *dpt;
	prev = NULL;
	/* search the it position before which to insert new domain */
	while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0)
	{	
		prev = it;
		it = it->next;
	}
//	printf("sdomain:%.*s\n", sdomain->len, sdomain->s);

	/* add new sdomain*/
	if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0)
	{
		ndl = pdt_init_tree(sdomain);
		if(ndl==NULL)
		{
			LM_ERR("no more shm memory\n");
			return -1; 
		}

		if(add_to_tree(ndl, code, domain)<0)
		{
			LM_ERR("internal error!\n");
			return -1;
		}
		ndl->next = it;
		
		/* new domain must be added as first element */
		if(prev==NULL)
			*dpt = ndl;
		else
			prev->next=ndl;

	}
	else 
		/* add (prefix, code) to already present sdomain */
		if(add_to_tree(it, code, domain)<0)
		{
			LM_ERR("internal error!\n");
			return -1;
		}

	return 0;
}
Пример #6
0
/**
 * Based on understanding gained from online resources as detailed in the 
 * bibliography of my writeup
 * 
 * recurses through the binary tree until it finds the correct location to 
 * insert the new node. As specified inserts so that smaller values are
 * stored in left sub tree and equal or larger values in the right sub tree
 * 
 * @param root a pointer to the Competitor * root in main, allows the value of 
 * root to be modified where required
 * @param node_to_add
 * @return the appropriate flags for any errors that occur
 */
int add_to_tree(competitor ** root, competitor * node_to_add){
    competitor * current = (*root);
    int error_descriptor = 0;
    if(current == NULL){
        error_descriptor = set_current(node_to_add, &current);
        if(error_descriptor != 0) return error_descriptor;
        (*root) = current;
         return 0;
    }else{
        if(TOTAL_NODE_TO_ADD_LENGTH < TOTAL_CURRENT_LENGTH){
            add_to_tree(&(current->left), node_to_add);
        }else{
            add_to_tree(&(current->right), node_to_add);
        }
    }
}
Пример #7
0
void SuffixTree::build_suffix_tree() {
    
    for (int i = 0; i < input_string.size(); ++i)
    {
        add_to_tree(i);
    }
}
Пример #8
0
access_t *get_access(size_t offset, tree_t **t_access, malloc_t *block)
{
  access_t      *access;

  if ((access = search_same_addr_on_tree(*t_access, (void *)offset)))
    return access;

  // if no access with this offset is found we create a new one
  if (!(access = alloc_access(block)))
    {
      dr_printf("dr_malloc fail\n");
      return NULL;
    }

  ds_memset(access, 0, sizeof(*access));
  access->offset = offset;

  access->node.data = access;
  access->node.high_addr = (void *)offset;
  access->node.min_addr = (void *)offset;

  add_to_tree(t_access, (tree_t*)access);

  return access;
}
Пример #9
0
void rrt_t::step()
{
	random_sample();
	nearest_vertex();
	if(propagate())
	{
		add_to_tree();
	}
}
Пример #10
0
int main() {
	bintree mytree = {0};
	srand(time(NULL));
    for (unsigned long long i = 0; i < TREE_SIZE; i++) {
        add_to_tree(&mytree, rand() % 100);
    }
    print_tree(&mytree);
    del_tree(&mytree);
	return 0;
}
void SuffixTrie::initialise() {  
  int a[128] = {0};
  pRoot = new TrieNode();
  pRoot->text = "root";
  for (int i = 0; i < constant_str.size(); ++i) {
    if (0 == a[constant_str[i]]) {
      add_to_tree(pRoot, constant_str.substr(i));
      a[constant_str[i]] = 1;
    }
  }
}
Пример #12
0
int main(){
    Tree * tree;        /*Tree ADT - holds integer values in AVL tree being tested*/
    int * entry;        /*Temporary variable when adding to, removing from and searching tree*/
    int * result;       /*Result of search*/
    int i;              /*Controls loops*/

    tree = init_tree(&compare, &compare, &destroy, &print, &collision);

    printf("Adding the numbers to the tree in an out of sequence order :\n");
    for (i = 0; i < 12; i++){
        entry = malloc(sizeof(int));
        *entry = (3 * i) % 10;
        printf("%d, ", *entry);
        tree = add_to_tree(tree, entry);
    }
    putchar('\n');
    printf("Repeated some entries to test collision resolution.\n");

    printf("Tree after insertions.\n");

    print_tree(tree);
    for (i = 0; i < 10; i = i + 3){
        entry = malloc(sizeof(int));
        *entry = i;
        remove_from_tree(tree, entry);
        free(entry);

        printf("%d is removed...\n", i);
        print_tree(tree);

        putchar('\n');
    }

    
    printf("Testing search_tree_closest...\n");
    printf("Searching for 3 (no longer in tree), should return 4.\n");
    entry = malloc(sizeof(int));
    *entry = 3;
    result = search_tree_closest(tree, entry);
    printf("Returned : %d\n", *result);
    free(entry);

    printf("Note : Because the search_tree_closest function works, \n");
    printf("it follows that the search_tree function must also work.\n");
    printf("In the context of only integers, this function doesn't \n");
    printf("really make sense though.\n");

    printf("Destroying tree...\n");
    destroy_tree(tree);

    printf("\n\nAll tests passed.\n");
    return 0;
}
Пример #13
0
int main()
 {
	struct tnode *root;
	char node_urls[10][MAX_URL_LENGTH];
	int url_frequency[10];
 	root = NULL;
	root = add_to_tree(root, "google.com");
	root = add_to_tree(root, "google.com");
	assert( root->count == 2);
	root = add_to_tree(root, "amazon.com");
 	assert(treeprint(0,root,node_urls, url_frequency) == 2);
	
       	populate_tree("small_url", &root);
	test_print(root, 7, Expected_URLs_small, Expected_Url_Freq_small);

       	populate_tree("long_url", &root);
	assert( lookup(root, "vonage.com") == 2323);
	test_print(root, 10, Expected_URLs, Expected_Url_Freq);
	
	return 0;
 }
Пример #14
0
int main (int argc, char const *argv[]) {
  tree root;
  int node_1_data = 1;
  int node_2_data = 2;
  
  root.data = 0;
  
  // Adding stuff
  add_to_tree(&root, node_1_data);
  add_to_tree(&root, node_2_data);
  
  // Search
  int find_data = 2;
  tree *result;
  result = find(&root, find_data);    
  
  // Finding min
  tree *min;
  min = find_minimum(&root);
  
  return 0;
}
Пример #15
0
void add_node(int data)
{
  bst *ptr = (bst *) malloc(sizeof(bst));
  ptr->data = data;
  ptr->left = NULL;
  ptr->right = NULL;

  if(root == NULL)
  {
     root = ptr;
  }
  else
  {
     add_to_tree(root, ptr);
  }
}
Пример #16
0
void incr_orig(access_t *access, size_t size, void *pc, void *drcontext,
	       malloc_t *block, ctx_t *ctx)
{
  orig_t	*orig_tree = search_same_addr_on_tree(access->origs, pc);
  orig_t	*orig_list = orig_tree;

  while (orig_list && orig_list->size != size)
    orig_list = orig_list->next;

  if (orig_list)
    {
      orig_list->nb_hit++;
      return;
    }

  if (!orig_tree)
    {
      if (!(orig_tree = new_orig(size, pc, drcontext, block, ctx)))
	{
	  dr_printf("dr_malloc fail\n");
	  return;
	}
      orig_tree->node.high_addr = pc;
      orig_tree->node.min_addr = pc;
      orig_tree->node.data = orig_tree;
      add_to_tree(&(access->origs), (tree_t*)orig_tree);

      return;
    }

  // if a an orig have the same addr but not the same size we create an other
  // entry and put it in the linked list for this node;
  if (!orig_list)
    {
      if (!(orig_list = new_orig(size, pc, drcontext, block, ctx)))
	{
	  dr_printf("dr_malloc fail\n");
	  return;
	}

      while (orig_tree->next)
	orig_tree = orig_tree->next;
      orig_tree->next = orig_list;
    }
}
Пример #17
0
static void
add_to_tree(struct ip_bucket_entry *ent, int level, struct vr_route_req *rt)
{
    unsigned int i;
    struct ip_bucket      *bkt;
    struct mtrie_bkt_info *ip_bkt_info;

    if (ent->entry_prefix_len > rt->rtr_req.rtr_prefix_len)
        return;

    ent->entry_prefix_len = rt->rtr_req.rtr_prefix_len;

    if (!ENTRY_IS_BUCKET(ent)) {
        /* a less specific entry, which needs to be replaced */
        if (ENTRY_IS_NEXTHOP(ent)) {
            set_entry_to_nh(ent, rt->rtr_nh);
        } else {
            set_entry_to_vdata(ent, (void *)rt->rtr_nh);
        }
        ent->entry_label_flags = rt->rtr_req.rtr_label_flags;
        ent->entry_label = rt->rtr_req.rtr_label;
        ent->entry_bridge_index = rt->rtr_req.rtr_index;

        return;
    }

    if (level >= (ip_bkt_get_max_level(rt->rtr_req.rtr_family) - 1))
        return;

    ip_bkt_info = ip_bkt_info_get(rt->rtr_req.rtr_family);

    /* Assured that this is valid bucket now */
    bkt = entry_to_bucket(ent);
    level++;

    for (i = 0; i < ip_bkt_info[level].bi_size; i++) {
        ent = index_to_entry(bkt, i);
        add_to_tree(ent, level, rt);
    }

    return;
}
Пример #18
0
/* Main file-processing routine
 * returns : IO_ERROR if IO error occured
 *           IO_EOF if EOF occured
 *           IO_SUCCESS at success
 */
int do_process_record(int fd, uint64_t * cur_position, compact_header_t ** tree)
{
    header_t hdr;
    int r;
    /*Read next header structure*/
    if ((r = read_header_from_file(fd, &hdr)) < 0) {
        return r;
    }
    /*Allocate and initialize index structure related to @hdr*/
    compact_header_t * node = malloc(sizeof(compact_header_t));
    node->left = node->right = NULL;

    /*copy key*/
    memcpy(node->key, hdr.key, 64);

    /*store offset of @hdr in input file */
    node->record_offset = *cur_position;

    /* Store payload size of @hdr. This is not stronly required,
     * but it will enable us to perform 1 read operation instead of 2
     * while writing output file */
    node->payload_size = hdr.size;

    /* Add current node to tree */
    if (*tree != NULL) {
        add_to_tree(node, *tree);
    } else {
        *tree = node;
    }

    /* fast-forward position in input file for hdr.size bytes (skip payload) */
    if (lseek64(fd, hdr.size, SEEK_CUR) < 0) {
        perror("lseek64()");
        return IO_ERROR;
    }
    *cur_position += hdr.size + sizeof(hdr);
    return IO_SUCCESS;
}
Пример #19
0
void augment(const double cost[N][N]) //main function of the algorithm
{
    if (max_match == n) return;        //check wether matching is already perfect
    int x, y, root = 0;                //just counters and root vertex
    int q[N], wr = 0, rd = 0;          //q - queue for bfs, wr,rd - write and read
                                       //pos in queue
    memset(S, false, sizeof(S));       //init set S
    memset(T, false, sizeof(T));       //init set T
    memset(prev, -1, sizeof(prev));    //init set prev - for the alternating tree
    for (x = 0; x < n; x++)            //finding root of the tree
        if (xy[x] == -1)
        {
            q[wr++] = root = x;
            prev[x] = -2;
            S[x] = true;
            break;
        }

    for (y = 0; y < n; y++)            //initializing slack array
    {
        slack[y] = lx[root] + ly[y] - cost[root][y];
        slackx[y] = root;
    }
   while (true)                                                        //main cycle
    {
        while (rd < wr)                                                 //building tree with bfs cycle
        {
            x = q[rd++];                                                //current vertex from X part
            for (y = 0; y < n; y++)                                     //iterate through all edges in equality graph
                if (cost[x][y] == lx[x] + ly[y] &&  !T[y])
                {
                    if (yx[y] == -1) break;                             //an exposed vertex in Y found, so
                                                                        //augmenting path exists!
                    T[y] = true;                                        //else just add y to T,
                    q[wr++] = yx[y];                                    //add vertex yx[y], which is matched
                                                                        //with y, to the queue
                    add_to_tree(yx[y], x, cost);                              //add edges (x,y) and (y,yx[y]) to the tree
                }
            if (y < n) break;                                           //augmenting path found!
        }
        if (y < n) break;                                               //augmenting path found!

        update_labels();                                                //augmenting path not found, so improve labeling
        wr = rd = 0;
        for (y = 0; y < n; y++)
        //in this cycle we add edges that were added to the equality graph as a
        //result of improving the labeling, we add edge (slackx[y], y) to the tree if
        //and only if !T[y] &&  slack[y] == 0, also with this edge we add another one
        //(y, yx[y]) or augment the matching, if y was exposed
            if (!T[y] &&  slack[y] == 0)
            {
                if (yx[y] == -1)                                        //exposed vertex in Y found - augmenting path exists!
                {
                    x = slackx[y];
                    break;
                }
                else
                {
                    T[y] = true;                                        //else just add y to T,
                    if (!S[yx[y]])
                    {
                        q[wr++] = yx[y];                                //add vertex yx[y], which is matched with
                                                                        //y, to the queue
                        add_to_tree(yx[y], slackx[y],cost);                  //and add edges (x,y) and (y,
                                                                        //yx[y]) to the tree
                    }
                }
            }
        if (y < n) break;                                               //augmenting path found!
    }

    if (y < n)                                                          //we found augmenting path!
    {
        max_match++;                                                    //increment matching
        //in this cycle we inverse edges along augmenting path
        for (int cx = x, cy = y, ty; cx != -2; cx = prev[cx], cy = ty)
        {
            ty = xy[cx];
            yx[cy] = cx;
            xy[cx] = cy;
        }
        augment(cost);                                                      //recall function, go to step 1 of the algorithm
    }
}//end of augment() function
Пример #20
0
/*
 * When adding a route:
 * - descend the tree to the bucket at which the route is significant.
 * (i.e. the bucket corresponding to a prefix >= to the route prefix).
 * - if the bucket needs to be created, it is first initialized and only
 * linked to the tree when the function exits.
 * - if the bucket exists, populate any descendent bucket entries that
 * themselfs do not have more specific routes.
 * - when a bucket is created, initialize any entries with the parent that
 * covers them.
 *
 * Flag data_is_nh indicates if the data in the mtrie nodes is nexthop or
 * void *vdata
 */
static int
__mtrie_add(struct ip_mtrie *mtrie, struct vr_route_req *rt, int data_is_nh)
{
    int ret, index = 0, level, err_level = 0, fin;
    unsigned char i;
    struct ip_bucket *bkt;
    struct ip_bucket_entry *ent, *err_ent = NULL;
    void *data, *err_data = NULL;
    struct mtrie_bkt_info *ip_bkt_info = ip_bkt_info_get(rt->rtr_req.rtr_family);

    ent = &mtrie->root;

    data = (void *)ent->entry_long_i;
    for (level = 0; level < ip_bkt_get_max_level(rt->rtr_req.rtr_family); level++) {
        if (!ENTRY_IS_BUCKET(ent)) {
            bkt = mtrie_alloc_bucket(ip_bkt_info, level, ent, data_is_nh);
            set_entry_to_bucket(ent, bkt);

            if (!err_ent) {
                err_ent = ent;
                err_data = data;
                err_level = level;
            }
        }

        bkt = entry_to_bucket(ent);
        if (!bkt) {

            ret = -ENOMEM;
            goto exit_ret;
        }

        index = rt_to_index(rt, level);
        ent = index_to_entry(bkt, index);

        if (rt->rtr_req.rtr_prefix_len > ip_bkt_info[level].bi_pfx_len) {
            if (!ENTRY_IS_BUCKET(ent)) {
                data = (void *)ent->entry_long_i;
            }

            continue;

        } else {
            /*
             * cover all the indices for which this route is the best
             * prefix match
             */

            fin = ip_bkt_info[level].bi_size;

            if ((rt->rtr_req.rtr_prefix_len >
                        (ip_bkt_info[level].bi_pfx_len - ip_bkt_info[level].bi_bits)) &&
                    (rt->rtr_req.rtr_prefix_len <= ip_bkt_info[level].bi_pfx_len)) {
                fin = 1 << (ip_bkt_info[level].bi_pfx_len - rt->rtr_req.rtr_prefix_len);
            }

            i = index;
            for (; ((i <= (ip_bkt_info[level].bi_size-1)) && fin);
                                                        i++, fin--) {
                ent = index_to_entry(bkt, i);
                add_to_tree(ent, level, rt);
             }

             break;
        }
    }

    return 0;

exit_ret:
    if (err_ent)
        mtrie_reset_entry(err_ent, err_level, err_data, data_is_nh);

    return ret;
}
Пример #21
0
      void solve_bipartite_matching()
      {
         for(size_t max_match=0; max_match<nel; ++max_match)
         {
            size_t x, y, root=MINUS_ONE;                           //just counters and root vertex
            std::vector<size_t> q(nel);
            size_t wr = 0, rd = 0;                                 //q - queue for bfs, wr,rd - write and read
            //pos in queue
            S.assign(nel, false);                             //init set S
            T.assign(nel, false);                             //init set T
            prev.assign(nel, MINUS_ONE);                      //init set prev - for the alternating tree
            for (x = 0; x < nel; x++)                         //finding root of the tree
               if (xy[x] == MINUS_ONE)
               {
                  q[wr++] = root = x;
                  prev[x] = MINUS_TWO;
                  S[x] = true;
                  break;
               }

            for (y = 0; y < nel; y++)                          //initializing slack array
            {
               //std::cerr << "root " << root << " y " << y << std::endl;
               slack[y] = lx[root] + ly[y] - get_cost(root,y);
               slackx[y] = root;
            }
            //second part of augment() function
            bool found= false;
            while (!found)                                          //main cycle
            {
               while (rd < wr && !found)                            //building tree with bfs cycle
               {
                  x = q[rd++];                                      //current vertex from X part
                  for (y = 0; y < nel && !found;)              //iterate through all edges in equality graph
                  {
                     if (get_cost(x,y) == lx[x] + ly[y] &&  !T[y])
                     {
                        if (yx[y] == MINUS_ONE)
                        {
                           found= true;               //an exposed vertex in Y found, so
                        }
                        //augmenting path exists!
                        else
                        {
                           T[y] = true;                                //else just add y to T,
                           q[wr++] = yx[y];                            //add vertex yx[y], which is matched
                           //with y, to the queue
                           add_to_tree(yx[y], x);                      //add edges (x,y) and (y,yx[y]) to the tree
                           ++y;
                        }
                     }
                     else
                        ++y;
                  }
               }
               if (!found)
               {

                  update_labels();                                     //augmenting path not found, so improve labeling
                  wr = rd = 0;
                  for (y = 0; y < nel && !found;)
                  {
                     //in this cycle we add edges that were added to the equality graph as a
                     //result of improving the labeling, we add edge (slackx[y], y) to the tree if
                     //and only if !T[y] &&  slack[y] == 0, also with this edge we add another one
                     //(y, yx[y]) or augment the matching, if y was exposed
                     if (!T[y] &&  slack[y] == 0)
                     {
                        if (yx[y] == MINUS_ONE)                               //exposed vertex in Y found - augmenting path exists!
                        {
                           x = slackx[y];
                           found = true;
                        }
                        else
                        {
                           T[y] = true;                                //else just add y to T,
                           if (!S[yx[y]])
                           {
                              q[wr++] = yx[y];                         //add vertex yx[y], which is matched with
                              //y, to the queue
                              add_to_tree(yx[y], slackx[y]);           //and add edges (x,y) and (y,
                              //yx[y]) to the tree
                           }
                           ++y;
                        }
                     }
                     else
                        ++y;
                  }
               }
            }

            assert(found);
            //in this cycle we inverse edges along augmenting path
            for (size_t cx = x, cy = y, ty; cx != MINUS_TWO; cx = prev[cx], cy = ty)
            {
               ty = xy[cx];
               yx[cy] = cx;
               xy[cx] = cy;
            }
         }

      }
Пример #22
0
void augment()                         //main function of the algorithm
{
    if (verbose)
    {
        printf("\n\nAugment(.) call\n");
        printf("Current matching is as follows:\n");
        print_matching();
    }

    if (max_match == n) return;        //check wether matching is already perfect
    int x, y, root;                    //just counters and root vertex
    int q[N], wr = 0, rd = 0;          //q - queue for bfs, wr,rd - write and read

    root = 0;                          // stop warning, it will be assigned below before xy has
                                       // a bunch of -1's in it to start.

                                       //pos in queue
    memset(S, false, sizeof(S));       //init set S
    memset(T, false, sizeof(T));       //init set T
    memset(prev, -1, sizeof(prev));    //init set prev - for the alternating tree
    for (x = 0; x < n; x++)            //finding root of the tree
        if (xy[x] == -1)
        {
            q[wr++] = root = x;
            prev[x] = -2;
            S[x] = true;
            break;
        }


    for (y = 0; y < n; y++)            //initializing slack array
    {
        slack[y] = lx[root] + ly[y] - cost[root][y];
        slackx[y] = root;
    } //second part of augment() function

    
    while (true)                                                        //main cycle
    {
        while (rd < wr)                                                 //building tree with bfs cycle
        {
            x = q[rd++];                                                //current vertex from X part
            for (y = 0; y < n; y++)                                     //iterate through all edges in equality graph
                if (cost[x][y] == lx[x] + ly[y] &&  !T[y])
                {
                    if (yx[y] == -1) break;                             //an exposed vertex in Y found, so
                                                                        //augmenting path exists!
                    T[y] = true;                                        //else just add y to T,
                    q[wr++] = yx[y];                                    //add vertex yx[y], which is matched
                                                                        //with y, to the queue
                    add_to_tree(yx[y], x);                              //add edges (x,y) and (y,yx[y]) to the tree
                }
            if (y < n) break;                                           //augmenting path found!
        }
        if (y < n) break;                                               //augmenting path found!

        if (verbose)
        {
            printf("Augmenting path not found\n");

            print_S_T_sets();
        }

        update_labels();                                                //augmenting path not found, so improve labeling

        draw_all_bfs_trees(root);

        wr = rd = 0;                
        for (y = 0; y < n; y++)        
        //in this cycle we add edges that were added to the equality graph as a
        //result of improving the labeling, we add edge (slackx[y], y) to the tree if
        //and only if !T[y] &&  slack[y] == 0, also with this edge we add another one
        //(y, yx[y]) or augment the matching, if y was exposed
            if (!T[y] &&  slack[y] == 0)
            {
                if (yx[y] == -1)                                        //exposed vertex in Y found - augmenting path exists!
                {
                    x = slackx[y];
                    break;
                }
                else
                {
                    T[y] = true;                                        //else just add y to T,
                    if (!S[yx[y]])    
                    {
                        q[wr++] = yx[y];                                //add vertex yx[y], which is matched with
                                                                        //y, to the queue
                        add_to_tree(yx[y], slackx[y]);                  //and add edges (x,y) and (y,
                                                                        //yx[y]) to the tree
                    }
                }
            }
        if (y < n) break;                                               //augmenting path found!
    }


    if (y < n)                                                          //we found augmenting path!
    {

        if (verbose)
        {
            draw_graph(y); 

            printf("Augmenting path found\n");

            printf("Exposed vertex y%d (via x%d)\n", y, x);

            printf("Matching before is as follows:\n");
            print_matching();

            draw_all_bfs_trees(root);
            pause_for_user();

            printf("Augmenting path:\n");
            //printf("(y) y%d --> x%d (x) ", y, x);
            printf("y%d --> x%d ", y, x);
            fflush(stdout);
            int tx = x;
            while (prev[tx] != -2)
            {
                printf("<===> y%d ", xy[tx]);
                fflush(stdout);
                tx = prev[tx];
                printf("--> x%d ", tx);
                fflush(stdout);
                if (tx == -1)
                {
                    printf("error :-(\n");
                    break;
                }

            }
            printf("\n");

            
        }

        max_match++;                                                    //increment matching
        //in this cycle we inverse edges along augmenting path
        for (int cx = x, cy = y, ty; cx != -2; cx = prev[cx], cy = ty)
        {
            ty = xy[cx];
            yx[cy] = cx;
            xy[cx] = cy;
        }

        if (verbose)
        {

            draw_graph(y); 
            pause_for_user();

            printf("Matching after is as follows:\n");
            print_matching();
            
            printf("\n");

        }



        augment();                                                      //recall function, go to step 1 of the algorithm
    }
}//end of augment() function