/* * Merge the classes of r1 and r2 * - both r1 and r2 must be free roots and have compatible types * - if both r1 and r2 are boolean, they may have arbitrary polarity * This adds either the substitution [r1 := r2] or [r2 := r1] */ void intern_tbl_merge_classes(intern_tbl_t *tbl, term_t r1, term_t r2) { assert(intern_tbl_root_is_free(tbl, r1) && intern_tbl_root_is_free(tbl, r2)); if (! intern_tbl_term_present(tbl, r1)) { partition_add(tbl, r1); } if (! intern_tbl_term_present(tbl, r2)) { partition_add(tbl, r2); } partition_merge(tbl, r1, r2); }
/** * Search the graph for fragments and integrate them into partitions */ void greedyBFS_fragment_scan(list_graph* graph, partition* parray, int pnum){ int i = 0; //Search for unpartitioned nodes for (i = 0; i < graph->size; i++){ if (graph->vertex[i].color == 0){ edge* head = graph->vertex[i].edge_list; int attached = 0; //Attempt to find a nearby partition to attach to while(head != NULL){ if (graph->vertex[head->id].color != 0){ partition_add(&parray[graph->vertex[head->id].partition], i, head->wgt); graph->vertex[i].partition = graph->vertex[head->id].partition; graph->vertex[i].color = 2; attached = 1; } head = head->next; } //Place the vertex in the partition with highest available space if (!attached){ int minwgt = parray[0].wgt; int sp = 0; int j; for (j = 1; j < pnum; j++){ if (parray[j].wgt < minwgt){ minwgt = parray[i].wgt; sp = j; } } partition_add(&parray[sp], i, 0); graph->vertex[i].partition = sp; graph->vertex[i].color = 2; } } } }
/* * Add the substitution [r1 := r2] to the table. * The substitution must be valid. */ void intern_tbl_add_subst(intern_tbl_t *tbl, term_t r1, term_t r2) { assert(intern_tbl_root_is_free(tbl, r1)); if (! intern_tbl_term_present(tbl, r1)) { partition_add(tbl, r1); } if (! intern_tbl_term_present(tbl, r2)) { partition_add_frozen(tbl, r2); } partition_merge(tbl, r1, r2); }
/** * Expand a partition */ list* greedyBFS_grow(list_graph* graph, partition* p, int source, int dest){ //Prepare the queue list* q = (list*) malloc ( sizeof(list)); list_init(q); //Get the Adjacency list of the vertex if (graph->vertex[dest].color == 2){ //Someone else already took our node return NULL; } //Check for constraints if(list_contains(&(p->constraints), dest)){ return NULL; } //Put the node in the partition graph->vertex[dest].color = 2; partition_add(p, dest, 0); //Add the new constraints to the partition partition_constraint_add(p, &(graph->vertex[dest].constraints)); //Check the adjacency list edge* head = graph->vertex[dest].edge_list; while(head != NULL){ if(graph->vertex[head->id].color < 2){ //Color Grey graph->vertex[head->id].color = 1; //Enqueue list_insert(q, head->id); } head = head->next; } return q; }
/** * Create an array of unbalanced partitions according to a distribution vector */ partition* greedyBFS_helper(list_graph* graph, int pnum, int* seeds){ //Allocate space for the data structures partition* parray = (partition *) malloc(sizeof(partition)*pnum); list* dest_list = (list *) malloc(sizeof(list)*pnum); list* src_list = (list *) malloc(sizeof(list)*pnum); int* src = (int*) malloc(sizeof(int)*pnum); int* dest = (int*) malloc(sizeof(int)*pnum); //Initialize the data structures and perform the initial discovery process int i, tmp; int maxtmp = -1; int maxi = -1; /** * Initialization */ for ( i = 0; i < pnum; i++){ //Mark seeds as partitioned graph->vertex[seeds[i]].color = 2; //Initialize and insert partition_init(&parray[i], graph->id, i); partition_add(&parray[i], seeds[i], 0); //Populate the lists with starting nodes and constraints list_init(&src_list[i]); list_init(&dest_list[i]); partition_constraint_add(&parray[i], &(graph->vertex[seeds[i]].constraints)); greedyBFS_discovery(graph, &dest_list[i], &parray[i], seeds[i]); //Find the best seed to start with tmp = greedyBFS_peek(graph, &parray[i], seeds[i]); if (tmp > maxtmp){ maxi = i; maxtmp = tmp; } //Set initial src and dst src[i] = seeds[i]; dest[i] = list_pop(&dest_list[i]); list_insert(&src_list[i], dest[i]); } /** * Partitioning */ while (maxtmp != -1){ printf("[%d]->[%d]:[%d]\n", src[maxi], dest[maxi], maxi); //Grow the partition list* l = greedyBFS_grow(graph, &parray[maxi], src[maxi], dest[maxi]); //Insert new data into the queue int pop = list_pop(l); while (pop != -1){ list_insert(&dest_list[maxi], pop); pop = list_pop(l); } //update src and dest if needed dest[maxi] = list_pop(&dest_list[maxi]); if (dest[maxi] >= 0) list_insert(&src_list[maxi], dest[maxi]); if (dest[maxi] != -1){ while(greedyBFS_peek(graph, &parray[maxi], src[maxi]) == -1){ src[maxi] = list_pop(&src_list[maxi]); if(src[maxi] == -1) break; } } //Find the new best partition and update src and dest if needed maxtmp = -1; for ( i = 0; i < pnum; i++){ if (src[i] == -1) tmp = -1; else tmp = greedyBFS_peek(graph, &parray[i], src[i]); if (tmp > maxtmp){ maxi = i; maxtmp = tmp; } } } /** * Fragments */ /*int alloc = graph->wgt; greedyBFS_grow(graph, &parray[i], *seeds++, alloc);*/ //greedyBFS_fragment_scan(graph, parray, pnum); /** * Cleanup */ return parray; }
int main() { uint32_t i; int32_t x, y, rx, ry; init_partition(&partition, 0); printf("\n*** Initial partition ***\n"); print_partition_details(&partition); for (i=0; i<40; i++) { x = random() % N; printf("--- testing %"PRId32" ---\n", x); y = partition_find(&partition, x); if (y < 0) { printf("item %"PRId32" not present; adding it\n", x); partition_add(&partition, x); } else { printf("root[%"PRId32"] = %"PRId32"\n", x, y); } } printf("\n*** Partition ***\n"); print_partition_details(&partition); printf("\n"); print_partition(&partition); printf("\n"); for (x=0; x<N; x++) { aux[x] = partition_find(&partition, x); } for (i=1; i<10; i++) { do { x = random() % N; } while (aux[x] < 0); do { y = random() % N; } while (x == y || aux[y] < 0); x = partition_find(&partition, x); y = partition_find(&partition, y); if (x != y) { printf("--- Merging %"PRId32" and %"PRId32" ---\n", x, y); partition_merge(&partition, x, y); } } printf("\n"); print_partition(&partition); reset_partition(&partition); for (i=0; i<100; i++) { x = random() % 300; rx = partition_find(&partition, x); if (rx < 0) { partition_add(&partition, x); rx = x; } y = random() % 300; ry = partition_find(&partition, y); if (ry < 0) { partition_add(&partition, y); ry = y; } if (rx != ry) { partition_merge(&partition, rx, ry); } } printf("\n\n"); print_partition(&partition); delete_partition(&partition); return 0; }