void extend_clique_on_fgraph(spp_cg_problem *spp, cut_data *new_cut, double *pviolation) { int old_coef_num, coef_num, i, j, k; double lhs = 1 + *pviolation; fnode *nodes = spp->fgraph->nodes; int nodenum = spp->fgraph->nodenum; int *indices = spp->tmp->itmp_8nodenum + 7 * nodenum; /* same tmp array is used in parent fn, but only after this fn returns */ int userind; old_coef_num = coef_num = new_cut->size/ISIZE; memcpy(indices, new_cut->coef, coef_num * ISIZE); /* i runs thru nodes in fgraph, j runs thru nodes in the clique. note that the clique is a subgraph of fgraph */ for ( i = j = 0; i < nodenum && j < old_coef_num; i++ ) { userind = nodes[i].ind; if ( userind < indices[j] ) { /* check if the node can be added to the clique */ for ( k = 0; k < coef_num; k++ ) if (spp_is_orthogonal(spp->cmatrix, userind, indices[k])) break; if ( k == coef_num ) { /* node can be added ... */ indices[coef_num++] = userind; lhs += nodes[i].val; } } else { /* node is in the clique */ j++; } } for ( ; i < nodenum; i++ ) { userind = nodes[i].ind; /* check if the node can be added to the clique */ for ( k = 0; k < coef_num; k++ ) if (spp_is_orthogonal(spp->cmatrix, userind, indices[k])) break; if ( k == coef_num ) { /* node can be added ... */ indices[coef_num++] = userind; lhs += nodes[i].val; } } /* if some nodes were added to the clique ... */ if (old_coef_num < coef_num) { new_cut->size = coef_num * ISIZE; qsort_i(indices, coef_num); memcpy(new_cut->coef, indices, new_cut->size); *pviolation = lhs - 1; } }
int extend_clique_greedily(col_ordered *cmatrix, int cl_length, int *cl_indices, int length, int *indices) { int i, j, var; int pos = 0; /* pos after the last var that has been added to the clique */ for (j = 0; j < length; j++) { var = indices[j]; for (i = cl_length - 1; i >= 0; i--) if (spp_is_orthogonal(cmatrix, cl_indices[i], var)) break; if (i >= 0) continue; for (i = pos - 1; i >= 0; i--) if (spp_is_orthogonal(cmatrix, indices[i], var)) break; if (i < 0) indices[pos++] = var; } return(pos); }
void construct_fractional_graph(spp_cg_problem *spp, int number, int *indices, double *values) { frac_graph *fgraph = spp->fgraph; int *all_nbr = spp->fgraph->all_nbr; double *all_edgecost = spp->fgraph->all_edgecost; fnode *nodes = fgraph->nodes; int min_degree, max_degree, min_deg_node, max_deg_node; int i, j, total_deg, old_total; fgraph->nodenum = number; /*========================================================================* Construct the adjacency lists (neighbors) of the nodes in fgraph. Two nodes are adjacent iff the columns corresponding to them are non-orthogonal. *========================================================================*/ for ( i = 0, total_deg = 0; i < number; i++ ) { old_total = total_deg; for ( j = 0; j < number; j++ ) { if ( j != i && !spp_is_orthogonal(spp->cmatrix, indices[i], indices[j])) { all_nbr[total_deg] = j; all_edgecost[total_deg++] = 1 - values[i] - values[j]; } } nodes[i].ind = indices[i]; nodes[i].val = values[i]; nodes[i].degree = total_deg - old_total; nodes[i].nbrs = all_nbr + old_total; nodes[i].edgecosts = all_edgecost + old_total; } fgraph->edgenum = total_deg / 2; fgraph->density = 2 * (double)fgraph->edgenum / (number * (number-1)); /*========================================================================* Compute the min and max degree. *========================================================================*/ min_deg_node = 0; max_deg_node = 0; min_degree = max_degree = nodes[0].degree; for ( i = 0; i < number; i++ ) { if ( nodes[i].degree < min_degree ) { min_deg_node = i; min_degree = nodes[i].degree; } if ( nodes[i].degree > max_degree ) { max_deg_node = i; max_degree = nodes[i].degree; } } fgraph->min_degree = min_degree; fgraph->max_degree = max_degree; fgraph->min_deg_node = min_deg_node; fgraph->max_deg_node = max_deg_node; /*========================================================================* Now create the node-node incidence matrix of the graph. *========================================================================*/ for ( i = number*number-1; i >=0 ; i-- ) fgraph->node_node[i] = FALSE; for ( i = 0; i < number; i++ ) for ( j = 0; j < nodes[i].degree; j++ ) fgraph->node_node[i * number + nodes[i].nbrs[j]] = TRUE; }