void set_of_sets::init(INT underlying_set_size, INT nb_sets, INT **Pts, INT *Sz, INT verbose_level) { INT f_v = (verbose_level >= 1); INT i; if (f_v) { cout << "set_of_sets::init nb_sets=" << nb_sets << " underlying_set_size=" << underlying_set_size << endl; } init_basic(underlying_set_size, nb_sets, Sz, verbose_level); for (i = 0; i < nb_sets; i++) { INT_vec_copy(Pts[i], Sets[i], Sz[i]); } }
int main() { float tab1[N1] = {3.2, 2.1, -8.4, 0.0, 5.5}; // a eviter generalement float tab2[N2]; float tab3[N3]; init_zero(tab2, N2); init_basic(tab3, N3); affiche(tab1, N1); affiche(tab2, N2); affiche(tab3, N3); return EXIT_SUCCESS; }
/* * Compute EMD between weighted samples, given a pairwise cost matrix * @param int n_x : number of samples in X * @param double *weight_x : list of weights of samples in X (sums to 1) * @param int n_y : number of samples in Y * @param double *weight_y : list of weights of samples in Y (sums to 1) * @param double **cost : pairwise cost matrix; cost[i][j] holds cost to * "move dirt" from X_i to Y_j * @return double : returns EMD between samples */ double emd(int n_x, double *weight_x, int n_y, double *weight_y, double **cost) { struct basic_variable **basis; struct basic_variable *var, *root, *to_remove; struct adj_node *adj; double *dual_x, *dual_y; int *solved_x, *solved_y; int i, j, B, min_row, min_col; double min_slack, slack, min_flow, sign, distance; B = n_x + n_y - 1; basis = initialize_flow(n_x, weight_x, n_y, weight_y, cost); // Iterate until optimality conditions satisfied dual_x = vector_malloc(n_x); dual_y = vector_malloc(n_y); solved_x = (int *) malloc(n_x*sizeof(int)); solved_y = (int *) malloc(n_y*sizeof(int)); while (1) { for (i = 0; i < n_x; i++) { solved_x[i] = 0; } for (i = 0; i < n_y; i++) { solved_y[i] = 0; } reset_current_adj(basis, B); var = basis[0]; dual_x[var->row] = 0.0; solved_x[var->row] = 1; while (1) { var->color = GRAY; if (solved_x[var->row]){ dual_y[var->col] = (cost[var->row][var->col] - dual_x[var->row]); solved_y[var->col] = 1; } else if (solved_y[var->col]) { dual_x[var->row] = (cost[var->row][var->col] - dual_y[var->col]); solved_x[var->row] = 1; } else { assert(FALSE); } for (adj = var->current_adj; adj != NULL; adj = adj->next) { if (adj->variable->color == WHITE) { break; } } if (adj == NULL) { var->color = BLACK; var = var->back_ptr; if (var == NULL) { break; } } else { var->current_adj = adj->next; adj->variable->back_ptr = var; var = adj->variable; } } // Check for optimality min_row = -1; min_col = -1; min_slack = 0.0; for (i = 0; i < n_x; i++) { for (j = 0; j < n_y; j++) { slack = cost[i][j] - dual_x[i] - dual_y[j]; if (min_row < 0 || slack < min_slack) { min_row = i; min_col = j; min_slack = slack; } } } for (i = 0; i < B; i++) { // If the pivot variable is any of the // basis variables, then the optimal // solution has been found; set // min_slack = 0.0 explicitly to avoid // floating point issues in comparison. if (basis[i]->row == min_row && basis[i]->col == min_col) { min_slack = 0.0; break; } } if (min_slack >= -EPSILON) { break; } // Introduce a new variable var = init_basic(min_row, min_col, 0.0); insert_basic(basis, B, var); root = var; reset_current_adj(basis, B + 1); while (1) { var->color = GRAY; for (adj = var->current_adj; adj != NULL; adj = adj->next) { if (var->back_ptr != NULL && (var->back_ptr->row == adj->variable->row || var->back_ptr->col == adj->variable->col)) { continue; } if (adj->variable == root) { // Found a cycle break; } if (adj->variable->color == WHITE) { break; } } if (adj == NULL) { var->color = BLACK; var = var->back_ptr; if (var == NULL) { // Couldn't find a cycle assert(FALSE); } } else { if (adj->variable->color == GRAY) { // We found a cycle root->back_ptr = var; break; } else { var->current_adj = adj->next; adj->variable->back_ptr = var; var = adj->variable; } } } // Find the largest flow that can be subtracted sign = -1.0; min_flow = 0; to_remove = NULL; for (var = root->back_ptr; var != root; var = var->back_ptr) { if (sign < 0 && (to_remove == NULL || var->flow < min_flow)) { min_flow = var->flow; to_remove = var; } sign *= -1.0; } // Adjust flows sign = -1.0; root->flow = min_flow; for (var = root->back_ptr; var != root; var = var->back_ptr) { var->flow += (sign * min_flow); sign *= -1.0; } // Remove the basic variable that went to zero remove_basic(basis, B, to_remove); } distance = 0; for (i = 0; i < B; i++) { distance += (basis[i]->flow * cost[basis[i]->row][basis[i]->col]); } free(dual_x); free(dual_y); free(solved_x); free(solved_y); destruct_basis(basis, B); return distance; }