summaryrefslogtreecommitdiffstats
path: root/src/misc/espresso/gimpel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc/espresso/gimpel.c')
-rw-r--r--src/misc/espresso/gimpel.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/misc/espresso/gimpel.c b/src/misc/espresso/gimpel.c
new file mode 100644
index 00000000..648bb64a
--- /dev/null
+++ b/src/misc/espresso/gimpel.c
@@ -0,0 +1,106 @@
+/*
+ * Revision Control Information
+ *
+ * $Source$
+ * $Author$
+ * $Revision$
+ * $Date$
+ *
+ */
+#include "mincov_int.h"
+
+
+/*
+ * check for:
+ *
+ * c1 c2 rest
+ * -- -- ---
+ * 1 1 0 0 0 0 <-- primary row
+ * 1 0 S1 <-- secondary row
+ * 0 1 T1
+ * 0 1 T2
+ * 0 1 Tn
+ * 0 0 R
+ */
+
+int
+gimpel_reduce(A, select, weight, lb, bound, depth, stats, best)
+sm_matrix *A;
+solution_t *select;
+int *weight;
+int lb;
+int bound;
+int depth;
+stats_t *stats;
+solution_t **best;
+{
+ register sm_row *prow, *save_sec;
+ register sm_col *c1, *c2;
+ register sm_element *p, *p1;
+ int c1_col_num, c2_col_num, primary_row_num, secondary_row_num;
+ int reduce_it;
+
+ reduce_it = 0;
+ for(prow = A->first_row; prow != 0; prow = prow->next_row) {
+ if (prow->length == 2) {
+ c1 = sm_get_col(A, prow->first_col->col_num);
+ c2 = sm_get_col(A, prow->last_col->col_num);
+ if (c1->length == 2) {
+ reduce_it = 1;
+ } else if (c2->length == 2) {
+ c1 = sm_get_col(A, prow->last_col->col_num);
+ c2 = sm_get_col(A, prow->first_col->col_num);
+ reduce_it = 1;
+ }
+ if (reduce_it) {
+ primary_row_num = prow->row_num;
+ secondary_row_num = c1->first_row->row_num;
+ if (secondary_row_num == primary_row_num) {
+ secondary_row_num = c1->last_row->row_num;
+ }
+ break;
+ }
+ }
+ }
+
+ if (reduce_it) {
+ c1_col_num = c1->col_num;
+ c2_col_num = c2->col_num;
+ save_sec = sm_row_dup(sm_get_row(A, secondary_row_num));
+ sm_row_remove(save_sec, c1_col_num);
+
+ for(p = c2->first_row; p != 0; p = p->next_row) {
+ if (p->row_num != primary_row_num) {
+ /* merge rows S1 and T */
+ for(p1 = save_sec->first_col; p1 != 0; p1 = p1->next_col) {
+ (void) sm_insert(A, p->row_num, p1->col_num);
+ }
+ }
+ }
+
+ sm_delcol(A, c1_col_num);
+ sm_delcol(A, c2_col_num);
+ sm_delrow(A, primary_row_num);
+ sm_delrow(A, secondary_row_num);
+
+ stats->gimpel_count++;
+ stats->gimpel++;
+ *best = sm_mincov(A, select, weight, lb-1, bound-1, depth, stats);
+ stats->gimpel--;
+
+ if (*best != NIL(solution_t)) {
+ /* is secondary row covered ? */
+ if (sm_row_intersects(save_sec, (*best)->row)) {
+ /* yes, actually select c2 */
+ solution_add(*best, weight, c2_col_num);
+ } else {
+ solution_add(*best, weight, c1_col_num);
+ }
+ }
+
+ sm_row_free(save_sec);
+ return 1;
+ } else {
+ return 0;
+ }
+}