Code Search for Developers
 
 
  

idr_binomial.c from EmStar at Krugle


Show idr_binomial.c syntax highlighted

/*
 *
 * Copyright (c) 2003 The Regents of the University of California.  All 
 * rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Neither the name of the University nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
 

#include <stdio.h>
#include <sys/time.h>


#include "idr_i.h"
#include "idr_binomial.h"

struct element *create_list(struct node *element)
{
	struct element *head;
	
	head=(struct element *)malloc(sizeof(struct element));
	head->next=NULL;
	head->element=element;

	return head;
}


void add_element(struct element **head, struct element *entry) 
{

	if (entry==NULL || *head==NULL || head==NULL) {
		printf("add_element: NULL pointer\n");
	}

	entry->next=*head;
	*head=entry;
}


struct element *delete_element(struct element *entry) 
{
	struct element *next;

	if (entry==NULL) {
		printf("delete_element: NULL entry pointer\n");
		return NULL;
	}

	next=entry->next;
	free(entry);

	return next;
}



// returns pointer to head of tree
nodep create_head(struct info *data)
{
	struct node *head;

	head=(struct node *)malloc(sizeof(struct node));
	head->parent=NULL;	// it's the root
	head->child=NULL;
	head->sibling=NULL;
	head->data=*data;
	head->degree=0;
	head->index=data->index;

			
	return head;
}


nodep join_trees(nodep y, nodep z)
{
	if (z==NULL ||y==NULL) {
		printf("join_trees: NULL pointer (y=%d, z=%d)\n",(int)y,(int)z);
	}
	y->parent=z;
	y->sibling=z->child;
	z->child=y;
	z->degree++;
	printf("-");
	return z;
}



nodep create_tree(struct info table[], int elements)
{
	int i=0;
	int recdepth=2<<(elements-1);	// that's a LOT of recursion depth
	nodep head;

	if (recdepth>MAX_RECDEPTH) {
		printf("Recursion depth too large (%d)\n", recdepth);
		exit(1);
	}
	
	// recursion
	if (elements>1) {
		nodep head1;
		nodep head2;
		// split the table in 2 pieces
		struct info t1[elements-1];
		struct info t2[elements-1];

		// first piece of the first table is table[0]
		t1[0]=table[0];
		// first piece of the second table is table[1]
		t2[0]=table[1];
		// the rest are the same
		for (i=1; i<elements-1; i++) {
			t1[i]=table[i+1];
			t2[i]=table[i+1];
		}
		// call myself
		head1=create_tree(t1, elements-1);
		head2=create_tree(t2, elements-1);
		return join_trees(head2, head1);
	} else if (elements==1) {
		// single element, create it
		head=create_head(&table[0]);
		printf(".");
		return head;
	} else {
		// elements <1 ?
		printf("Error\n");
		return NULL;
	}
}	





void print_node_info(nodep n, char silent)
{
	if (silent==1)
		return;

	if (n==NULL) {
		printf("print_node_info: NULL pointer\n");
		return;
	}

	printf("  Degree=%d, Data=%d, Index=%d, Sum=%d\n", 
		n->degree, n->data.data, n->index, n->sum);
}


// walks the tree all the way down using childs
// returns the last element
nodep walk_down(nodep head, int depth, char silent)
{
	struct node *tmp=head;
	int d=0;

	if (depth==0) {
		return tmp;
	}

	while (tmp!=NULL) {
		if (d<=depth) {
			d++;
			print_node_info(tmp, silent);
			if (tmp->child==NULL) {
				return tmp;
			} else {
				tmp=tmp->child;
			}
		} else {
			// I'm too deep, go up 1
			tmp=tmp->parent;
			break;
		}
	}

	return tmp;
}


void walk_tree(nodep head, int depth)
{
	struct node *tmp=head;
	int mydepth=depth;
	
	if (head==NULL) {
		printf("walk_tree: NULL pointer\n");
		return;
	}

	if (depth==0) {
		print_node_info(head, 0);
		return;
	}
	
	// first, go all the way down
	tmp=walk_down(tmp, depth, 0);
//	print_node_info(tmp);

	// I am all the way down to depth, set mydepth=0
	mydepth=0;

	// eventually I will reach the head
	while (tmp!=head) {

		// reached the end, now go up and right (next sibling)
		// try moving to the right first
		while (tmp->sibling!=NULL) {
			tmp=tmp->sibling;
			printf("Sibling=%d\n", tmp->data.data);
			print_node_info(tmp, 0);
			printf("Walking down from %d, mydepth=%d\n", 
					tmp->data.data, mydepth);
			tmp=walk_down(tmp, mydepth, 0);
		}

		// nothing left to the right, now go up	
		tmp=tmp->parent;
		// Moved 1 up, now update mydepth
		mydepth++;
		if (tmp != head) {
			printf("Parent=%d\n", tmp->data.data);
			print_node_info(tmp, 0);
			printf("\n");
		}
	}
}


nodep walk_down_and_sum(nodep head, int depth)
{
	struct node *tmp=head;
	int d=0;

	if (depth==0) {
		return tmp;
	}

	while (tmp!=NULL) {
		if (d<=depth) {
			d++;
			if (tmp->parent != NULL && tmp!=head) {
				tmp->sum=tmp->parent->sum+tmp->data.data;
			} else {
				tmp->sum=tmp->data.data;
			}
			if (tmp->child==NULL) {
				return tmp;
			} else {
				tmp=tmp->child;
			}
		} else {
			// I'm too deep, go up 1
			tmp=tmp->parent;
			break;
		}
	}

	return tmp;
}


void delete_tree(nodep *head)
{
	struct node *tmp=*head;
	struct node *next=NULL;

	if (head==NULL) {
		printf("delete_tree: NULL head pointer\n");
		return;
	}

	// first, go all the way down
	tmp=walk_down(tmp, (*head)->degree, 1);

	// Did we actually go down, or not?
	if (tmp->parent==NULL) {
		// we didn't go down at all because there's nothing underneath
		free(*head);
		*head=NULL;
		return;
	}

	
	// the next pointer should now point to tmp's parent
	next=tmp->parent;
	// remove tmp
	next->child=NULL;	// set my child to NULL, I am about to remove it
	free(tmp);
	printf(".");
	tmp=next;

	while(next!=*head) {
		// first, see if I can go right
		while(next->sibling!=NULL) {
			if (next->child==NULL) {
				// my child is null and I can go right, I should be removed
				tmp=next;
				next=next->sibling;
				printf(".");
				free(tmp);
				tmp=next;
			} else {
				// my child is NOT null, go down
				tmp=walk_down(tmp, (*head)->degree, 1);
				next=tmp->parent;
				next->child=NULL;
				printf(".");
				free(tmp);
				tmp=next;
			}
		}

		// Nothing left in my right or below me. Remove me and go up
		tmp=next;
		next=next->parent;
		next->child=NULL;
		printf(".");
		free(tmp);
		tmp=next;
	}

	// All done, now free the head
	free(*head);	
	*head=NULL;
}

void calculate_sums(nodep head, int depth)
{
	struct node *tmp=head;
	int mydepth=depth;

	if (head==NULL) {
		printf("calculate_sums: NULL head pointer\n");
		return;
	}

	tmp=walk_down_and_sum(tmp, depth);
	mydepth=0;

	while(tmp!=head) {
		while (tmp->sibling!=NULL) {
			tmp=tmp->sibling;
			tmp->sum=tmp->data.data+tmp->parent->sum;
			tmp=walk_down_and_sum(tmp, mydepth);
		}	
		// nothing left to the right or below me
		tmp=tmp->parent;
		mydepth++;
	}

}



void assign_heads(nodep head[])
{
	int i;

	if (head[0]->child==NULL)
		// no children on the head, it's a leaf node
		return;

	head[1]=head[0]->child;	// the second element is the child of the head

	// every other element is the sibling of the previous one
	for (i=2;i<=head[0]->degree;i++) {
		head[i]=head[i-1]->sibling;
	}
}
	
nodep walk_down_and_sum_with_constraint(nodep head, int depth, int min,
										struct element **lh, nodep masterhead)
{
	struct node *tmp=head;
	int d=0;

	if (depth==0) {
		//is this the last binomial tree ?
		// (using data instead of sum, since it's the last tree, so
		// the nodes' parent(which is what the sum value reflects) should
		// be ignored
		if (*lh==NULL && tmp->data.data >= min) {
			*lh=create_list(tmp);
		}
		return tmp;
	}

	while (tmp!=NULL) {
		char check=0;
		if (d<=depth) {
			d++;
			if (tmp->parent != NULL && tmp!=masterhead) {
				tmp->sum=tmp->parent->sum+tmp->data.data;
			} else {
				tmp->sum=tmp->data.data;
			}

			// Sum is calculated, now check
			if (tmp->sum >= min) {
				if (*lh==NULL) {
					*lh=create_list(tmp);
				} else {
					struct element *entry=create_list(tmp);
					add_element(lh, entry);
				}
				check++;
			}

			if (tmp->child==NULL) {
				return tmp;
			} else {
				tmp=tmp->child;
			}
		} else {
			// I'm too deep, go up 1
			tmp=tmp->parent;
			if (check>=1) {
				*lh=delete_element(*lh);
			}
			break;
		}
	}

	return tmp;
}



void calculate_sums_with_constraint(nodep head, int depth, int min, 
									struct element **lh, nodep masterhead)
{
	struct node *tmp=head;
	int mydepth=depth;

	if (head==NULL) {
		printf("calculate_sums_with_constraint: NULL head pointer\n");
		return;
	}

	tmp=walk_down_and_sum_with_constraint(tmp, mydepth, min, lh, masterhead);
	mydepth=0;

	while(tmp!=head) {
		while (tmp->sibling!=NULL) {
//			printf("Moving right\n");
			tmp=tmp->sibling;
			tmp->sum=tmp->data.data+tmp->parent->sum;
			if (tmp->sum >= min) {
				if (*lh==NULL) {
					*lh=create_list(tmp);
				} else {
					struct element *entry=create_list(tmp);
					add_element(lh, entry);
				}
				// added an element. Move the tmp pointer down or the element
				// will be added again
				if (tmp->child!=NULL) {
					tmp=tmp->child;
				}
			}
	//		printf("Going down %d--%d\n", tmp->degree, tmp->data);
			tmp=walk_down_and_sum_with_constraint(tmp, tmp->degree, min, lh,
				 masterhead);
		}	
		// nothing left to the right or below me
//		printf("Moving up\n");
		tmp=tmp->parent;
		mydepth++;
	}

}






See more files for this project here

EmStar

EmStar is a software system for developing and deploying wireless sensor networks involving Linux-based platforms. As the wireless sensor network community has attempted to deploy more complex designs---large-scale, long-lived systems that need self-organization and adaptivity---a number of difficult software design issues have arisen. Advances in software design have not kept pace with the capabilities of hardware. This is because designing for an adaptive, efficient, and useful sensor network has turned out to be surprisingly complex and difficult. EmStar is a Linux-based software framework, whose goal is to dramatically reduce this complexity, enabling work to be shared and reused, and simplifying and speeding the design of new sensor network applications.

Project homepage: http://cvs.cens.ucla.edu/emstar/
Programming language(s): C,Shell Script
License: other

  idr_binomial.c
  idr_binomial.h
  idr_conf.c
  idr_conf.h
  idr_i.h
  idr_lower.c
  idr_main.c
  idr_upper.c
  idr_util.c