int postorder (const BiTreeNode *node, List *list) { if (!bitree_is_eob(node)) { if (!bitree_is_eob(bitree_left(node))) { if (postorder(bitree_left(node), list) != 0) { return -1; } } if (!bitree_is_eob(bitree_right(node))) { if (postorder(bitree_right(node), list) != 0) { return 0; } } if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) { return -1; } } return 0; }
int set_intersection(Set *seti, const Set *set1, const Set *set2) { ListElmt *member; void *data; set_init(seti, set1->match, NULL); for (member = list_head(set1); member != NULL; member = list_next(member)) { if (set_is_member(set2, list_data(member))) { data = list_data(member); if (list_ins_next(seti, list_tail(seti), data) != 0) { set_destroy(seti); return -1; } } } return 0; }
int set_intersection(Set * seti, const Set * set1, const Set * set2) { ListElmt *member; void *data; /***************************************************************************** * Initialize the set for the intersection. * *****************************************************************************/ set_init(seti, set1->match, NULL); /***************************************************************************** * Insert the members present in both sets. * *****************************************************************************/ for (member = list_head(set1); member != NULL; member = list_next(member)) { if (set_is_member(set2, list_data(member))) { data = list_data(member); if (list_ins_next(seti, list_tail(seti), data) != 0) { set_destroy(seti); return -1; } } } return 0; }
int set_difference(Set * setd, const Set * set1, const Set * set2) { ListElmt *member; void *data; /***************************************************************************** * Initialize the set for the difference. * *****************************************************************************/ set_init(setd, set1->match, NULL); /***************************************************************************** * Insert the members from set1 not in set2. * *****************************************************************************/ for (member = list_head(set1); member != NULL; member = list_next(member)) { if (!set_is_member(set2, list_data(member))) { data = list_data(member); if (list_ins_next(setd, list_tail(setd), data) != 0) { set_destroy(setd); return -1; } } } return 0; }
int set_difference(Set *setd, const Set *set1, const Set *set2) { ListElem *member; void *data; //init union set_init(setd, set1->match, NULL); //insert members of the first set for (member = list_head(set1); member != NULL; member = list_next(member)) { if (!set_is_member(set2, list_data(member))) { data = list_data(member); if (list_ins_next(setd, list_tail(setd), data) != 0) { set_destroy(setd); return -1; } } } return 0; };
/** * 后序遍历二叉树 */ int postorder(const BiTreeNode *node, List *list){ if(!bitree_is_eob(node)){ if(!bitree_is_eob(bitree_left(node))){ if(inorder(bitree_left(node), list) != 0){ printf("%s\n","postorder() left tree order end"); return -1; } } if(!bitree_is_eob(bitree_right(node))){ if(inorder(bitree_right(node), list) != 0){ printf("%s\n", "postorder() right tree order end"); return -1; } } if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0){ printf("%s\n", "postorder() add node to list fail."); return -1; } } return 0; }
int main() { List list; ListElmt *element; int *data; int i; list_init(&list, free); element = list_head(&list); for (i = 10; i > 0; i--) { if ((data = (int *)malloc(sizeof(int))) == NULL) { return 1; } * data = i; if (list_ins_next(&list, NULL, data) != 0) { return 1; } } print_list(&list); element = list_head(&list); for (i = 0; i < 7; i++) { element = list_next(element); } data = list_data(element); fprintf(stdout, "Removing an element after the one containing %03d\n", *data); if (list_rem_next(&list, element, (void **)&data) != 0) { return 1; } print_list(&list); fprintf(stdout, "Inserting 011 at the tail of the list\n"); *data = 11; if (list_ins_next(&list, list_tail(&list), data) != 0) { return 1; } print_list(&list); fprintf(stdout, "Removing an element after the first element\n"); element = list_head(&list); if (list_rem_next(&list, element, (void **)&data) != 0) { return 1; } print_list(&list); fprintf(stdout, "Inserting 012 at the head of the list\n"); *data = 12; if (list_ins_next(&list, NULL, data) != 0) { return 1; } print_list(&list); fprintf(stdout, "Iterating and removing the fourth element\n"); element = list_head(&list); element = list_next(element); element = list_next(element); if(list_rem_next(&list, element, (void **)&data) != 0) { return 1; } print_list(&list); fprintf(stdout, "Inserting 013 after the first element\n"); *data = 13; if (list_ins_next(&list, list_head(&list), data) != 0) { return 1; } print_list(&list); i = list_is_head(&list, list_head(&list)); fprintf(stdout, "Testing list_is_head...Value=%d (1=OK)\n", i); i = list_is_head(&list, list_tail(&list)); fprintf(stdout, "Testing list_is_head...Value=%d (1=OK)\n", i); i = list_is_tail(list_tail(&list)); fprintf(stdout, "Testing list_is_head...Value=%d (1=OK)\n", i); i = list_is_tail(list_head(&list)); fprintf(stdout, "Testing list_is_head...Value=%d (1=OK)\n", i); fprintf(stdout, "Destroying the list\n"); list_destroy(&list); return 0; }
/* 入队 */ int queue_enqueue(Queue *queue, const void *data) { /* 插入尾部 */ return list_ins_next(queue, list_tail(queue), data); }
int queue_enqueue(Queue *queue, const void *data) { // enqueue the data return list_ins_next(queue, list_tail(queue), data); }
/* queue push */ int queue_push(Queue *queue, void *data) { return list_ins_next(queue, list_tail(queue), data); }
int main(int argc, char **argv) { List list; ListElmt *element; int *data, i; /***************************************************************************** * * * Initialize the linked list. * * * *****************************************************************************/ list_init(&list, free); /***************************************************************************** * * * Perform some linked list operations. * * * *****************************************************************************/ element = list_head(&list); for (i = 10; i > 0; i--) { if ((data = (int *)malloc(sizeof(int))) == NULL) return 1; *data = i; if (list_ins_next(&list, NULL, data) != 0) return 1; } print_list(&list); element = list_head(&list); for (i = 0; i < 7; i++) element = list_next(element); data = list_data(element); fprintf(stdout, "Removing an element after the one containing %03d\n", *data); if (list_rem_next(&list, element, (void **)&data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 011 at the tail of the list\n"); *data = 11; if (list_ins_next(&list, list_tail(&list), data) != 0) return 1; print_list(&list); fprintf(stdout, "Removing an element after the first element\n"); element = list_head(&list); if (list_rem_next(&list, element, (void **)&data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 012 at the head of the list\n"); *data = 12; if (list_ins_next(&list, NULL, data) != 0) return 1; print_list(&list); fprintf(stdout, "Iterating and removing the fourth element\n"); element = list_head(&list); element = list_next(element); element = list_next(element); if (list_rem_next(&list, element, (void **)&data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 013 after the first element\n"); *data = 13; if (list_ins_next(&list, list_head(&list), data) != 0) return 1; print_list(&list); i = list_is_head(&list, list_head(&list)); fprintf(stdout, "Testing list_is_head...Value=%d (1=OK)\n", i); i = list_is_head(&list, list_tail(&list)); fprintf(stdout, "Testing list_is_head...Value=%d (0=OK)\n", i); i = list_is_tail(list_tail(&list)); fprintf(stdout, "Testing list_is_tail...Value=%d (1=OK)\n", i); i = list_is_tail(list_head(&list)); fprintf(stdout, "Testing list_is_tail...Value=%d (0=OK)\n", i); /***************************************************************************** * * * Destroy the linked list. * * * *****************************************************************************/ fprintf(stdout, "Destroying the list\n"); list_destroy(&list); return 0; }
int set_insert(Set *set, const void *data) { if (set_is_member(set, data)) return 1; return list_ins_next(set, list_tail(set), data); }
static int get_interface_addr(struct ospfd *ospfd) { int ret; struct ifaddrs *ifaddr; /* First of all: remove all entries if any is available. * This makes this method re-callable to refresh the interface address * status. */ list_destroy(ospfd->network.rd_list); ospfd->network.rd_list = list_create(list_cmp_rd, list_free_rd); ret = getifaddrs(&ifaddr); if (ret < 0) { err_sys("failed to query interface addresses"); return FAILURE; } while (ifaddr != NULL) { struct rd *rd; struct ip_addr *ip_addr; struct sockaddr_in *in4; struct sockaddr_in6 *in6; if (!ifaddr->ifa_addr) goto next; switch (ifaddr->ifa_addr->sa_family) { /* only IPv{4,6} */ case AF_INET: case AF_INET6: break; default: goto next; break; } /* We know it is a IPv4 or IPv6 address. * Now we search the routing domain list for * this interface. If we found is we add the new * IP address, if not we add a new routing domain * and also add the IP address */ rd = list_lookup_match(ospfd->network.rd_list, ifname_cmp, ifaddr->ifa_name); if (rd == NULL) { /* new interface ... */ rd = xzalloc(sizeof(struct rd)); ret = list_ins_next(ospfd->network.rd_list, NULL, rd); if (ret != SUCCESS) { fprintf(stderr, "Failure in inserting rd\n"); abort(); } memcpy(rd->if_name, ifaddr->ifa_name, min((strlen(ifaddr->ifa_name) + 1), sizeof(rd->if_name))); rd->if_flags = ifaddr->ifa_flags; /* see netdevice(7) for list of flags */ rd->ip_addr_list = list_create(list_cmp_struct_ip_addr, free_ip_addr); } /* interface specific setup is fine, we can * now carelessly add the new ip address to * the interface */ ip_addr = xzalloc(sizeof(struct ip_addr)); ip_addr->family = ifaddr->ifa_addr->sa_family; switch (ip_addr->family) { case AF_INET: /* copy address */ in4 = (struct sockaddr_in *)ifaddr->ifa_addr; memcpy(&ip_addr->ipv4.addr, &in4->sin_addr, sizeof(ip_addr->ipv4.addr)); /* copy netmask */ in4 = (struct sockaddr_in *)ifaddr->ifa_netmask; memcpy(&ip_addr->ipv4.netmask, &in4->sin_addr, sizeof(ip_addr->ipv4.netmask)); /* copy broadcast */ in4 = (struct sockaddr_in *)ifaddr->ifa_broadaddr; memcpy(&ip_addr->ipv4.broadcast, &in4->sin_addr, sizeof(ip_addr->ipv4.broadcast)); break; case AF_INET6: /* copy address */ in6 = (struct sockaddr_in6 *)ifaddr->ifa_addr; memcpy(&ip_addr->ipv6.addr, &in6->sin6_addr, sizeof(ip_addr->ipv6.addr)); /* and scope too */ ip_addr->ipv6.scope = in6->sin6_scope_id; /* copy netmask */ in6 = (struct sockaddr_in6 *)ifaddr->ifa_netmask; memcpy(&ip_addr->ipv6.netmask, &in6->sin6_addr, sizeof(ip_addr->ipv6.netmask)); break; default: err_msg("Programmed error - address (protocol) not supported: %d", ip_addr->family); return FAILURE; break; } /* and at the newly data at the end of the list */ list_insert(rd->ip_addr_list, ip_addr); next: ifaddr = ifaddr->ifa_next; } freeifaddrs(ifaddr); #if 0 list_for_each(ospfd->network.rd_list, print_all_interfaces); #endif return SUCCESS; }
void resolve_symbols(int fd, list_t *list) { int i, j; /* loop counter */ int ret; /* return value */ char *strings; /* strtab entries */ char *string; /* symbol table strtab entries */ Elf32_Sym *sym; /* symbol entry */ Elf32_Sym *tmp_sym; /* temporary symbol */ Elf32_Ehdr ehdr; /* ELF header */ Elf32_Shdr *shdr; /* section header */ Elf32_Shdr *strtab; /* strtab section header */ Elf32_Shdr *tmp_shdr; /* temporary section header */ Elf32_Shdr *text_shdr; /* .text section header */ /* * Read the ELF Header and display */ ret = read(fd, &ehdr, sizeof(ehdr)); if(ret != sizeof(ehdr)) { perror("read"); exit(-1); } /* * Allocate memory for sections headers */ shdr = (Elf32_Shdr *) malloc(sizeof(Elf32_Shdr) * ehdr.e_shnum); if(!shdr) { perror("malloc"); exit(-1); } ret = lseek(fd, ehdr.e_shoff, SEEK_SET); if(ret < 0) { perror("lseek"); exit(-1); } ret = read(fd, shdr, sizeof(Elf32_Shdr) * ehdr.e_shnum); if(ret != sizeof(Elf32_Shdr) * ehdr.e_shnum) { perror("read"); exit(-1); } /* * Pull out the string table */ strtab = &shdr[ehdr.e_shstrndx]; strings = (char *) malloc(strtab->sh_size); if(!strings) { perror("malloc"); exit(-1); } ret = lseek(fd, strtab->sh_offset, SEEK_SET); if(ret < 0) { perror("lseek"); exit(-1); } ret = read(fd, strings, strtab->sh_size); if(ret != strtab->sh_size) { perror("read"); exit(-1); } /* * Iterate through sections headers, find symtab */ for(tmp_shdr = shdr, i = 0; i < ehdr.e_shnum; ++tmp_shdr, i++) { if(tmp_shdr->sh_type == SHT_SYMTAB) { Elf32_Shdr *strtab_hdr = &shdr[tmp_shdr->sh_link]; string = (char *) malloc(strtab_hdr->sh_size); if(!string) { perror("malloc"); exit(-1); } ret = lseek(fd, strtab_hdr->sh_offset, SEEK_SET); if(ret != strtab_hdr->sh_offset) { perror("lseek"); exit(-1); } ret = read(fd, string, strtab_hdr->sh_size); if(ret != strtab_hdr->sh_size) { perror("read"); exit(-1); } sym = (Elf32_Sym *) malloc(tmp_shdr->sh_size); if(!sym) { perror("malloc"); exit(-1); } ret = lseek(fd, tmp_shdr->sh_offset, SEEK_SET); if(ret != tmp_shdr->sh_offset) { perror("lseek"); exit(-1); } ret = read(fd, sym, tmp_shdr->sh_size); if(ret != tmp_shdr->sh_size) { perror("read"); exit(-1); } for(tmp_sym = sym, j = 0; j < tmp_shdr->sh_size; j += sizeof(Elf32_Sym), ++tmp_sym) { text_shdr = &shdr[tmp_sym->st_shndx]; if(tmp_sym->st_shndx > ehdr.e_shnum) continue; if(!strcmp(&strings[text_shdr->sh_name], ".text")) { bpx_t *bpx; if(strlen(&string[tmp_sym->st_name]) <= 0) continue; if(!tmp_sym->st_size) continue; bpx = (bpx_t *) malloc(sizeof(bpx_t)); bpx->name = &string[tmp_sym->st_name]; bpx->addr = tmp_sym->st_value; bpx->value = 0; list_ins_next(list, list_tail(list), bpx); } } break; } } }
int queue_enqueue(Queue *queue, const void *data){ return list_ins_next(queue, queue->tail, data); }
void verifyInterSection(uint8_t** set,uint8_t** recved,int32_t setSize, List* L){ int32_t* setC = setToInt(set, setSize); int32_t* setS= setToInt(recved, setSize); CHTbl htbl; intHash_init(&htbl, setSize); for(int i=0;i<setSize;i++){ //printf("%d,%d\n",i,setC[i]); intHash_insert(&htbl, setC[i]); } List L2; list_init(&L2, &free); for(int i=0;i<setSize;i++){ //in the intersection if(intHash_lookup(&htbl, setS[i])==0){ list_ins_next(&L2, NULL, recved[i]); }; } printf("size of L2=%d\n",list_size(&L2)); printf("size of L1=%d\n",list_size(L)); if(list_size(&L2)!=list_size(L)){ printf("Incorrect intersection!\n"); abort(); } uint8_t** int1=(uint8_t**)calloc(list_size(L), sizeof(uint8_t*)); uint8_t** int2=(uint8_t**)calloc(list_size(&L2), sizeof(uint8_t*)); ListElmt * e1 = L->head; ListElmt * e2= L2.head; for(int i=0;i<list_size(&L2);i++){ int1[i]=(uint8_t*)e1->data; int2[i]=(uint8_t*)e2->data; e1=e1->next; e2=e2->next; } for(int i=0;i<list_size(&L2);i++){ if(!contains(int1,int2[i],list_size(&L2),defaultDatalen)){ printf("Incorrect intersection!\n"); //abort(); } } printf("Intersection correct!\n"); printf("Should contain:\n"); for(int i=0;i<list_size(&L2);i++){ printBytes(int2[i], defaultDatalen); } printf("Contains:\n"); for(int i=0;i<list_size(&L2);i++){ printBytes(int1[i], defaultDatalen); } }
int bfs(Graph *graph, BfsVertex *start, List *hops) { Queue queue; AdjList *adjlist, *clr_adjlist; BfsVertex *clr_vertex, *adj_vertex; ListElmt *element, *member; /***************************************************************************** * * * Initialize all of the vertices in the graph. * * * *****************************************************************************/ for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { clr_vertex = ((AdjList *)list_data(element))->vertex; if (graph->match(clr_vertex, start)) { /*********************************************************************** * * * Initialize the start vertex. * * * ***********************************************************************/ clr_vertex->color = gray; clr_vertex->hops = 0; } else { /*********************************************************************** * * * Initialize vertices other than the start vertex. * * * ***********************************************************************/ clr_vertex->color = white; clr_vertex->hops = -1; } } /***************************************************************************** * * * Initialize the queue with the adjacency list of the start vertex. * * * *****************************************************************************/ queue_init(&queue, NULL); if (graph_adjlist(graph, start, &clr_adjlist) != 0) { queue_destroy(&queue); return -1; } if (queue_enqueue(&queue, clr_adjlist) != 0) { queue_destroy(&queue); return -1; } /***************************************************************************** * * * Perform breadth-first search. * * * *****************************************************************************/ while (queue_size(&queue) > 0) { adjlist = queue_peek(&queue); /************************************************************************** * * * Traverse each vertex in the current adjacency list. * * * **************************************************************************/ for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { adj_vertex = list_data(member); /*********************************************************************** * * * Determine the color of the next adjacent vertex. * * * ***********************************************************************/ if (graph_adjlist(graph, adj_vertex, &clr_adjlist) != 0) { queue_destroy(&queue); return -1; } clr_vertex = clr_adjlist->vertex; /*********************************************************************** * * * Color each white vertex gray and enqueue its adjacency list. * * * ***********************************************************************/ if (clr_vertex->color == white) { clr_vertex->color = gray; clr_vertex->hops = ((BfsVertex *)adjlist->vertex)->hops + 1; if (queue_enqueue(&queue, clr_adjlist) != 0) { queue_destroy(&queue); return -1; } } } /************************************************************************** * * * Dequeue the current adjacency list and color its vertex black. * * * **************************************************************************/ if (queue_dequeue(&queue, (void **)&adjlist) == 0) { ((BfsVertex *)adjlist->vertex)->color = black; } else { queue_destroy(&queue); return -1; } } queue_destroy(&queue); /***************************************************************************** * * * Pass back the hop count for each vertex in a list. * * * *****************************************************************************/ list_init(hops, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { /************************************************************************** * * * Skip vertices that were not visited (those with hop counts of -1). * * * **************************************************************************/ clr_vertex = ((AdjList *)list_data(element))->vertex; if (clr_vertex->hops != -1) { if (list_ins_next(hops, list_tail(hops), clr_vertex) != 0) { list_destroy(hops); return -1; } } } return 0; }
int list_push_back(struct linked_list* list, const void* data) { return list_ins_next(list, list->tail, data); }
/* this is O(1) but is included for convencience */ void list_append(List *list, void *data){ ListElmt *node = list->tail; list_ins_next(list,list->tail,data); printf("new list size after append: %d\n", list->size); return; }
static int dfs_main(Graph * graph, AdjList * adjlist, List * ordered) { AdjList *clr_adjlist; DfsVertex *clr_vertex, *adj_vertex; ListElmt *member; /***************************************************************************** * * * Color the vertex gray and traverse its adjacency list. * * * *****************************************************************************/ ((DfsVertex *) adjlist->vertex)->color = gray; for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { /************************************************************************** * * * Determine the color of the next adjacent vertex. * * * **************************************************************************/ adj_vertex = list_data(member); if (graph_adjlist(graph, adj_vertex, &clr_adjlist) != 0) return -1; clr_vertex = clr_adjlist->vertex; /************************************************************************** * * * Move one vertex deeper when the next adjacent vertex is white. * * * **************************************************************************/ if (clr_vertex->color == white) { if (dfs_main(graph, clr_adjlist, ordered) != 0) return -1; } } /***************************************************************************** * * * Color the current vertex black and make it first in the list. * * * *****************************************************************************/ ((DfsVertex *) adjlist->vertex)->color = black; if (list_ins_next(ordered, NULL, (DfsVertex *) adjlist->vertex) != 0) return -1; return 0; }
int stack_push (Stack *stack, const void *data) { /* Push the data onto the stack. */ return list_ins_next (stack, NULL, data); }
/*--------------------------------------------------------------*/ int shortest(Graph *graph, Heap *H, double *A_weights, const PathVertex *start, List *paths, int (*match) (const void *key1, const void *key2), int gw, int gh) { AdjList *adjlist; PathVertex *pth_vertex, *adj_vertex; ListElmt *element, *member; int found, i; /*PairHeap H; Position *P; */ /*Heap *H; */ /* A_weights binary heap, used for priority queue */ /*double *A_weights; */ /* array of weights to be min-heapified */ CoordData Index2Coord[(gw*gh*2)+1]; int Coord2Index[gw][gh][2]; int index; AdjList *Coord2Vertex[gw][gh][2]; /***************************************************************************** * * * Initialize all of the vertices in the graph. * * * *****************************************************************************/ found = 0; index = 1; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { pth_vertex = ((AdjList *)list_data(element))->vertex; if (match(pth_vertex, start)) { short int x,y,z; /*********************************************************************** * * * Initialize the start vertex. * * * ***********************************************************************/ x = ((CoordData*)((PathVertex*)pth_vertex)->data)->x; y = ((CoordData*)((PathVertex*)pth_vertex)->data)->y; z = ((CoordData*)((PathVertex*)pth_vertex)->data)->z; Coord2Vertex[x][y][z] = list_data(element); pth_vertex->color = white; pth_vertex->d = 0; pth_vertex->parent = NULL; found = 1; A_weights[index] = pth_vertex->d; Coord2Index[x][y][z] = index; Index2Coord[index].x = x; Index2Coord[index].y = y; Index2Coord[index].z = z; index++; } else { short int x,y,z; /*********************************************************************** * * * Initialize vertices other than the start vertex. * * * ***********************************************************************/ x = ((CoordData*)((PathVertex*)pth_vertex)->data)->x; y = ((CoordData*)((PathVertex*)pth_vertex)->data)->y; z = ((CoordData*)((PathVertex*)pth_vertex)->data)->z; Coord2Vertex[x][y][z] = list_data(element); pth_vertex->color = white; pth_vertex->d = DBL_MAX; pth_vertex->parent = NULL; A_weights[index] = pth_vertex->d; Coord2Index[x][y][z] = index; Index2Coord[index].x = x; Index2Coord[index].y = y; Index2Coord[index].z = z; index++; } } /***************************************************************************** * * * Return if the start vertex was not found. * * * *****************************************************************************/ if (!found) return -1; binheap_build(H,A_weights,gw*gh*2); /* build the heap */ /***************************************************************************** * * * Use Dijkstra's algorithm to compute shortest paths from the start vertex. * * * *****************************************************************************/ i = 0; while (i < graph_vcount(graph)) { short int x,y,z; /************************************************************************** * * * Select the white vertex with the smallest shortest-path estimate. * * * **************************************************************************/ index = binheap_indexofmin(H); /* get index of minimum-weight edge */ binheap_extract(H); /* remove it from the heap */ x = Index2Coord[index].x; y = Index2Coord[index].y; z = Index2Coord[index].z; adjlist = Coord2Vertex[x][y][z]; /************************************************************************** * * * Color the selected vertex black. * * * **************************************************************************/ ((PathVertex *)adjlist->vertex)->color = black; /************************************************************************** * * * Traverse each vertex adjacent to the selected vertex. * * * **************************************************************************/ for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { short int px,py,pz; adj_vertex = list_data(member); px = ((CoordData*)((PathVertex*)adj_vertex)->data)->x; py = ((CoordData*)((PathVertex*)adj_vertex)->data)->y; pz = ((CoordData*)((PathVertex*)adj_vertex)->data)->z; /*********************************************************************** * * * Find the adjacent vertex in the list of adjacency-list structures. * * * ***********************************************************************/ pth_vertex = ((AdjList*)Coord2Vertex[px][py][pz])->vertex; /***************************************************************** * * * Relax the adjacent vertex in the list of adjacency-list * * structures. * * * *****************************************************************/ if (relax(adjlist->vertex, pth_vertex, adj_vertex->weight)) { /* update pth_vertex->d in FH */ binheap_decrease_key(H, Coord2Index[px][py][pz] , pth_vertex->d); } } /************************************************************************** * * * Prepare to select the next vertex. * * * **************************************************************************/ i++; } /* destroy binary heap */ /*binheap_destroy(H);*/ /*free(A_weights);*/ /***************************************************************************** * * * Load the vertices with their path information into a list. * * * *****************************************************************************/ list_init(paths, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { /************************************************************************** * * * Load each black vertex from the list of adjacency-list structures. * * * **************************************************************************/ pth_vertex = ((AdjList *)list_data(element))->vertex; if (pth_vertex->color == black) { if (list_ins_next(paths, list_tail(paths), pth_vertex) != 0) { printf("Problem inserting!\n"); list_destroy(paths); return -1; } } } return 0; }
int mst(Graph *graph, const MstVertex *start, List *span, int (*match)(const void *key1, const void *key2)) { AdjList *adjlist = NULL; MstVertex *mst_vertex, *adj_vertex; ListElmt *element, *member; double minimum; int found, i; found = 0; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (match(mst_vertex, start)) { mst_vertex->color = white; mst_vertex->key = 0; mst_vertex->parent = NULL; found = 1; } else { mst_vertex->color = white; mst_vertex->key = DBL_MAX; mst_vertex->parent = NULL; } } if (!found) return -1; /* * Use Prim's algorithm */ i = 0; /* Select white vertex with the smallest value */ while (i < graph_vcount(graph)) { minimum = DBL_MAX; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == white && mst_vertex->key < minimum) { minimum = mst_vertex->key; adjlist = list_data(element); } } /* Color the selected vertex black */ ((MstVertex *)adjlist->vertex)->color = black; for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { adj_vertex = list_data(member); for(element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (match(mst_vertex, adj_vertex)) { if (mst_vertex->color == white && adj_vertex->weight < mst_vertex->key) { mst_vertex->key = adj_vertex->weight; mst_vertex->parent = adjlist->vertex; } break; } } } i++; } list_init(span, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == black) { if (list_ins_next(span, list_tail(span), mst_vertex) != 0) { list_destroy(span); return -1; } } } return 0; }
/* mst */ int mst(Graph *graph, const MstVertex *start, List *span, int (*match)(const void *key1, const void *key2)) { AdjList *adjlist; MstVertex *mst_vertex, *adj_vertex; ListElmt *element, *member; double minimum; int found, i; /* Initialize all of the vertices in the graph. */ found = 0; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (match(mst_vertex, start)) { /* Initialize the start vertex. */ mst_vertex->color = white; mst_vertex->key = 0; mst_vertex->parent = NULL; found = 1; } else { /* Initialize vertices other than the start vertex. */ mst_vertex->color = white; mst_vertex->key = DBL_MAX; mst_vertex->parent = NULL; } } /* Return if the start vertex was not found. */ if (!found) { return -1; } /* Use Prim's algorithm to compute a minimum spanning tree. */ i = 0; while (i < graph_vcount(graph)) { /* Select the white vertex with the smallest key value. */ minimum = DBL_MAX; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == white && mst_vertex->key < minimum) { minimum = mst_vertex->key; adjlist = list_data(element); } } /* color the selected vertex black. */ ((MstVertex *)adjlist->vertex)->color = black; /* traverse each vertex adjacent to the selected vertex. */ for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { adj_vertex = list_data(member); /* Find the adjacent vertex in the list of * adjacency-list structures. */ for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *) list_data(element))->vertex; if (match(mst_vertex, adj_vertex)) { /* decide whether to change the key * value and parent of the adjacent * vertex in the list of * adjacency-list structures.*/ if (mst_vertex->color == white && adj_vertex->weight < mst_vertex->key) { mst_vertex->key = adj_vertex->weight; mst_vertex->parent = adjlist->vertex; } break; } } } /* prepare to select the next vertex. */ i++; } /* Load the minimum spanning tree into a list. */ list_init(span, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL ; element = list_next(element)) { /* Load each black vertex from the list of * adjacency-list structures. */ mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == black) { if (list_ins_next(span, list_tail(span), mst_vertex) != 0) { list_destroy(span); return -1; } } } return 0; }
/*--------------------------------------------------------------*/ void SPElement2sPath(SPElement *path, List *sPath, CoordData *start) { int s,p,v; /* "pointers" to vertices in path */ sPathData *newElement; CoordData *vCoord,*pCoord; int done; list_init(sPath, (void*)sPath_vertex_free); /* find end vertex in path (root of list, parent == -1) */ s = 0; while ( path[s].parent != -1 ) s++; /* find startd vertex in path */ v = 0; while (!(( path[v].c.x == start->x )&&( path[v].c.y == start->y )&&( path[v].c.z == start->z ))) v++; p = path[v].parent; done = 0; /* follow v back to root (when v == s) */ while (!done) { /* allocate some memory */ newElement = (sPathData*) malloc(sizeof(sPathData)); vCoord = (CoordData*) malloc(sizeof(CoordData)); pCoord = (CoordData*) malloc(sizeof(CoordData)); if ((newElement == NULL)||(vCoord == NULL)||(pCoord == NULL)) { printf("shortest.c : mem allocation error\n"); fflush(stdout); exit(1); } /* set current vertex coords */ vCoord->x = path[v].c.x; vCoord->y = path[v].c.y; vCoord->z = path[v].c.z; /* set parent vertex coords */ pCoord->x = path[p].c.x; pCoord->y = path[p].c.y; pCoord->z = path[p].c.z; /* set the new element to list */ newElement->vertex = vCoord; newElement->parent = pCoord; newElement->d = path[v].d; /* insert the element into the list */ if (list_ins_next(sPath, list_tail(sPath), newElement) != 0) { printf("Problem inserting into sPath!\n"); list_destroy(sPath); exit(1); } /* next vertex */ if (path[p].parent == -1) { done = 1; /*insert one more element starting with parent */ newElement = (sPathData*) malloc(sizeof(sPathData)); vCoord = (CoordData*) malloc(sizeof(CoordData)); if ((newElement==NULL)||(vCoord==NULL)) { printf("helper.c : memory allocation error\n"); fflush(stdout); exit(1); } vCoord->x = path[p].c.x; vCoord->y = path[p].c.y; vCoord->z = path[p].c.z; newElement->vertex = vCoord; newElement->parent = NULL; newElement->d = 0; if (list_ins_next(sPath, list_tail(sPath), newElement) != 0){ printf("Problem inserting into sPath!\n"); list_destroy(sPath); exit(1); } } else { v = p; p = path[p].parent; } } }
int gridSteinerFH(Graph *grid_graph, AdjList**** Edge2Adj, int width, int height, CoordData *term, int no_terminals, double *L,int net_num, int *edge_count_OUT, int **SteinerTree_OUT, int l, int K) { int i,j; /* globals */ int GRID_WIDTH, GRID_HEIGHT, NO_TERMINALS; Graph ND; /* distance network of terminals */ /*used to generate grid graph */ PathVertex *path_vertex; sPathData *sPath_vertex; CoordData *coord; /* used in shortest paths computations */ PathVertex **terminals; /* a (1D) array of terminal (pointers) */ List *tempPaths, /* tempporary */ **sPaths; /* 2d array of shortest path lists */ ListElmt *element; /* temp, used to traverse a list */ /* used in computing MST of ND */ MstVertex *mst_start, *mst_vertex, *mst_vertex1, *mst_vertex2; List TD; /* spanning tree of ND */ /* used in final steps of algorithm */ Graph NTD; /* complete distance network */ List T; /* spanning tree of NTD (eventually the steiner tree)*/ int isSteiner; /* boolean flag */ double tree_cost; /* total cost of the steiner tree (unused, this is computed after*/ GRID_WIDTH = width; GRID_HEIGHT = height; NO_TERMINALS = no_terminals; mst_start = NULL; /*-----------------------------------------------*/ /* If the number of terminals is two, then we */ /* only need to perform one call of Dijkstra to */ /* get the Steiner Tree */ /*-----------------------------------------------*/ if (NO_TERMINALS == 2) { PathVertex *v1,*v2; /* the two terminals*/ CoordData *c1,*c2; /* coordinates of the two terminals*/ List P; /* P-Array in Dijkstra's*/ ListElmt *e; /* list counter*/ List T; /* steiner tree*/ double tree_cost; int j; int first_edge,last_edge; PathVertex *u; u = NULL; /* allocate vertices */ v1 = (PathVertex*) malloc(sizeof(PathVertex)); v2 = (PathVertex*) malloc(sizeof(PathVertex)); c1 = (CoordData*) malloc(sizeof(CoordData)); c2 = (CoordData*) malloc(sizeof(CoordData)); /* set terminal data */ c1->x = term[0].x; c1->y = term[0].y; c1->z = term[0].z; c2->x = term[1].x; c2->y = term[1].y; c2->z = term[1].z; v1->data = c1; v2->data = c2; /* compute shortest path from v1 */ if (shortest(grid_graph, v1 , &P, match_coord,GRID_WIDTH,GRID_HEIGHT) != 0) return 1; /* initialize the tree */ list_init(&T,NULL); /* find the end vertex (v2)*/ for (e = list_head(&P); e != NULL; e = list_next(e)) if ( match_coord(v2,list_data(e))) u = (PathVertex*)list_data(e); first_edge = 1; last_edge = 0; /* follow the end vertex back to the start vertex*/ while (u->parent != NULL) { int ux,uy,uz,upx,upy,upz; AdjList *a; ListElmt *ee; /*current vertex*/ ux = ((CoordData*)((PathVertex*)u)->data)->x; uy = ((CoordData*)((PathVertex*)u)->data)->y; uz = ((CoordData*)((PathVertex*)u)->data)->z; /*connecting vertex (parent)*/ upx = ((CoordData*)((PathVertex*)u->parent)->data)->x; upy = ((CoordData*)((PathVertex*)u->parent)->data)->y; upz = ((CoordData*)((PathVertex*)u->parent)->data)->z; /* get the index of the edge that connects (ux,uy,uz) and its parent*/ a = Edge2Adj[ux][uy][uz]; for (ee = list_head(&a->adjacent); ee != NULL; ee = list_next(ee)) { PathVertex *v; int *i; int vx,vy,vz; v = (PathVertex*)list_data(ee); vx = ((CoordData*)v->data)->x; vy = ((CoordData*)v->data)->y; vz = ((CoordData*)v->data)->z; /* found it*/ if (( vx == upx ) && ( vy == upy ) && ( vz == upz )) { /*don't insert if its a via*/ if (first_edge) { first_edge = 0; if (v->index > ((grid_graph->ecount / 2) - (grid_graph->vcount/2))) continue; } /*check if its the last edge*/ if (u->parent != NULL) if (u->parent->parent == NULL) last_edge = 1; /* don't insert if its a via*/ if (last_edge) if (v->index > ((grid_graph->ecount / 2) - (grid_graph->vcount/2))) continue; i = (int*) malloc(sizeof(int)); tree_cost += v->weight; *i = v->index; list_ins_next(&T, list_tail(&T),i); } } /* next */ u = u->parent; } /* count total edges*/ *edge_count_OUT = list_size(&T); /* write the solution (including vias)*/ if ((*(SteinerTree_OUT) = (int*) malloc(sizeof(int)*(list_size(&T))))==NULL) { printf("gsFH.h : SteinerTree_OUT mem allocation error\n"); fflush(stdout); exit(1); } e = list_head(&T); for (j = 0; ((j < list_size(&T))&&(e!=NULL)); j++,e=list_next(e)) (*SteinerTree_OUT)[j] = *((int*)list_data(e)); /* free up some temps*/ free(v1->data); free(v1); free(v2->data); free(v2); list_destroy(&P); list_destroy(&T); return 0; } /*--------------------------------------------------------*/ /* General case of 3 or more terminals begins here. The */ /* above code for 2 terminals or less can be removed */ /* without affecting the block solution. However, it is */ /* faster with the special case */ /*--------------------------------------------------------*/ /* Create Path Vertices out of the original terminal set */ if ((terminals = (PathVertex**) malloc(sizeof(PathVertex*)*NO_TERMINALS))==NULL) { printf("gsFH.h : terminals mem allocation error\n"); fflush(stdout); exit(1); } for (i = 0; i < NO_TERMINALS; i++) { int x,y,z; x = term[i].x; y = term[i].y; z = term[i].z; path_vertex = (PathVertex*) malloc(sizeof(PathVertex)); coord = (CoordData*) malloc(sizeof(CoordData)); if ((path_vertex == NULL)||(coord == NULL)) { printf("gsFH.h : terminal[i] mem allocation error\n"); fflush(stdout); exit(1); } coord->x = x; coord->y = y; coord->z = z; path_vertex->data = coord; terminals[i] = path_vertex; } /* inialize an array of list pointers used in extracting shortest paths from Dijkstra */ sPaths = (List**) malloc(sizeof(List*)*NO_TERMINALS); if (sPaths == NULL) { printf("gsFH.h : sPaths mem allocation error\n"); fflush(stdout); exit(1); } if ((tempPaths = (List*) malloc(sizeof(List)*NO_TERMINALS))==NULL) { printf("gsFH.h : tempPaths mem allocation error\n"); fflush(stdout); exit(1); } for (i = 0; i < NO_TERMINALS; i++) if ((sPaths[i] = (List*) malloc(sizeof(List)*NO_TERMINALS))==NULL) { printf("gsFH.h : sPaths[i] mem allocation error\n"); fflush(stdout); exit(1); } /*--------------------------------------------------------------------------------------*/ /* COMPUTE THE SHORTEST PATHS */ /* Shortest paths are computed using O(EV^2) version of Dijkstras Algorithm */ /*--------------------------------------------------------------------------------------*/ /* for each terminal (stored as a path vertex), find the shortest path */ /* The shortest path for terminal[i] is stored in the List pointed to by */ /* paths[i]. */ for (i = 0; i < NO_TERMINALS; i++) { if (shortest(grid_graph, terminals[i], &tempPaths[i], match_coord,GRID_WIDTH,GRID_HEIGHT) != 0) return 1; /* copy out the shortest path data, if we don't do this, it will get overwritten*/ for (j = 0; j < NO_TERMINALS; j++) if (i != j) copy_sPath(&tempPaths[i], &(sPaths[i][j]), (CoordData*)((PathVertex*)terminals[j])->data); } /*--------------------------------------------------------------------------------------------------*/ /* Generate complete distance network ND */ /*--------------------------------------------------------------------------------------------------*/ /* initialize the graph */ graph_init(&ND, match_coord, (void*)mst_vertex_free); /* insert the verticies. Verticies consist of all the terminals */ for (i = 0; i < NO_TERMINALS; i++) { /* allocate space for a MST vertex */ if ((mst_vertex = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) { printf("Error allocating space for mst_vertex\n"); printf("Terminating..\n"); return 1; } /* if it's the first, make it the start. It doesn't matter which one is the start */ if (i == 1) mst_start = mst_vertex; /* set the data */ if ((coord = (CoordData*) malloc(sizeof(CoordData)))==NULL) { printf("gsFH.h : coord mem allocation error\n"); fflush(stdout); exit(1); } coord->x = ((CoordData*)(((PathVertex*)terminals[i])->data))->x; coord->y = ((CoordData*)(((PathVertex*)terminals[i])->data))->y; coord->z = ((CoordData*)(((PathVertex*)terminals[i])->data))->z; mst_vertex->data = coord; /* insert */ if (graph_ins_vertex(&ND, mst_vertex) != 0) { printf("Error inserting vertex into mst_graph\n"); printf("Terminating...\n"); return 1; } } /* now we must insert the edges into the distance network graph ND. We do this by accessing the shortest path lists (sPath) computed in the previous step */ for (i = 0; i < NO_TERMINALS; i++) { int ux,uy,uz; ux = ((CoordData*)((PathVertex*)terminals[i])->data)->x; uy = ((CoordData*)((PathVertex*)terminals[i])->data)->y; uz = ((CoordData*)((PathVertex*)terminals[i])->data)->z; for (j = 0; j < NO_TERMINALS; j++) { int vx,vy,vz; /* shouldn't be an edge from a terminal to itself */ if (i != j) { double weight; CoordData *v1,*v2; int eCode; vx = ((CoordData*)((PathVertex*)terminals[j])->data)->x; vy = ((CoordData*)((PathVertex*)terminals[j])->data)->y; vz = ((CoordData*)((PathVertex*)terminals[j])->data)->z; /* now we must find how far away vx is from vy. we do this by looking for at the head element in sPath[i][j] */ element = list_head(&(sPaths[i][j])); sPath_vertex = list_data(element); weight = ((sPathData*)sPath_vertex)->d; /* allocate an edge */ if ((v1 = (CoordData*) malloc(sizeof(CoordData))) == NULL) { printf("gsFH.h : v1 mem allocation error\n"); fflush(stdout); exit(1); } if ((v2 = (CoordData*) malloc(sizeof(CoordData))) == NULL) { printf("gsFH.h : v2 mem allocation error\n"); fflush(stdout); exit(1); } v1->x = ux; v1->y = uy; v1->z = uz; v2->x = vx; v2->y = vy; v2->z = vz; if ((mst_vertex1 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) { printf("gsFH.h : mst_vertex1 mem allocation error\n"); fflush(stdout); exit(1); } if ((mst_vertex2 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) { printf("gsFH.h : mst_vertex2 mem allocation error\n"); fflush(stdout); exit(1); } mst_vertex1->data =v1; mst_vertex2->data = v2; mst_vertex2->weight = weight; if ((eCode = graph_ins_edge(&ND, mst_vertex1, mst_vertex2)) != 0) { printf("Error inserting edge into ND\n"); printf("graph_ins_edge returned the value %d\n",eCode); return 1; } free(mst_vertex1->data); free(mst_vertex1); }/* endif i!=j */ }/* endfor j */ }/* endfor i */ /*--------------------------------------------------------------------------------------------------*/ /* Copmute TD (Min Span Tree of ND) */ /*--------------------------------------------------------------------------------------------------*/ if (mst(&ND, mst_start,&TD, match_coord) != 0) { printf("Error computing minimum spanning tree\n"); return 1; } /* set leaves */ /* initialize */ for ( element = list_head(&TD); element != NULL; element = list_next(element)) { mst_vertex = list_data(element); mst_vertex->is_leaf = 1; } /* for each node, set the parent is_leaf to 0. Then, all leaves will remain */ for (element = list_head(&TD); element != NULL; element = list_next(element)) { mst_vertex = list_data(element); if (mst_vertex->parent != NULL) mst_vertex->parent->is_leaf = 0; } /*--------------------------------------------------------------------------------------------------*/ /* Find N[TD] */ /*--------------------------------------------------------------------------------------------------*/ graph_init(&NTD,match_coord,(void*)mst_vertex_free); /* for each edge in TD */ for (element = list_head(&TD); element != NULL; element = list_next(element)) { MstVertex *nextVertex; int v,p; p = -1; v = -1; nextVertex = list_data(element); /* if it is not the root */ if (nextVertex->parent != NULL) { int vx,vy,vz,px,py,pz; ListElmt *currentV, *nextV; int done; vx = ((CoordData*)((MstVertex*)nextVertex)->data)->x; vy = ((CoordData*)((MstVertex*)nextVertex)->data)->y; vz = ((CoordData*)((MstVertex*)nextVertex)->data)->z; px = ((CoordData*)(MstVertex*)(nextVertex->parent)->data)->x; py = ((CoordData*)(MstVertex*)(nextVertex->parent)->data)->y; pz = ((CoordData*)(MstVertex*)(nextVertex->parent)->data)->z; /* find terminal index of nextVertex and nextVertex->parent */ for (i = 0; i < NO_TERMINALS; i++) { int tx,ty,tz; tx = ((CoordData*)((PathVertex*)terminals[i])->data)->x; ty = ((CoordData*)((PathVertex*)terminals[i])->data)->y; tz = ((CoordData*)((PathVertex*)terminals[i])->data)->z; if ((tx == vx)&&(ty == vy)&&(tz == vz)) v = i; if ((tx == px)&&(ty == py)&&(tz == pz)) p = i; } /* now, we must step through the list of sPathData elements found in sPaths[p][v]. For each element in the list, we must insert vertices for the vertex and parent, then make an edge with the appropriate weight and insert it */ currentV = list_head(&(sPaths[p][v])); nextV = list_next(currentV); done = 0; while ( !done ) { MstVertex *u,*v, *mst_vertex1, *mst_vertex2; CoordData *uc,*vc; sPathData *currentVData, *nextVData; int cvx,cvy,cvz,nvx,nvy,nvz; double weight; /*---------------------------------------*/ /* insert vertices u and v into NTD */ /*---------------------------------------*/ /* make a vertex for currentV and nextV */ u = (MstVertex*) malloc(sizeof(MstVertex)); v = (MstVertex*) malloc(sizeof(MstVertex)); uc = (CoordData*) malloc(sizeof(CoordData)); vc = (CoordData*) malloc(sizeof(CoordData)); if ((u == NULL)||(uc==NULL)||(v==NULL)||(vc==NULL)) { printf("gsFH.h : error allocating vertex for NTD\n"); fflush(stdout); exit(1); } /* get vertices from the sPaths list */ currentVData = list_data(currentV); nextVData = list_data(nextV); /* get vertex data */ cvx = ((CoordData*)((sPathData*)currentVData)->vertex)->x; cvy = ((CoordData*)((sPathData*)currentVData)->vertex)->y; cvz = ((CoordData*)((sPathData*)currentVData)->vertex)->z; nvx = ((CoordData*)((sPathData*)nextVData)->vertex)->x; nvy = ((CoordData*)((sPathData*)nextVData)->vertex)->y; nvz = ((CoordData*)((sPathData*)nextVData)->vertex)->z; /* set vertex data */ uc->x = cvx; uc->y = cvy; uc->z = cvz; vc->x = nvx; vc->y = nvy; vc->z = nvz; u->data = uc; v->data = vc; /* calculate weight between u and v */ weight = currentVData->d - nextVData->d; /* try and insert u, if it exists, then delete the memory we allocated for it */ if ( graph_ins_vertex(&NTD, u) == 1 ) { free(uc); free(u); } else { /* doesnt' matter which one is the start */ mst_start = u; } /* try and insert v, if it exists, then delete the memorr we allocated for it */ if ( graph_ins_vertex(&NTD, v) == 1) { free(vc); free(v); } /* now the vertices u and v are in the graph. we now have to make an edge for uv */ /* make edge going forward */ if ((uc = (CoordData*)malloc(sizeof(CoordData))) == NULL) { printf("gsFH.h : uc mem allocation error\n"); fflush(stdout); exit(1); } if ((vc = (CoordData*)malloc(sizeof(CoordData))) == NULL) { printf("gsFH.h : vc mem allocation error\n"); fflush(stdout); exit(1); } uc->x = cvx; uc->y = cvy; uc->z = cvz; vc->x = nvx; vc->y = nvy; vc->z = nvz; if ((mst_vertex1 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) { printf("gsFH.h : mst_Vertex1 mem allocation error\n"); fflush(stdout); exit(1); } if ((mst_vertex2 = (MstVertex*)malloc(sizeof(MstVertex))) == NULL) { printf("gsFH.h : mst_vertex2 mem allocation error\n"); fflush(stdout); exit(1); } mst_vertex1->data = uc; mst_vertex2->data = vc; mst_vertex2->weight = weight; /* try and insert, if it exists, free previously allocated mem */ if ( graph_ins_edge(&NTD, mst_vertex1, mst_vertex2) == 1) { free(vc); free(mst_vertex2); } /* free the label */ free(mst_vertex1->data); free(mst_vertex1); /* make edge going backward */ if ((uc = (CoordData*)malloc(sizeof(CoordData))) == NULL) { printf("gsFH.h : uc mem allocation error\n"); fflush(stdout); exit(1); } if ((vc = (CoordData*)malloc(sizeof(CoordData))) == NULL) { printf("gsFH.h : vc mem allocation error\n"); fflush(stdout); exit(1); } uc->x = cvx; uc->y = cvy; uc->z = cvz; vc->x = nvx; vc->y = nvy; vc->z = nvz; if ((mst_vertex1 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) { printf("gsFH.h : mst_Vertex1 mem allocation error\n"); fflush(stdout); exit(1); } if ((mst_vertex2 = (MstVertex*)malloc(sizeof(MstVertex))) == NULL) { printf("gsFH.h : mst_Vertex2 mem allocation error\n"); fflush(stdout); exit(1); } mst_vertex1->data = vc; mst_vertex2->data = uc; mst_vertex2->weight = weight; /* try and insert, if it exists, free previously allocated mem */ if ( graph_ins_edge(&NTD, mst_vertex1, mst_vertex2) == 1) { free(uc); free(mst_vertex2); } /* free the label */ free(mst_vertex1->data); free(mst_vertex1); /* follow pointers */ currentV = list_next(currentV); nextV = list_next(nextV); /* check to see if we're finished */ if (nextV == NULL) done = 1; } } } /*----------------------------------------------------------------------------------------------------------*/ /* Compute T (minimum spanning tree of NTD) */ /*----------------------------------------------------------------------------------------------------------*/ /* call minimum spanning tree subroutine */ if (mst(&NTD, mst_start,&T, match_coord) != 0) { printf("Error computing minimum spanning tree\n"); return 1; } /* set leaves */ for ( element = list_head(&T); element != NULL; element = list_next(element)) { mst_vertex = list_data(element); mst_vertex->is_leaf = 1; } /* for each node, set the parent is_leaf to 0. Then, all leaves will remain */ for (element = list_head(&T); element != NULL; element = list_next(element)) { mst_vertex = list_data(element); if (mst_vertex->parent != NULL) mst_vertex->parent->is_leaf = 0; } /*--------------------------------------------------------------------------------------*/ /* Compute Steiner Tree Sk */ /*--------------------------------------------------------------------------------------*/ isSteiner = 0; /* we remove all leaves that arent' terminals, when all leaves are terminals then we have a Steiner Tree */ while (!isSteiner) { ListElmt *prev; /* assume we have it */ isSteiner = 1; /* check if each leaf is a terminal */ prev = list_head(&T); element = list_next(prev); while (element != NULL) { int mx,my,mz; mst_vertex = list_data(element); mx = ((CoordData*)((MstVertex*)mst_vertex)->data)->x; my = ((CoordData*)((MstVertex*)mst_vertex)->data)->y; mz = ((CoordData*)((MstVertex*)mst_vertex)->data)->z; if (mst_vertex->is_leaf) { int found; found = 0; for (i = 0; i < NO_TERMINALS; i++) { int tx,ty,tz; tx = ((CoordData*)((PathVertex*)terminals[i])->data)->x; ty = ((CoordData*)((PathVertex*)terminals[i])->data)->y; tz = ((CoordData*)((PathVertex*)terminals[i])->data)->z; if ( (tx==mx)&&(ty==my)&&(tz==mz)) found = 1; } /* remove it if we can't find it */ if (!found) { MstVertex *junk; ListElmt *e; isSteiner = 0; /* not done yet */ list_rem_next(&T, prev, (void**)(&junk)); /*reset leaves */ /* initialize */ for ( e = list_head(&T); e != NULL; e = list_next(e)) { mst_vertex = list_data(e); mst_vertex->is_leaf = 1; } /* for each node, set the parent is_leaf to 0. Then, all leaves will remain */ for (e = list_head(&T); e != NULL; e = list_next(e)) { mst_vertex = list_data(e); if (mst_vertex->parent != NULL) mst_vertex->parent->is_leaf = 0; } /* start over at beginning of list */ prev = list_head(&T); element = list_next(prev); } else { prev = list_next(prev); element = list_next(element); } } else { prev = list_next(prev); element = list_next(element); } } } /* we can further eliminate vias that connect to a terminal leaf. These are not neccessary*/ isSteiner = 0; while (!isSteiner) { ListElmt *prev; /* assume we have it */ isSteiner = 1; /* check if each leaf is a terminal */ prev = list_head(&T); element = list_next(prev); while (element != NULL) { int mx,my,mz; mst_vertex = list_data(element); mx = ((CoordData*)((MstVertex*)mst_vertex)->data)->x; my = ((CoordData*)((MstVertex*)mst_vertex)->data)->y; mz = ((CoordData*)((MstVertex*)mst_vertex)->data)->z; if (mst_vertex->is_leaf) { int remove; int px,py; remove = 0; px = ((CoordData*)((MstVertex*)mst_vertex->parent)->data)->x; py = ((CoordData*)((MstVertex*)mst_vertex->parent)->data)->y; if ((px == mx)&&(py == my)) remove = 1; /* remove it if neccessary */ if (remove) { MstVertex *junk; ListElmt *e; isSteiner = 0; /* not done yet */ list_rem_next(&T, prev, (void**)(&junk)); /*reset leaves */ /* initialize */ for ( e = list_head(&T); e != NULL; e = list_next(e)) { mst_vertex = list_data(e); mst_vertex->is_leaf = 1; } /* for each node, set the parent is_leaf to 0. Then, all leaves will remain */ for (e = list_head(&T); e != NULL; e = list_next(e)) { mst_vertex = list_data(e); if (mst_vertex->parent != NULL) mst_vertex->parent->is_leaf = 0; } /* start over at beginning of list */ prev = list_head(&T); element = list_next(prev); } else { prev = list_next(prev); element = list_next(element); } } else { prev = list_next(prev); element = list_next(element); } } } /* get the total cost of the tree */ tree_cost = 0; for (element = list_head(&T); element != NULL; element = list_next(element)) { CoordData *u, *v; mst_vertex = list_data(element); if (( mst_vertex->parent == NULL)) continue; else { double temp; u = (CoordData*)mst_vertex->data; v = (CoordData*)mst_vertex->parent->data; /* look up cost of edge uv */ temp = find_edge_weight(grid_graph,u,v); tree_cost += temp; } } *edge_count_OUT = list_size(&T)-1; if ((*(SteinerTree_OUT) = (int*) malloc(sizeof(int)*(list_size(&T)-1)))==NULL) { printf("gsFH.h : SteinerTree_OUT mem allocation error\n"); fflush(stdout); exit(1); } i = 0; for ( element = list_head(&T); element != NULL; element = list_next(element)) { int vx,vy,vz,px,py,pz; int tx,ty,tz; AdjList *a; ListElmt *e; int edge_index; double edge_weight; mst_vertex = list_data(element); vx = ((CoordData*)mst_vertex->data)->x; vy = ((CoordData*)mst_vertex->data)->y; vz = ((CoordData*)mst_vertex->data)->z; if (mst_vertex->parent != NULL) { px = ((CoordData*)mst_vertex->parent->data)->x; py = ((CoordData*)mst_vertex->parent->data)->y; pz = ((CoordData*)mst_vertex->parent->data)->z; edge_weight = mst_vertex->weight; } else { px = -1; py = -1; pz = -1; } a = (AdjList*)Edge2Adj[vx][vy][vz]; tx = ((CoordData*)((PathVertex*)(a->vertex))->data)->x; ty = ((CoordData*)((PathVertex*)(a->vertex))->data)->y; tz = ((CoordData*)((PathVertex*)(a->vertex))->data)->z; for ( e = list_head(&(a->adjacent)); e != NULL; e = list_next(e) ) { PathVertex *p; p = (PathVertex*)list_data(e); tx = ((CoordData*)p->data)->x; ty = ((CoordData*)p->data)->y; tz = ((CoordData*)p->data)->z; if ((tx == px)&&(ty == py)&&(tz == pz)) { /*found*/ edge_index = p->index; (*SteinerTree_OUT)[i] = edge_index; i++; } } } /*-------------------------------------------------------------------------------------*/ /* Clean Up */ /*-------------------------------------------------------------------------------------*/ /* free our list of temporary paths*/ for (i = 0; i < NO_TERMINALS; i++) list_destroy(&tempPaths[i]); free(tempPaths); /* destroy distance network*/ graph_destroy(&ND); /* deystroy all the shortest path lists*/ for (i = 0; i < NO_TERMINALS; i++) for (j = 0; j < NO_TERMINALS; j++) if ( i != j ) list_destroy(&sPaths[i][j]); /* destroy the pointers to the shortest path lists*/ for (i = 0; i < NO_TERMINALS; i++) free(sPaths[i]); free(sPaths); /* destroy the minimum spanning tree*/ list_destroy(&TD); /* destroy grid spanning tree*/ graph_destroy(&NTD); /* destroy the terminal list*/ for (i = 0; i < NO_TERMINALS; i++) { path_vertex_free(terminals[i]); } free(terminals); /*destroy the steiner tree*/ list_destroy(&T); return 0; }
int tsp(List *vertices, const TspVertex *start, List *tour, int (*match) (const void *key1, const void *key2)) { TspVertex *tsp_vertex, *tsp_start, *selection; ListElmt *element; double minimum, distance, x, y; int found, i; /***************************************************************************** * * * Initialize the list for the tour. * * * *****************************************************************************/ list_init(tour, NULL); /***************************************************************************** * * * Initialize all of the vertices in the graph. * * * *****************************************************************************/ found = 0; for (element = list_head(vertices); element != NULL; element = list_next(element)) { tsp_vertex = list_data(element); if (match(tsp_vertex, start)) { /*********************************************************************** * * * Start the tour at the start vertex. * * * ***********************************************************************/ if (list_ins_next(tour, list_tail(tour), tsp_vertex) != 0) { list_destroy(tour); return -1; } /*********************************************************************** * * * Save the start vertex and its coordinates. * * * ***********************************************************************/ tsp_start = tsp_vertex; x = tsp_vertex->x; y = tsp_vertex->y; /*********************************************************************** * * * Color the start vertex black. * * * ***********************************************************************/ tsp_vertex->color = black; found = 1; } else { /*********************************************************************** * * * Color all other vertices white. * * * ***********************************************************************/ tsp_vertex->color = white; } } /***************************************************************************** * * * Return if the start vertex was not found. * * * *****************************************************************************/ if (!found) { list_destroy(tour); return -1; } /***************************************************************************** * * * Use the nearest-neighbor heuristic to compute the tour. * * * *****************************************************************************/ i = 0; while (i < list_size(vertices) - 1) { /************************************************************************** * * * Select the white vertex closest to the previous vertex in the tour. * * * **************************************************************************/ minimum = DBL_MAX; for (element = list_head(vertices); element != NULL; element = list_next(element)) { tsp_vertex = list_data(element); if (tsp_vertex->color == white) { distance = sqrt(pow(tsp_vertex->x-x,2.0) + pow(tsp_vertex->y-y,2.0)); if (distance < minimum) { minimum = distance; selection = tsp_vertex; } } } /************************************************************************** * * * Save the coordinates of the selected vertex. * * * **************************************************************************/ x = selection->x; y = selection->y; /************************************************************************** * * * Color the selected vertex black. * * * **************************************************************************/ selection->color = black; /************************************************************************** * * * Insert the selected vertex into the tour. * * * **************************************************************************/ if (list_ins_next(tour, list_tail(tour), selection) != 0) { list_destroy(tour); return -1; } /************************************************************************** * * * Prepare to select the next vertex. * * * **************************************************************************/ i++; } /***************************************************************************** * * * Insert the start vertex again to complete the tour. * * * *****************************************************************************/ if (list_ins_next(tour, list_tail(tour), tsp_start) != 0) { list_destroy(tour); return -1; } return 0; }
/*--------------------------------------------------------------*/ int copy_sPath(List *path, List *sPath, CoordData *start) { ListElmt *element; sPathData *newElement; PathVertex *path_vertex, *v, *p; int done; list_init(sPath, (void*)sPath_vertex_free); v = NULL; /* find start vertex in path */ for ( element = list_head(path); element != NULL; element = list_next(element)) { int sx,sy,sz,px,py,pz; path_vertex = list_data(element); px = ((CoordData*)((PathVertex*)path_vertex)->data)->x; py = ((CoordData*)((PathVertex*)path_vertex)->data)->y; pz = ((CoordData*)((PathVertex*)path_vertex)->data)->z; sx = start->x; sy = start->y; sz = start->z; /* if found, set a pointer and skip to end of list */ if ((px==sx)&&(py==sy)&&(pz==sz)) { v = path_vertex; element = list_tail(path); } } p = v->parent; done = 0; /* follow v back to root (when parent == NULL) */ while ( !done ) { CoordData *vCoord, *pCoord; /* allocate some memory */ newElement = (sPathData*) malloc(sizeof(sPathData)); vCoord = (CoordData*) malloc(sizeof(CoordData)); pCoord = (CoordData*) malloc(sizeof(CoordData)); if ((newElement == NULL)||(vCoord == NULL)||(pCoord == NULL)) { printf("helper.c : mem allocation error\n"); fflush(stdout); exit(1); } /* set current vertex coords */ vCoord->x = ((CoordData*)((PathVertex*)v)->data)->x; vCoord->y = ((CoordData*)((PathVertex*)v)->data)->y; vCoord->z = ((CoordData*)((PathVertex*)v)->data)->z; /* set parent vertex coords */ pCoord->x = ((CoordData*)((PathVertex*)p)->data)->x; pCoord->y = ((CoordData*)((PathVertex*)p)->data)->y; pCoord->z = ((CoordData*)((PathVertex*)p)->data)->z; /* set the new element to list */ newElement->vertex = vCoord; newElement->parent = pCoord; newElement->d = ((PathVertex*)v)->d; /* insert the element into the list */ if (list_ins_next(sPath, list_tail(sPath), newElement) != 0) { printf("Problem inserting into sPath!\n"); list_destroy(sPath); return -1; } /* next vertex */ if (p->parent == NULL) { done = 1; /*insert one more element starting with parent */ newElement = (sPathData*) malloc(sizeof(sPathData)); vCoord = (CoordData*) malloc(sizeof(CoordData)); if ((newElement==NULL)||(vCoord==NULL)) { printf("helper.c : memory allocation error\n"); fflush(stdout); exit(1); } vCoord->x = ((CoordData*)((PathVertex*)p)->data)->x; vCoord->y = ((CoordData*)((PathVertex*)p)->data)->y; vCoord->z = ((CoordData*)((PathVertex*)p)->data)->z; newElement->vertex = vCoord; newElement->parent = NULL; newElement->d = 0; if (list_ins_next(sPath, list_tail(sPath), newElement) != 0){ printf("Problem inserting into sPath!\n"); list_destroy(sPath); return -1; } } else { v = p; p = p->parent; } } return 0; }
int stack_push(Stack *stack, const void *data) { //push the data onto the stack/list top/head return list_ins_next(stack, NULL, data); }
int set_union(Set * setu, const Set * set1, const Set * set2) { ListElmt *member; void *data; /***************************************************************************** * Initialize the set for the union. * *****************************************************************************/ set_init(setu, set1->match, NULL); /***************************************************************************** * Insert the members of the first set. * *****************************************************************************/ for (member = list_head(set1); member != NULL; member = list_next(member)) { data = list_data(member); if (list_ins_next(setu, list_tail(setu), data) != 0) { set_destroy(setu); return -1; } } /***************************************************************************** * Insert the members of the second set. * *****************************************************************************/ for (member = list_head(set2); member != NULL; member = list_next(member)) { if (set_is_member(set1, list_data(member))) { /*********************************************************************** * Do not allow the insertion of duplicates. * ***********************************************************************/ continue; } else { data = list_data(member); if (list_ins_next(setu, list_tail(setu), data) != 0) { set_destroy(setu); return -1; } } } return 0; }