static void updateNeighbors(HWND hwnd) { // get selected screen name or empty string if no selection CString screen; HWND child = getItem(hwnd, IDC_MAIN_SERVER_SCREENS_LIST); LRESULT index = SendMessage(child, LB_GETCURSEL, 0, 0); if (index != LB_ERR) { screen = ARG->m_screens[index]; } // set neighbor combo boxes child = getItem(hwnd, IDC_MAIN_SERVER_LEFT_COMBO); updateNeighbor(child, screen, kLeft); child = getItem(hwnd, IDC_MAIN_SERVER_RIGHT_COMBO); updateNeighbor(child, screen, kRight); child = getItem(hwnd, IDC_MAIN_SERVER_TOP_COMBO); updateNeighbor(child, screen, kTop); child = getItem(hwnd, IDC_MAIN_SERVER_BOTTOM_COMBO); updateNeighbor(child, screen, kBottom); }
/** colors the positive weighted nodes of a given set of nodes V with the lowest possible number of colors and * finds a clique in the graph induced by V, an upper bound and an apriori bound for further branching steps */ TCLIQUE_WEIGHT tcliqueColoring( TCLIQUE_GETNNODES((*getnnodes)), /**< user function to get the number of nodes */ TCLIQUE_GETWEIGHTS((*getweights)), /**< user function to get the node weights */ TCLIQUE_SELECTADJNODES((*selectadjnodes)), /**< user function to select adjacent edges */ TCLIQUE_GRAPH* tcliquegraph, /**< pointer to graph data structure */ BMS_CHKMEM* mem, /**< block memory */ int* buffer, /**< buffer of size nnodes */ int* V, /**< non-zero weighted nodes for branching */ int nV, /**< number of non-zero weighted nodes for branching */ NBC* gsd, /**< neighbor color information of all nodes */ TCLIQUE_Bool* iscolored, /**< coloring status of all nodes */ TCLIQUE_WEIGHT* apbound, /**< pointer to store apriori bound of nodes for branching */ int* clique, /**< buffer for storing the clique */ int* nclique, /**< pointer to store number of nodes in the clique */ TCLIQUE_WEIGHT* weightclique /**< pointer to store the weight of the clique */ ) { const TCLIQUE_WEIGHT* weights; TCLIQUE_WEIGHT maxsatdegree; TCLIQUE_WEIGHT range; TCLIQUE_Bool growclique; int node; int nodeVindex; int i; int j; LIST_ITV* colorinterval; LIST_ITV nwcitv; LIST_ITV* pnc; LIST_ITV* lcitv; LIST_ITV* item; LIST_ITV* tmpitem; int* workclique; int* currentclique; int ncurrentclique; int weightcurrentclique; int* Vadj; int nVadj; int adjidx; assert(getnnodes != NULL); assert(getweights != NULL); assert(selectadjnodes != NULL); assert(buffer != NULL); assert(V != NULL); assert(nV > 0); assert(clique != NULL); assert(nclique != NULL); assert(weightclique != NULL); assert(gsd != NULL); assert(iscolored != NULL); weights = getweights(tcliquegraph); assert(weights != NULL); /* initialize maximum weight clique found so far */ growclique = TRUE; *nclique = 0; *weightclique = 0; /* get node of V with maximum weight */ nodeVindex = getMaxWeightIndex(getnnodes, getweights, tcliquegraph, V, nV); node = V[nodeVindex]; assert(0 <= node && node < getnnodes(tcliquegraph)); range = weights[node]; assert(range > 0); /* set up data structures for coloring */ BMSclearMemoryArray(iscolored, nV); /* new-memory */ BMSclearMemoryArray(gsd, nV); /* new-memory */ iscolored[nodeVindex] = TRUE; /* color the first node */ debugMessage("---------------coloring-----------------\n"); debugMessage("1. node choosen: vindex=%d, vertex=%d, satdeg=%d, range=%d)\n", nodeVindex, node, gsd[nodeVindex].satdeg, range); /* set apriori bound: apbound(v_i) = satdeg(v_i) + weight(v_i) */ apbound[nodeVindex] = range; assert(apbound[nodeVindex] > 0); /* update maximum saturation degree: maxsatdeg = max { satdeg(v_i) + weight(v_i) | v_i in V } */ maxsatdegree = range; debugMessage("-> updated neighbors:\n"); /* set neighbor color of the adjacent nodes of node */ Vadj = buffer; nVadj = selectadjnodes(tcliquegraph, node, V, nV, Vadj); for( i = 0, adjidx = 0; i < nV && adjidx < nVadj; ++i ) { assert(V[i] <= Vadj[adjidx]); /* Vadj is a subset of V */ if( V[i] == Vadj[adjidx] ) { /* node is adjacent to itself, but we do not need to color it again */ if( i == nodeVindex ) { /* go to the next node in Vadj */ adjidx++; continue; } debugMessage(" nodeVindex=%d, node=%d, weight=%d, satdegold=%d -> ", i, V[i], weights[V[i]], gsd[i].satdeg); /* sets satdeg for adjacent node */ gsd[i].satdeg = range; /* creates new color interval [1,range] */ ALLOC_ABORT( BMSallocChunkMemory(mem, &colorinterval) ); colorinterval->next = NULL; colorinterval->itv.inf = 1; colorinterval->itv.sup = range; /* colorinterval is the first added element of the list of neighborcolors of the adjacent node */ gsd[i].lcitv = colorinterval; /* go to the next node in Vadj */ adjidx++; debugPrintf("satdegnew=%d, nbc=[%d,%d]\n", gsd[i].satdeg, gsd[i].lcitv->itv.inf, gsd[i].lcitv->itv.sup); } } /* set up data structures for the current clique */ ALLOC_ABORT( BMSallocMemoryArray(¤tclique, nV) ); workclique = clique; /* add node to the current clique */ currentclique[0] = node; ncurrentclique = 1; weightcurrentclique = range; /* color all other nodes of V */ for( i = 0 ; i < nV-1; i++ ) { assert((workclique == clique) != (currentclique == clique)); /* selects the next uncolored node to color */ nodeVindex = getMaxSatdegIndex(V, nV, gsd, iscolored, weights); if( nodeVindex == -1 ) /* no uncolored nodes left */ break; node = V[nodeVindex]; assert(0 <= node && node < getnnodes(tcliquegraph)); range = weights[node]; assert(range > 0); iscolored[nodeVindex] = TRUE; debugMessage("%d. node choosen: vindex=%d, vertex=%d, satdeg=%d, range=%d, growclique=%u, weight=%d)\n", i+2, nodeVindex, node, gsd[nodeVindex].satdeg, range, growclique, weightcurrentclique); /* set apriori bound: apbound(v_i) = satdeg(v_i) + weight(v_i) */ apbound[nodeVindex] = gsd[nodeVindex].satdeg + range; assert(apbound[nodeVindex] > 0); /* update maximum saturation degree: maxsatdeg = max { satdeg(v_i) + weight(v_i) | v_i in V } */ if( maxsatdegree < apbound[nodeVindex] ) maxsatdegree = apbound[nodeVindex]; /* update clique */ if( gsd[nodeVindex].satdeg == 0 ) { /* current node is not adjacent to nodes of current clique, * i.e. current clique can not be increased */ debugMessage("current node not adjacend to current clique (weight:%d) -> starting new clique\n", weightcurrentclique); /* check, if weight of current clique is larger than weight of maximum weight clique found so far */ if( weightcurrentclique > *weightclique ) { int* tmp; /* update maximum weight clique found so far */ assert((workclique == clique) != (currentclique == clique)); tmp = workclique; *weightclique = weightcurrentclique; *nclique = ncurrentclique; workclique = currentclique; currentclique = tmp; assert((workclique == clique) != (currentclique == clique)); } weightcurrentclique = 0; ncurrentclique = 0; growclique = TRUE; } if( growclique ) { /* check, if the current node is still adjacent to all nodes in the clique */ if( gsd[nodeVindex].satdeg == weightcurrentclique ) { assert(ncurrentclique < nV); currentclique[ncurrentclique] = node; ncurrentclique++; weightcurrentclique += range; #ifdef TCLIQUE_DEBUG { int k; debugMessage("current clique (size:%d, weight:%d):", ncurrentclique, weightcurrentclique); for( k = 0; k < ncurrentclique; ++k ) debugPrintf(" %d", currentclique[k]); debugPrintf("\n"); } #endif } else { debugMessage("node satdeg: %d, clique weight: %d -> stop growing clique\n", gsd[nodeVindex].satdeg, weightcurrentclique); growclique = FALSE; } } /* search for fitting color intervals for current node */ pnc = &nwcitv; if( gsd[nodeVindex].lcitv == NULL ) { /* current node has no colored neighbors yet: create new color interval [1,range] */ ALLOC_ABORT( BMSallocChunkMemory(mem, &colorinterval) ); colorinterval->next = NULL; colorinterval->itv.inf = 1; colorinterval->itv.sup = range; /* add the new colorinterval [1, range] to the list of chosen colorintervals for node */ pnc->next = colorinterval; pnc = colorinterval; } else { int tocolor; int dif; /* current node has colored neighbors */ tocolor = range; lcitv = gsd[nodeVindex].lcitv; /* check, if first neighbor color interval [inf, sup] has inf > 1 */ if( lcitv->itv.inf != 1 ) { /* create new interval [1, min{range, inf}] */ dif = lcitv->itv.inf - 1 ; if( dif > tocolor ) dif = tocolor; ALLOC_ABORT( BMSallocChunkMemory(mem, &colorinterval) ); colorinterval->next = NULL; colorinterval->itv.inf = 1; colorinterval->itv.sup = dif; tocolor -= dif; pnc->next = colorinterval; pnc = colorinterval; } /* as long as node is not colored with all colors, create new color interval by filling * the gaps in the existing neighbor color intervals of the neighbors of node */ while( tocolor > 0 ) { dif = tocolor; ALLOC_ABORT( BMSallocChunkMemory(mem, &colorinterval) ); colorinterval->next = NULL; colorinterval->itv.inf = lcitv->itv.sup+1; if( lcitv->next != NULL ) { int min; min = lcitv->next->itv.inf - lcitv->itv.sup - 1; if( dif > min ) dif = min; lcitv = lcitv->next; } colorinterval->itv.sup = colorinterval->itv.inf + dif - 1; tocolor -= dif; pnc->next = colorinterval; pnc = colorinterval; } } debugMessage("-> updated neighbors:\n"); /* update saturation degree and neighbor colorintervals of all neighbors of node */ Vadj = buffer; nVadj = selectadjnodes(tcliquegraph, node, V, nV, Vadj); for( j = 0, adjidx = 0; j < nV && adjidx < nVadj; ++j ) { assert(V[j] <= Vadj[adjidx]); /* Vadj is a subset of V */ if( V[j] == Vadj[adjidx] ) { if( !iscolored[j] ) { debugMessage(" nodeVindex=%d, node=%d, weight=%d, satdegold=%d -> ", j, V[j], weights[V[j]], gsd[j].satdeg); updateNeighbor(mem, &gsd[j], nwcitv.next); debugPrintf("satdegnew=%d, nbc=[%d,%d]\n", gsd[j].satdeg, gsd[j].lcitv->itv.inf, gsd[j].lcitv->itv.sup); } /* go to the next node in Vadj */ adjidx++; } } /* free data structure of created colorintervals */ item = nwcitv.next; while( item != NULL ) { tmpitem = item->next; BMSfreeChunkMemory(mem, &item); item = tmpitem; } /* free data structure of neighbor colorinterval of node just colored */ item = gsd[nodeVindex].lcitv; while( item != NULL ) { tmpitem = item->next; BMSfreeChunkMemory(mem, &item); item = tmpitem; } } assert((workclique == clique) != (currentclique == clique)); /* update maximum weight clique found so far */ if( weightcurrentclique > *weightclique ) { int* tmp; tmp = workclique; *weightclique = weightcurrentclique; *nclique = ncurrentclique; workclique = currentclique; currentclique = tmp; } assert((workclique == clique) != (currentclique == clique)); /* move the found clique to the provided clique pointer, if it is not the memory array */ if( workclique != clique ) { assert(clique == currentclique); assert(*nclique <= nV); BMScopyMemoryArray(clique, workclique, *nclique); currentclique = workclique; } /* free data structures */ BMSfreeMemoryArray(¤tclique); /* clear chunk memory */ BMSclearChunkMemory(mem); debugMessage("------------coloringend-----------------\n"); return maxsatdegree; }