summaryrefslogtreecommitdiffstats
path: root/src/misc/espresso/indep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc/espresso/indep.c')
-rw-r--r--src/misc/espresso/indep.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/misc/espresso/indep.c b/src/misc/espresso/indep.c
new file mode 100644
index 00000000..10b363a0
--- /dev/null
+++ b/src/misc/espresso/indep.c
@@ -0,0 +1,134 @@
+/*
+ * Revision Control Information
+ *
+ * $Source$
+ * $Author$
+ * $Revision$
+ * $Date$
+ *
+ */
+#include "mincov_int.h"
+
+static sm_matrix *build_intersection_matrix();
+
+
+#if 0
+/*
+ * verify that all rows in 'indep' are actually independent !
+ */
+static int
+verify_indep_set(A, indep)
+sm_matrix *A;
+sm_row *indep;
+{
+ register sm_row *prow, *prow1;
+ register sm_element *p, *p1;
+
+ for(p = indep->first_col; p != 0; p = p->next_col) {
+ prow = sm_get_row(A, p->col_num);
+ for(p1 = p->next_col; p1 != 0; p1 = p1->next_col) {
+ prow1 = sm_get_row(A, p1->col_num);
+ if (sm_row_intersects(prow, prow1)) {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+#endif
+
+solution_t *
+sm_maximal_independent_set(A, weight)
+sm_matrix *A;
+int *weight;
+{
+ register sm_row *best_row, *prow;
+ register sm_element *p;
+ int least_weight;
+ sm_row *save;
+ sm_matrix *B;
+ solution_t *indep;
+
+ indep = solution_alloc();
+ B = build_intersection_matrix(A);
+
+ while (B->nrows > 0) {
+ /* Find the row which is disjoint from a maximum number of rows */
+ best_row = B->first_row;
+ for(prow = B->first_row->next_row; prow != 0; prow = prow->next_row) {
+ if (prow->length < best_row->length) {
+ best_row = prow;
+ }
+ }
+
+ /* Find which element in this row has least weight */
+ if (weight == NIL(int)) {
+ least_weight = 1;
+ } else {
+ prow = sm_get_row(A, best_row->row_num);
+ least_weight = weight[prow->first_col->col_num];
+ for(p = prow->first_col->next_col; p != 0; p = p->next_col) {
+ if (weight[p->col_num] < least_weight) {
+ least_weight = weight[p->col_num];
+ }
+ }
+ }
+ indep->cost += least_weight;
+ (void) sm_row_insert(indep->row, best_row->row_num);
+
+ /* Discard the rows which intersect this row */
+ save = sm_row_dup(best_row);
+ for(p = save->first_col; p != 0; p = p->next_col) {
+ sm_delrow(B, p->col_num);
+ sm_delcol(B, p->col_num);
+ }
+ sm_row_free(save);
+ }
+
+ sm_free(B);
+
+/*
+ if (! verify_indep_set(A, indep->row)) {
+ fail("sm_maximal_independent_set: row set is not independent");
+ }
+*/
+ return indep;
+}
+
+static sm_matrix *
+build_intersection_matrix(A)
+sm_matrix *A;
+{
+ register sm_row *prow, *prow1;
+ register sm_element *p, *p1;
+ register sm_col *pcol;
+ sm_matrix *B;
+
+ /* Build row-intersection matrix */
+ B = sm_alloc();
+ for(prow = A->first_row; prow != 0; prow = prow->next_row) {
+
+ /* Clear flags on all rows we can reach from row 'prow' */
+ for(p = prow->first_col; p != 0; p = p->next_col) {
+ pcol = sm_get_col(A, p->col_num);
+ for(p1 = pcol->first_row; p1 != 0; p1 = p1->next_row) {
+ prow1 = sm_get_row(A, p1->row_num);
+ prow1->flag = 0;
+ }
+ }
+
+ /* Now record which rows can be reached */
+ for(p = prow->first_col; p != 0; p = p->next_col) {
+ pcol = sm_get_col(A, p->col_num);
+ for(p1 = pcol->first_row; p1 != 0; p1 = p1->next_row) {
+ prow1 = sm_get_row(A, p1->row_num);
+ if (! prow1->flag) {
+ prow1->flag = 1;
+ (void) sm_insert(B, prow->row_num, prow1->row_num);
+ }
+ }
+ }
+ }
+
+ return B;
+}