}
}
-#ifdef UNUSED
-/* balanceLayers:
- * The following is the layer balancing heuristic.
- * Balance the widths of the layers as much as possible.
- * It's no longer used.
- */
-static void balanceLayers(graph_t * g)
-{
- int maxLayerIndex, nextLayerIndex, i;
- double maxWidth, w;
-
- //get the max width layer number
-
- for (i = 0; i < nLayers; i++) {
- if (layerWidthInfo[sortedLayerIndex[i]].nNodeGroupsInLayer <= 1
- ||
- layerWidthInfo[sortedLayerIndex[i]].layerNumber + 1 == nLayers)
- continue;
- else {
- maxLayerIndex = sortedLayerIndex[i];
- maxWidth = layerWidthInfo[maxLayerIndex].width;
- printf("Balancing: maxLayerIndex = %d\n", maxLayerIndex);
- break;
- }
- }
-
- if (i == nLayers)
- return; //reduction of layerwidth is not possible.
-
- //balancing ~~ packing by node demotion
- nextLayerIndex = -1;
- for (i = 0; i < nLayers; i++) {
- if (layerWidthInfo[i].layerNumber ==
- layerWidthInfo[maxLayerIndex].layerNumber + 1) {
- nextLayerIndex = i;
- }
- }
-
- if (nextLayerIndex > -1) {
- //if (layerWidthInfo[nextLayerIndex].width <= 0.5*layerWidthInfo[maxLayerIndex].width)
- //{
- int changed = 0;
- w = 0;
-
- //demote nodes to the next layer
- for (i = 0; i < layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer;
- i++) {
- if (layerWidthInfo[maxLayerIndex].removed[i])
- continue;
-
- if (!checkHorizontalEdge
- (g, layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i],
- nextLayerIndex)
- && layerWidthInfo[nextLayerIndex].width
- /*+ (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width */
- <= layerWidthInfo[maxLayerIndex].width
- /*- (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width*/
- ) {
- w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->
- width;
- changed++;
-
- int j;
- nodeGroup_t *ng =
- layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
-
- layerWidthInfo[maxLayerIndex].removed[i] = 1;
- layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
- layerWidthInfo[maxLayerIndex].width -= (ng->width);
- layerWidthInfo[maxLayerIndex].nDummyNodes++;
- for (j = 0; j < ng->nNodes; j++)
- ND_rank(ng->nodes[j])++;
-
-
- layerWidthInfo[nextLayerIndex].
- nodeGroupsInLayer[layerWidthInfo[nextLayerIndex].
- nNodeGroupsInLayer] = ng;
- layerWidthInfo[nextLayerIndex].
- removed[layerWidthInfo[nextLayerIndex].
- nNodeGroupsInLayer] = 0;
- layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer++;
- layerWidthInfo[nextLayerIndex].width +=
- (ng->width + GD_nodesep(g));
- }
-
- }
-
- if (changed) {
- //printf("Demoted %d nodes\n", changed);
- return;
- }
- //}
- }
-}
-
-/* applyPacking:
- * The following is the initial packing heuristic
- * It's no longer used.
- */
-static void applyPacking(graph_t * g, double targetAR)
-{
- int i;
-
- sortedLayerIndex = N_NEW(agnnodes(g), int);
-
- for (i = 0; i < agnnodes(g); i++) {
- sortedLayerIndex[i] = i;
- }
-
-
- node_t *v;
-
- for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
- //printf("%s, rank = %d, ranktype = %d\n", agnameof(v), ND_rank(v), ND_ranktype(v));
- }
-
- //GD_nodesep(g) = 0.25;
- //GD_ranksep(g) = 0.25;
- ////////////////////
- //printf("Nodesep = %d, Ranksep = %d\n",GD_nodesep(g), GD_ranksep(g));
-
-
- for (i = 0; i < 1; i++) {
- //printf("iteration = %d\n----------------------\n", i);
- for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
- //printf("%s rank = %d\n", agnameof(v), ND_rank(v));
- }
-
- computeLayerWidths(g);
- sortLayers(g);
- reduceMaxWidth(g);
-
- //printf("====================\n");
- }
-
-
- int k;
-
- for (k = 0; k < nLayers - 1; k++) {
- int cnt = 0, tg;
- if (layerWidthInfo[k].nNodeGroupsInLayer > 7) {
-
- cnt = 0;
- tg = layerWidthInfo[k].nNodeGroupsInLayer - 7;
-
- for (i = layerWidthInfo[k].nNodeGroupsInLayer - 1; i >= 0; i--) {
-
- if (layerWidthInfo[k].removed[i])
- continue;
-
- int j;
- nodeGroup_t *ng = layerWidthInfo[k].nodeGroupsInLayer[i];
-
-
- layerWidthInfo[k].removed[i] = 1;
- layerWidthInfo[k].nNodeGroupsInLayer--;
- layerWidthInfo[k].nDummyNodes++;
- layerWidthInfo[k].width -=
- (ng->width * DPI + GD_nodesep(g));
- for (j = 0; j < ng->nNodes; j++)
- ND_rank(ng->nodes[j])++;
-
- //create new layer
- layerWidthInfo[k +
- 1].nodeGroupsInLayer[layerWidthInfo[k +
- 1].
- nNodeGroupsInLayer] =
- ng;
- layerWidthInfo[k + 1].nNodeGroupsInLayer++;
- //layerWidthInfo[k+1].layerNumber = ND_rank(ng->nodes[0]);
-
- //layerWidthInfo[k+1].width += ( ng->width*DPI + (layerWidthInfo[nLayers].nNodeGroupsInLayer > 1) * GD_nodesep(g) ); // just add the node widths now.
-
- cnt++;
-
- if (cnt == tg)
- break;
-
- }
- }
- }
-
- //calcualte the max width
- int maxW = 0;
- int nNodeG = 0, l, nDummy = 0;
- int index;
-
- for (k = 0; k < nLayers; k++) {
- //printf("Layer#=%d, #dumNd=%d, width=%0.1lf, node=%s\n", layerWidthInfo[k].layerNumber, layerWidthInfo[k].nDummyNodes, layerWidthInfo[k].width,
- // agnameof(layerWidthInfo[k].nodeGroupsInLayer[0]->nodes[0]));
- if (layerWidthInfo[k].width > maxW) // && layerWidthInfo[k].nNodeGroupsInLayer > 0)
- {
- maxW = layerWidthInfo[k].width;
- nNodeG = layerWidthInfo[k].nNodeGroupsInLayer;
- l = layerWidthInfo[k].layerNumber;
- nDummy = layerWidthInfo[k].nDummyNodes;
- index = k;
- }
- }
- //printf("Ht=%d, MxW=%d, #ndGr=%d, #dumNd=%d, lyr#=%d, 1stNd=%s\n", (nLayers-1)*DPI, maxW, nNodeG, nDummy, l, agnameof(layerWidthInfo[index].nodeGroupsInLayer[0]->nodes[0]));
-
- // printf("Finally...\n------------------\n");
- for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
- //printf("%s, rank = %d, ranktype = %d\n", agnameof(v, ND_rank(v), ND_ranktype(v));
- }
-
-}
-#endif
-
/* applyPacking2:
* The following is the packing heuristic for wide layout.
*/
}
-#ifdef UNUSED
-/* applyPacking4:
- * The following is the packing heuristic for wide layout.
- * It's used with Nikolov-Healy healy heuristic.
- */
-void applyPacking4(graph_t * g)
-{
- int i;
-
- sortedLayerIndex = N_NEW(agnnodes(g), int);
-
- for (i = 0; i < agnnodes(g); i++) {
- sortedLayerIndex[i] = i;
- }
-
-
- for (i = 0; i < 1; i++) {
- /* printf("iteration = %d\n----------------------\n", i);
- for (v = agfstnode(g); v; v = agnxtnode(g,v))
- {
- printf("%s rank = %d\n", agnameof(v), ND_rank(v));
- }
- */
-
-
- computeLayerWidths(g);
- sortLayers(g);
- reduceMaxWidth2(g);
- //printf("====================\n");
- }
-}
-
-/*
- * NOCOLOV & HEALY'S NODE PROMOTION HEURISTIC
- */
-
-/****************************************************************
- * This data structure is needed for backing up node information
- * during node promotion
- ****************************************************************/
-typedef struct myNodeInfo_t {
- int indegree;
- int outdegree;
- int rank;
- Agnode_t *node;
-} myNodeInfo_t;
-
-myNodeInfo_t *myNodeInfo;
-
-
-/* getMaxLevelNumber:
- * return the maximum level number assigned
- */
-int getMaxLevelNumber(graph_t * g)
-{
- int max;
- Agnode_t *n;
-
- max = ND_rank(agfstnode(g));
-
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- if (ND_rank(n) > max)
- max = ND_rank(n);
- }
-
- return max;
-}
-
-/* countDummyDiff:
- * return the difference in the count of dummy nodes before
- * and after promoting the node v
- */
-static int countDummyDiff(graph_t * g, Agnode_t * v, int max)
-{
- int dummydiff = 0;
- Agedge_t *e;
- Agnode_t *u;
- int maxR = 0;
- int j;
-
- for (j = 0; j < ND_in(v).size; j++) {
- e = ND_in(v).list[j];
- u = agtail(e);
-
- if (myNodeInfo[ND_id(u)].rank == myNodeInfo[ND_id(v)].rank + 1) {
- dummydiff += countDummyDiff(g, u, max);
- }
- }
-
- if (myNodeInfo[ND_id(v)].rank + 1 < max
- || (ND_in(v).size == 0 && myNodeInfo[ND_id(v)].rank + 1 <= max))
- myNodeInfo[ND_id(v)].rank += 1;
-
- dummydiff = dummydiff - ND_in(v).size + ND_out(v).size;
-
-
- return dummydiff;
-}
-
-/* applyPromotionHeuristic:
- * Node Promotion Heuristic
- * by Nikolov and Healy
- */
-static void applyPromotionHeuristic(graph_t * g)
-{
- graph_t graphBkup = *g;
- Agnode_t *v;
- int promotions;
-
- int max = getMaxLevelNumber(g);
- int count = 0;
- int nNodes = agnnodes(g);
- int i, j;
-
- myNodeInfo = N_NEW(nNodes, myNodeInfo_t);
- myNodeInfo_t *myNodeInfoBak = N_NEW(nNodes, myNodeInfo_t);
-
- for (v = agfstnode(g), i = 0; v; v = agnxtnode(g, v), i++) {
- myNodeInfo[i].indegree = ND_in(v).size;
- myNodeInfo[i].outdegree = ND_out(v).size;
- myNodeInfo[i].rank = ND_rank(v);
- myNodeInfo[i].node = v;
- ND_id(v) = i;
-
- myNodeInfoBak[i] = myNodeInfo[i];
- }
-
- do {
- promotions = 0;
-
- for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
- if (ND_in(v).size > 0) {
- if (countDummyDiff(g, v, max) <= 0) {
- promotions++;
-
- for (j = 0; j < nNodes; j++) {
- myNodeInfoBak[j] = myNodeInfo[j];
- }
-
- } else {
- for (j = 0; j < nNodes; j++) {
- myNodeInfo[j] = myNodeInfoBak[j];
- }
- }
- }
- }
- count++;
- } while (count < max);
-
- for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
- ND_rank(v) = myNodeInfo[ND_id(v)].rank;
- }
-}
-
-/*
- * LONGEST PATH ALGORITHM
- */
-
-/* allNeighborsAreBelow:
- * Return 1 if all the neighbors of n already ranked, else 0
- */
-static int allNeighborsAreBelow(Agnode_t * n)
-{
- Agedge_t *e;
- /* graph_t *g = agraphof(n); */
- int i;
-
- //for (e = agfstout(g,n); e; e = agnxtout(g,e))
- for (i = 0; i < ND_out(n).size; i++) {
- e = ND_out(n).list[i];
- if (ED_edge_type(e) == VIRTUAL) {
- if (ED_to_orig(e) != NULL)
- e = ED_to_orig(e);
- else if (ND_node_type(aghead(e)) == VIRTUAL)
- continue;
- }
-
- if (ND_pinned(aghead(e)) != 2) //neighbor of n is not below
- {
- return 0;
- }
- }
-
- return 1;
-}
-
-/* reverseLevelNumbers:
- * In Nikolov and Healy ranking, bottom layer ranking is 0 and
- * top layer ranking is the maximum.
- * Graphviz does the opposite.
- * This function does the reversing from Nikolov to Graphviz.
- */
-static void reverseLevelNumbers(graph_t * g)
-{
- Agnode_t *n;
- int max;
-
- max = getMaxLevelNumber(g);
-
- //printf("max = %d\n", max);
-
- //return;
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- ND_rank(n) = max - ND_rank(n);
- }
-}
-
-/* doSameRank:
- * Maintain the same ranking constraint.
- * Can only be used with the Nikolov and Healy algorithm
- */
-static void doSameRank(graph_t * g)
-{
- int i;
- for (i = 0; i < nNodeGroups; i++) {
- int j;
-
- for (j = 0; j < nodeGroups[i].nNodes; j++) {
- if (ND_ranktype(nodeGroups[i].nodes[j]) == SAMERANK) //once we find a SAMERANK node in a group- make all the members of the group SAMERANK
- {
- int k;
- int r = ND_rank(UF_find(nodeGroups[i].nodes[j]));
- for (k = 0; k < nodeGroups[i].nNodes; k++) {
- ND_rank(nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) = r;
- }
-
- break;
- }
- }
- }
-}
-
-/* doMinRank:
- * Maintain the MIN ranking constraint.
- * Can only be used with the Nikolov and Healy algorithm
- */
-void doMinRank(graph_t * g)
-{
- int i;
- for (i = 0; i < nNodeGroups; i++) {
- int j;
-
- for (j = 0; j < nodeGroups[i].nNodes; j++) {
- if (ND_ranktype(nodeGroups[i].nodes[j]) == MINRANK) //once we find a MINRANK node in a group- make the rank of all the members of the group 0
- {
- int k;
- for (k = 0; k < nodeGroups[i].nNodes; k++) {
- ND_rank(nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) = 0;
- if (ND_ranktype
- (nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) !=
- SOURCERANK)
- ND_ranktype(nodeGroups[i].
- nodes[(j +
- k) % nodeGroups[i].nNodes]) =
- MINRANK;
- }
-
- break;
- }
- }
- }
-}
-
-/* getMaxRank:
- * Return the maximum rank among all nodes.
- */
-static int getMaxRank(graph_t * g)
-{
- int i;
- node_t *v;
- int maxR = ND_rank(agfstnode(g));
- for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
- if (ND_rank(v) > maxR)
- maxR = ND_rank(v);
- }
-
- return maxR;
-}
-
-/* doMaxRank:
- * Maintain the MAX ranking constraint.
- * Can only be used with the Nikolov and Healy algorithm
- */
-static void doMaxRank(graph_t * g)
-{
- int i;
- for (i = 0; i < nNodeGroups; i++) {
- int j;
- int maxR = getMaxRank(g);
-
- for (j = 0; j < nodeGroups[i].nNodes; j++) {
- if (ND_ranktype(nodeGroups[i].nodes[j]) == MAXRANK) //once we find a MAXRANK node in a group- make the rank of all the members of the group MAX
- {
- int k;
- for (k = 0; k < nodeGroups[i].nNodes; k++) {
- ND_rank(nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) = maxR;
- if (ND_ranktype
- (nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) !=
- SINKRANK)
- ND_ranktype(nodeGroups[i].
- nodes[(j +
- k) % nodeGroups[i].nNodes]) =
- MAXRANK;
- }
-
- break;
- }
- }
- }
-}
-
-/* doSourceRank:
- * Maintain the SOURCE ranking constraint.
- * Can only be used with the Nikolov and Healy algorithm
- */
-static void doSourceRank(graph_t * g)
-{
- int i;
- int flag = 0;
-
- for (i = 0; i < nNodeGroups; i++) {
- int j;
-
- for (j = 0; j < nodeGroups[i].nNodes; j++) {
- //once we find a SOURCERANK node in a group- make the rank of all the members of the group 0
- if (ND_ranktype(nodeGroups[i].nodes[j]) == SOURCERANK) {
- int k;
- for (k = 0; k < nodeGroups[i].nNodes; k++) {
- ND_rank(nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) = 0;
- ND_ranktype(nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) =
- SOURCERANK;
- }
-
- flag = 1;
- break;
- }
- }
- }
-
- if (!flag)
- return;
-
- flag = 0;
-
- //The SourceRank group might be the only group having rank 0. Check if increment of ranking of other nodes is necessary at all.
- for (i = 0; i < nNodeGroups; i++) {
- if (nodeGroups[i].nNodes > 0
- && ND_ranktype(nodeGroups[i].nodes[0]) != SOURCERANK
- && ND_rank(nodeGroups[i].nodes[0]) == 0) {
- flag = 1;
- break;
- }
- }
-
-
- if (!flag)
- return;
-
- //Now make all NON-SourceRank nodes' ranking nonzero (increment)
- for (i = 0; i < nNodeGroups; i++) {
- if (nodeGroups[i].nNodes > 0
- && ND_ranktype(nodeGroups[i].nodes[0]) != SOURCERANK) {
- int j;
-
- for (j = 0; j < nodeGroups[i].nNodes; j++) {
- ND_rank(nodeGroups[i].nodes[j])++;
- }
- }
- }
-}
-
-/* doSinkRank:
- * Maintain the SINK ranking constraint.
- * Can only be used with the Nikolov and Healy algorithm
- */
-static void doSinkRank(graph_t * g)
-{
- int i, max;
- int flag = 0;
-
- max = getMaxRank(g);
-
-
- //Check if any non-sink node has rank = max
- for (i = 0; i < nNodeGroups; i++) {
- if (nodeGroups[i].nNodes > 0
- && ND_ranktype(nodeGroups[i].nodes[0]) != SINKRANK
- && ND_rank(nodeGroups[i].nodes[0]) == max) {
- flag = 1;
- break;
- }
- }
-
- if (!flag)
- return;
-
- for (i = 0; i < nNodeGroups; i++) {
- int j;
-
- for (j = 0; j < nodeGroups[i].nNodes; j++) {
- if (ND_ranktype(nodeGroups[i].nodes[j]) == SINKRANK) //once we find a SINKRANK node in a group- make the rank of all the members of the group: max+1
- {
- int k;
- for (k = 0; k < nodeGroups[i].nNodes; k++) {
- ND_rank(nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) =
- max + 1;
- ND_ranktype(nodeGroups[i].
- nodes[(j + k) % nodeGroups[i].nNodes]) =
- SINKRANK;
- }
-
- break;
- }
- }
- }
-}
-
-/* rank2:
- * Initial codes for ranking (Nikolov-Healy).
- * It's no longer used.
- */
-void rank2(graph_t * g)
-{
- int currentLayer = 1;
- int nNodes = agnnodes(g);
- int nEdges = agnedges(g);
- int nPinnedNodes = 0, nSelected = 0;
- Agnode_t *n, **UArray;
- int USize = 0;
- int i, prevSize = 0;
-
- UArray = N_NEW(nEdges * 2, Agnode_t *);
-
- /* make all pinning values 0 */
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- ND_pinned(n) = 0;
- }
-
- while (nPinnedNodes != nNodes) {
- for (nSelected = 0, n = agfstnode(g); n; n = agnxtnode(g, n)) {
- if (ND_pinned(n) == 0) {
- if (allNeighborsAreBelow(n)) {
- ND_pinned(n) = 1;
-
- UArray[USize] = n;
- USize++;
-
- ND_rank(n) = currentLayer;
- nPinnedNodes++;
- nSelected++;
- }
- }
- }
-
- if (nSelected == 0) //no node has been selected
- {
- currentLayer++;
- for (i = prevSize; i < USize; i++) {
- ND_pinned(UArray[i]) = 2; //pinning value of 2 indicates this node is below the current node under consideration
- }
-
- prevSize = USize;
- }
- }
-
- //Apply Nikolov's node promotion heuristic
- applyPromotionHeuristic(g);
-
- //this is for the sake of graphViz layer numbering scheme
- reverseLevelNumbers(g);
-
- computeNodeGroups(g); //groups of UF DS nodes
-
- //modify the ranking to respect the same ranking constraint
- doSameRank(g);
-
- //satisfy min ranking constraints
- doMinRank(g);
- doMaxRank(g);
-
- //satisfy source ranking constraints
- doSourceRank(g);
- doSinkRank(g);
-
- //Apply the FFDH algorithm to achieve better aspect ratio;
- applyPacking(g, 1); //achieve an aspect ratio of 1
-}
-#endif
-
/****************************************************************
* Initialize all the edge types to NORMAL
****************************************************************/
return ratio;
}
-#ifdef UNUSED
-/* applyExpansion:
- * Heuristic for expanding very narrow graphs by edge reversal.
- * Needs improvement.
- */
-void applyExpansion(graph_t * g)
-{
- node_t *sink = NULL;
- int i, k;
- edge_t *e;
-
- computeLayerWidths(g);
-
- for (i = 0; i < nLayers; i++) {
- if (layerWidthInfo[i].layerNumber == nLayers / 2) {
- k = i;
- break;
- }
- }
-
- //now reverse the edges, from the k-th layer nodes to their parents
- for (i = 0; i < layerWidthInfo[k].nNodeGroupsInLayer; i++) {
- int p;
- nodeGroup_t *ng = layerWidthInfo[k].nodeGroupsInLayer[i];
- for (p = 0; p < ng->nNodes; p++) {
- node_t *nd = ng->nodes[p];
-
- while (e = ND_in(nd).list[0]) {
- printf("Reversing edge: %s->%s\n", agnemeof(agtail(e)),
- agnameof(aghead(e)));
- reverse_edge(e);
- }
-
- int j, l;
- node_t *v3;
- edge_t *e3;
- for (v3 = agfstnode(g); v3; v3 = agnxtnode(g, v3)) {
- for (e3 = agfstout(g, v3); e3; e3 = agnxtout(g, e3)) {
- if (ND_rank(aghead(e3)) > k && ND_rank(agtail(e3)) < k) {
- printf("Reversing long edge: %s->%s\n",
- agnameof(agtail(e3)), agnameof(aghead(e3)));
- reverse_edge(e3);
- }
-
- }
- }
-
- /*for (l = 0; l < nLayers; l++) {
- if (layerWidthInfo[l].layerNumber <= k)
- continue;
-
- for (j = 0; j < layerWidthInfo[l].nNodeGroupsInLayer; j++) {
- int q;
- nodeGroup_t *ng2 = layerWidthInfo[l].nodeGroupsInLayer[j];
- for (q = 0; q < ng2->nNodes; q++) {
- node_t *nd2 = ng2->nodes[q];
- edge_t *e2;
- int s = 0;
- while (e2 = ND_in(nd2).list[s]) {
- if (ND_rank(agtail(e2)) < k) {
- printf("Reversing edge: %s->%s\n",
- agnameof(agtail(e2)), agnameof(aghead(e2)));
- getchar();
- //reverse_edge(e2);
- }
- else s++;
- }
- }
- }
- } */
-
- if (sink == NULL) {
- int brFlag = 1;
- for (l = 0; l < nLayers && brFlag; l++) {
- for (j = 0;
- j < layerWidthInfo[l].nNodeGroupsInLayer
- && brFlag; j++) {
- int q;
- nodeGroup_t *ng2 =
- layerWidthInfo[l].nodeGroupsInLayer[j];
- for (q = 0; q < ng2->nNodes && brFlag; q++) {
- node_t *nd2 = ng2->nodes[q];
- if (ND_in(nd2).size == 0) {
- sink = nd2;
- brFlag = 0;
- }
- }
- }
- }
-
- }
-
- virtual_edge(nd, /*sink */
- layerWidthInfo[0].nodeGroupsInLayer[0]->nodes[0],
- NULL);
- }
- }
-
- //collapse_sets(g);
-}
-#endif
-
/* zapLayers:
* After applying the expansion heuristic, some layers are
* found to be empty.
if (Verbose)
fprintf(stderr, "combiAR = %lf\n", asp->combiAR);
-
- /* Uncomment the following codes, for working with narrow graphs */
-#ifdef UNUSED
- if (combiAR < 0.8 * targetAR) {
- char str[20];
- printf("Apply expansion? (y/n):");
- scanf("%s", str);
- if (strcmp(str, "y") == 0)
- applyExpansion(g);
- break;
- } else
-#endif
/* Success or if no improvement */
if ((asp->combiAR <= asp->targetAR) || ((iterations == -1) && (lastAR <= asp->combiAR))) {
asp->prevIterations = asp->curIterations;
asp->combiAR = computeCombiAR(g);
}
-#ifdef UNUSED
-/* NikolovHealy:
- * Nikolov-Healy approach to ranking.
- * First, use longest path algorithm.
- * Then use node promotion heuristic.
- * This function is called by rank4 function.
- */
-static void NikolovHealy(graph_t * g)
-{
- int currentLayer = 1;
- int nNodes = agnnodes(g);
- int nEdges = agnedges(g);
- int nPinnedNodes = 0, nSelected = 0;
- Agnode_t *n, **UArray;
- int USize = 0;
- int i, prevSize = 0;
-
- /************************************************************************
- * longest path algorithm
- ************************************************************************/
- UArray = N_NEW(nEdges * 2, Agnode_t *);
-
- /* make all pinning values 0 */
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- ND_pinned(n) = 0;
- }
-
- while (nPinnedNodes != nNodes) {
- for (nSelected = 0, n = agfstnode(g); n; n = agnxtnode(g, n)) {
- if (ND_pinned(n) == 0) {
- if (allNeighborsAreBelow(n)) {
- ND_pinned(n) = 1;
-
- UArray[USize] = n;
- USize++;
-
- ND_rank(n) = currentLayer;
- nPinnedNodes++;
- nSelected++;
- }
- }
- }
-
- if (nSelected == 0) //no node has been selected
- {
- currentLayer++;
- for (i = prevSize; i < USize; i++) {
- ND_pinned(UArray[i]) = 2; //pinning value of 2 indicates this node is below the current node under consideration
- }
-
- prevSize = USize;
- }
-
- }
-
- /************************************************************************
- * end of longest path algorithm
- ************************************************************************/
-
- //Apply node promotion heuristic
- applyPromotionHeuristic(g);
-
- //this is for the sake of graphViz layer numbering scheme
- reverseLevelNumbers(g);
-
-}
-
-
-/* rank4:
- * This function is calls the NikolovHealy function
- * for ranking in the Nikolov-Healy approach.
- */
-void rank4(graph_t * g, int iterations)
-{
- int currentLayer = 1;
- int nNodes = agnnodes(g);
- int nEdges = agnedges(g);
- int nPinnedNodes = 0, nSelected = 0;
- Agnode_t *n, **UArray;
- int USize = 0;
- int i, prevSize = 0;
-
- int it;
- printf("# of interations of packing: ");
- scanf("%d", &it);
- printf("it=%d\n", it);
-
- computeNodeGroups(g); //groups of UF DS nodes
-
- for (i = 0; i < it; i++) {
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- ND_rank(n) = 0;
- }
-
- NikolovHealy(g);
-
- edge_t *e;
- int cnt = 0;
- int lc;
-
-
- combiAR = computeCombiAR(g);
- printf("%d. combiAR = %lf\n", i, combiAR);
-
- /*
- //modify the ranking to respect the same ranking constraint
- doSameRank(g);
-
- //satisfy min ranking constraints
- doMinRank(g);
- doMaxRank(g);
-
- //satisfy source ranking constraints
- doSourceRank(g);
- doSinkRank(g);
- */
-
- //Apply the FFDH algorithm to achieve better aspect ratio;
- applyPacking4(g);
-
- }
-
-}
-#endif
-
/* init_UF_size:
* Initialize the Union Find data structure
*/