示例#1
0
static int process_habit(DictionaryIterator *iter, struct NetworkState *state)
{
    int rval = 0;
    struct NetworkCallbacks *callbacks = state->callbacks;

    Tuple *tuple = dict_find(iter, 1);
    abort_if(!tuple, "tuple is null");
    int id = tuple->value->int32;

    tuple = dict_find(iter, 2);
    abort_if(!tuple, "tuple is null");
    char *name = tuple->value->cstring;

    tuple = dict_find(iter, 3);
    abort_if(!tuple, "tuple is null");
    int checkmark = tuple->value->int32;

    if(callbacks->on_habit)
    {
        void *ctx = callbacks->on_habit_context;
        rval = callbacks->on_habit(id, name, checkmark, ctx);
        abort_if(rval, "state->on_habit failed");

        rval = request_next_habit(state);
        abort_if(rval, "request_next_habit failed");
    }

CLEANUP:
    return rval;
}
示例#2
0
static void NETWORK_on_received(DictionaryIterator *iter, void *context)
{
    int rval = 0;
    struct NetworkState *state = context;
    abort_if(!state, "state is null");

    Tuple *tuple = dict_find(iter, 0);
    abort_if(!tuple, "tuple is null");

    char *action = tuple->value->cstring;
    log_debug("<-- %s", action);

    if(strcmp(action, "COUNT") == 0)
    {
        rval = process_count(iter, state);
        abort_if(rval, "process_count failed");
    }
    else if(strcmp(action, "HABIT") == 0)
    {
        rval = process_habit(iter, state);
        abort_if(rval, "process_habit failed");
    }
    else if(strcmp(action, "OK") == 0)
    {
        rval = process_ok(state);
        abort_if(rval, "process_ok failed");
    }

CLEANUP:
    return;
}
示例#3
0
int NETWORK_register()
{
    int rval = 0;

    struct NetworkState *state = 0;
    state = (struct NetworkState*) malloc(sizeof(struct NetworkState));
    abort_if(!state, "could not allocate state");

    struct NetworkCallbacks *callbacks = 0;
    callbacks = (struct NetworkCallbacks*) malloc(sizeof(struct NetworkCallbacks));
    abort_if(!callbacks, "could not allocate callbacks");

    state->callbacks = callbacks;
    callbacks->on_ok = 0;
    callbacks->on_habit = 0;
    callbacks->on_count = 0;
    callbacks->on_ok_context = 0;
    callbacks->on_habit_context = 0;
    callbacks->on_count_context = 0;

    app_message_register_inbox_received(NETWORK_on_received);
    app_message_open(1024, 1024);
    app_message_set_context(state);

CLEANUP:
    return rval;
}
示例#4
0
static int request_next_habit(struct NetworkState *state)
{
    int rval = 0;
    abort_if(!state, "state is null");

    if(state->habit_current >= state->habit_count)
        goto CLEANUP;

    DictionaryIterator *dict;
    rval = app_message_outbox_begin(&dict);
    abort_if(rval, "app_message_outbox_begin failed");

    rval = dict_write_cstring(dict, 0, "FETCH");
    abort_if(rval, "dict_write_cstring failed");

    rval = dict_write_int32(dict, 1, state->habit_current);
    abort_if(rval, "dict_write_cstring failed");

    rval = app_message_outbox_send();
    abort_if(rval, "app_message_outbox_send failed");

    state->habit_current++;

CLEANUP:
    return rval;
}
示例#5
0
static int process_count(DictionaryIterator *iter, struct NetworkState *state)
{
    int rval = 0;
    abort_if(!state, "state is null");
    struct NetworkCallbacks *callbacks = state->callbacks;

    Tuple *tuple = dict_find(iter, 1);
    abort_if(!tuple, "tuple is null");

    int count = tuple->value->int32;

    if(callbacks->on_count)
    {
        rval = callbacks->on_count(count, callbacks->on_count_context);
        abort_if(rval, "state->on_count failed");
    }

    if(count > MAX_HABIT_COUNT) count = MAX_HABIT_COUNT;
    state->habit_count = count;
    state->habit_current = 0;

    rval = request_next_habit(state);
    abort_if(rval, "request_next_habit failed");

CLEANUP:
    return rval;
}
示例#6
0
文件: main.c 项目: iSoron/multirow
int benchmark_set(int algorithm,
                  int set_idx,
                  const struct LFreeSet2D *set,
                  const double *rays,
                  const double *pre_m,
                  const double center,
                  int *wrong_answer)
{
    int rval = 0;
    int lb[2], ub[2];

    if(algorithm == ALGORITHM_NAIVE)
    {
        if (USE_FIXED_BOUNDS)
        {
            ub[0] = ub[1] = NAIVE_BIG_M;
            lb[0] = lb[1] = -NAIVE_BIG_M;
        }
        else
        {
            rval = LFREE_2D_get_bounding_box(set, lb, ub);
            abort_if(rval, "LFREE_2D_get_bounding_box failed");

            ub[0] += BOUNDING_BOX_PADDING;
            ub[1] += BOUNDING_BOX_PADDING;
            lb[0] -= BOUNDING_BOX_PADDING;
            lb[0] -= BOUNDING_BOX_PADDING;
        }

        ub[0] = fmin(ub[0], MAX_BOX_SIZE);
        ub[1] = fmin(ub[1], MAX_BOX_SIZE);
        lb[0] = fmax(lb[0], -MAX_BOX_SIZE);
        lb[1] = fmax(lb[1], -MAX_BOX_SIZE);

        if(ub[0] == MAX_BOX_SIZE || ub[1] == MAX_BOX_SIZE || lb[0] ==
                -MAX_BOX_SIZE || lb[1] == -MAX_BOX_SIZE)
        {
            log_info("    bounding box has been clipped\n");
        }
    }

    for (int k = 0; k < N_SAMPLES_PER_SET; k ++)
    {
        rval = benchmark_set_sample(algorithm, set_idx, set, rays, pre_m,
                                    center, lb, ub, k, wrong_answer);
        abort_if(rval, "benchmark_set_sample failed");
    }

CLEANUP:
    return rval;
}
示例#7
0
文件: main.c 项目: iSoron/multirow
int benchmark(int n_sets, struct LFreeSet2D *sets, double *rays,
              int algorithm)
{
    int rval = 0;

    log_info("Running benchmark...\n");

    double total_initial_time = get_user_time();
    stats_printf("cpu_time:\n");

    for (int j = 0; j < n_sets; j++)
    {
        log_debug("Set %d...\n", j);

        double set_initial_time = get_user_time();

        struct LFreeSet2D *set = &sets[j];
        double *pre_m = &PRE_M[j * 4];
        double center = CENTER[j];

        rval = LFREE_2D_print_set(set);
        abort_if(rval, "LFREE_2D_print_set failed");

        int wrong_answer = 0;

        rval = benchmark_set(algorithm, j, set, rays, pre_m, center, &wrong_answer);
        abort_if(rval, "benchmark_set failed");

        double set_duration = get_user_time() - set_initial_time;
        double avg = (set_duration / N_SAMPLES_PER_SET) * 1000;

        if(wrong_answer) avg = 1000000;

        stats_printf("  %d: %.8lf\n", j, avg);
        log_info("  %3d: %12.3lf ms\n", j, avg);
    }

    double total_duration = get_user_time() - total_initial_time;

    log_info("    %.3lf ms per set                     \n",
             total_duration / (n_sets * N_SAMPLES_PER_SET) * 1000);

    if(algorithm == ALGORITHM_MIP)
    {
        log_info("    %.3lf s spent on LP_create\n", MIP_TIME_CREATE);
        log_info("    %.3lf s spent on LP_optimize\n", MIP_TIME_OPTIMIZE);
    }

CLEANUP:
    return rval;
}
示例#8
0
int benchmark_set(int algorithm,
                  int set_idx,
                  const struct LFreeSet2D *set,
                  const double *rays,
                  const double *pre_m,
                  const double center,
                  int *wrong_answer)
{
    int rval = 0;
    int lb[2], ub[2];

    if(algorithm == ALGORITHM_NAIVE)
    {
        if (USE_FIXED_BOUNDS)
        {
            ub[0] = ub[1] = NAIVE_BIG_M;
            lb[0] = lb[1] = -NAIVE_BIG_M;
        }
        else
        {
            rval = LFREE_2D_get_bounding_box(set, lb, ub);
            abort_if(rval, "LFREE_2D_get_bounding_box failed");

            ub[0] += BOUNDING_BOX_PADDING;
            ub[1] += BOUNDING_BOX_PADDING;
            lb[0] -= BOUNDING_BOX_PADDING;
            lb[0] -= BOUNDING_BOX_PADDING;
        }

        int dx = ub[0] - lb[0];
        int dy = ub[1] - lb[1];

        if(dx >= MAX_BOX_SIZE && dy >= MAX_BOX_SIZE)
        {
            log_info("    bounding box is too large: %d by %d\n", dx, dy);
            *wrong_answer = 1;
            
            goto CLEANUP;
        }
    }

    for (int k = 0; k < N_SAMPLES_PER_SET; k ++)
    {
        rval = benchmark_set_sample(algorithm, set_idx, set, rays, pre_m,
                center, lb, ub, k, wrong_answer);
        abort_if(rval, "benchmark_set_sample failed");
    }

CLEANUP:
    return rval;
}
示例#9
0
static int process_ok(struct NetworkState *state)
{
    int rval = 0;
    abort_if(!state, "state is null");

    struct NetworkCallbacks *callbacks = state->callbacks;
    abort_if(!callbacks, "callbacks is null");

    if(!callbacks->on_ok) goto CLEANUP;
    rval = callbacks->on_ok(callbacks->on_ok_context);
    abort_if(rval, "state->on_ok failed");

CLEANUP:
    return rval;
}
示例#10
0
文件: flow.c 项目: iSoron/gtsp
int static mark_reachable_nodes(
        const struct Graph *graph, double *residual_caps, struct Node *from)
{
    int rval = 0;

    struct Node **stack;
    int stack_top = 0;
    int *parents = 0;

    stack = (struct Node **) malloc(graph->node_count * sizeof(struct Node *));
    abort_if(!stack, "could not allocate stack");

    parents = (int *) malloc(graph->node_count * sizeof(int));
    abort_if(!parents, "could not allocate parents");

    stack[stack_top++] = from;
    from->mark = 1;

    while (stack_top > 0)
    {
        struct Node *n = stack[--stack_top];

        for (int j = 0; j < n->degree; j++)
        {
            struct Edge *e = n->adj[j].edge;
            struct Node *neighbor = n->adj[j].neighbor;

            if (neighbor->mark) continue;
            if (residual_caps[e->index] <= 0) continue;

            stack[stack_top++] = neighbor;
            neighbor->mark = 1;
            parents[neighbor->index] = n->index;
        }

    }

    log_verbose("Reachable nodes:\n");
    for (int i = 0; i < graph->node_count; i++)
        if (graph->nodes[i].mark)
                log_verbose("    %d from %d\n", graph->nodes[i].index,
                        parents[i]);

    CLEANUP:
    if (parents) free(parents);
    if (stack) free(stack);
    return rval;
}
示例#11
0
static int
check_short (model_t model, int group, int *src, TransitionCB cb, void *context)
{
    abort_if (true, "Checking layer designed for algorithms using PINS long/all calls");
    (void) model; (void) group; (void) src; (void) cb; (void) context;
    return 0;
}
示例#12
0
int NETWORK_request_list()
{
    int rval = 0;

    DictionaryIterator *dict;
    rval = app_message_outbox_begin(&dict);
    abort_if(rval, "app_message_outbox_begin failed");

    rval = dict_write_cstring(dict, 0, "COUNT");
    abort_if(rval, "dict_write_cstring failed");

    rval = app_message_outbox_send();
    abort_if(rval, "app_message_outbox_send failed");

    log_debug("--> %s", "COUNT");

CLEANUP:
    return rval;
}
示例#13
0
static void
find_culprit_slot (check_ctx_t *ctx, int g)
{
    int             count;

    for (int i = 0; i < ctx->N; i++) {
        while (ctx->src2[i] == ctx->src[i]) {
            i++;
            abort_if (i >= ctx->N, "No-deterministic GBnextLong for group %d", g);
        }
        ctx->src2[i] = ctx->src[i]; // fill

        // retry with src2 more similar to src:
        ctx->idx = i;
        ctx->call_idx = 0;
        ctx->comparison_failed = false;
        count = GBgetTransitionsLong (ctx->parent, g, ctx->src2, find, ctx);
        abort_if (count != ctx->call_idx , "Wrong count returned by GBnextLong(compare): %d (Found: %d).",
                  count, ctx->call_idx);
    }
    HREassert (false);
}
示例#14
0
文件: lifting.c 项目: iSoron/multirow
int LIFTING_2D_lift_fixed(int n_halfspaces,
                          const double *halfspaces,
                          const double *ray,
                          double k1,
                          double *opt)
{
    int rval = 0;

    double k0;
    double value;

    rval = LIFTING_2D_optimize_continuous(n_halfspaces, halfspaces,
            ray[1] + k1, &k0, &value);
    abort_if(rval, "LIFTING_2D_optimize_continuous failed");

    double delta = k0 - ray[0];

    double r_ceil[2] = { ray[0] + ceil(delta), ray[1] + k1 };
    double r_floor[2] = { ray[0] + floor(delta), ray[1] + k1 };

    log_debug("    delta=%.6lf value=%.6lf\n", delta, value);
    log_debug("    r_ceil=%12.6lf %12.6lf\n", r_ceil[0], r_ceil[1]);
    log_debug("    r_floor=%12.6lf %12.6lf\n", r_floor[0], r_floor[1]);

    double value_ceil, value_floor;

    rval = LIFTING_2D_psi(n_halfspaces, halfspaces, r_ceil, &value_ceil);
    abort_if(rval, "LIFTING_2D_psi failed");

    rval = LIFTING_2D_psi(n_halfspaces, halfspaces, r_floor, &value_floor);
    abort_if(rval, "LIFTING_2D_psi failed");

    *opt = min(value_ceil, value_floor);

CLEANUP:
    return rval;
}
示例#15
0
static int
check_long (model_t model, int g, int *src, TransitionCB cb, void *context)
{
    check_ctx_t    *ctx = GBgetContext (model);
    int             count;
    int             found;

    // collect
    ctx->src = src;
    ctx->group = g;
    ctx->user_cb = cb;
    ctx->user_ctx = context;
    ci_clear (ctx->check_must);
    isba_discard_int (ctx->stack, isba_size_int(ctx->stack));
    HREassert (!ctx->reentrent, "INTERFACE ERROR: GBgetTransitions* is not re-entrant");
    ctx->reentrent = 1;
    count = GBgetTransitionsLong (ctx->parent, g, src, collect, ctx);
    ctx->reentrent = 0;
    found = isba_size_int(ctx->stack);
    abort_if (count != found, "Wrong count returned by GBnextLong(collect): %d (Found: %d).",
              count, found);

    // compare
    ctx->src2 = copy_vec (ctx, g, src);
    ctx->comparison_failed = false;
    ctx->call_idx = 0;
    count = GBgetTransitionsLong (ctx->parent, g, ctx->src2, compare, ctx);
    abort_if (count != ctx->call_idx , "Wrong count returned by GBnextLong(compare): %d (Found: %d).",
              count, ctx->call_idx );

    if (ctx->call_idx != found || ctx->comparison_failed) {
        find_culprit_slot (ctx, g);
    }

    return count;
}
示例#16
0
TEST(Greedy2DTest, test_compute_bounds_3)
{
    int rval = 0;
    double bounds[100];
    double f[] = {5 / 22.0, 0.0};
    double rays[] = {-1 / 22.0, 0.0, 0.0, 1 / 18.0, 1 / 22.0, 0.0};

    rval = GREEDY_2D_compute_bounds(rays, 3, f, bounds);
    abort_if(rval, "GREEDY_2D_compute_bounds failed");

    EXPECT_NEAR(5.0, bounds[0], BOUNDS_EPSILON);
    EXPECT_NEAR(17.0, bounds[2], BOUNDS_EPSILON);
    EXPECT_EQ(GREEDY_BIG_E, bounds[1]);

    CLEANUP:
    if (rval) FAIL();
}
示例#17
0
TEST(Greedy2DTest, test_compute_bounds_2)
{
    int rval = 0;
    double bounds[100];
    double f[] = {1 / 2.0, 1 / 2.0};
    double rays[] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 0.0};

    rval = GREEDY_2D_compute_bounds(rays, 5, f, bounds);
    abort_if(rval, "GREEDY_2D_compute_bounds failed");

    EXPECT_NEAR(0.5, bounds[0], BOUNDS_EPSILON);
    EXPECT_NEAR(0.5, bounds[1], BOUNDS_EPSILON);
    EXPECT_NEAR(0.5, bounds[2], BOUNDS_EPSILON);
    EXPECT_NEAR(0.5, bounds[3], BOUNDS_EPSILON);
    EXPECT_EQ(GREEDY_BIG_E, bounds[4]);

    CLEANUP:
    if (rval) FAIL();
}
示例#18
0
TEST(Greedy2DTest, test_compute_bounds_1)
{
    int rval = 0;
    double bounds[100];
    double f[] = {1 / 4.0, 3 / 4.0};
    double rays[] = {-2 / 5.0, 5 / 7.0, 0.0, 1.0, 1.0, 1.0, 4 / 5.0, -2 / 3.0,
            -1.0, 0.0};

    rval = GREEDY_2D_compute_bounds(rays, 5, f, bounds);
    abort_if(rval, "GREEDY_2D_compute_bounds failed");

    EXPECT_NEAR(23 / 50.0, bounds[0], BOUNDS_EPSILON);
    EXPECT_NEAR(23 / 42.0, bounds[1], BOUNDS_EPSILON);
    EXPECT_NEAR(9 / 11.0, bounds[2], BOUNDS_EPSILON);
    EXPECT_NEAR(9 / 11.0, bounds[3], BOUNDS_EPSILON);
    EXPECT_NEAR(23 / 50.0, bounds[4], BOUNDS_EPSILON);

    CLEANUP:
    if (rval) FAIL();
}
示例#19
0
static void
find (void *context, transition_info_t *ti, int *dst2, int *cpy)
{
    check_ctx_t        *ctx = (check_ctx_t *) context;

    abort_if (ti->group != ctx->group,
              "Transition info does not return correct group for group %d (found: %d)",
              ctx->group, ti->group);

    int                *dst = isba_index (ctx->stack, ctx->call_idx++);
    int                 idx = find_diff (ctx, dst, dst2);
    ctx->comparison_failed |= ( idx != ctx->N );

    int             found = isba_size_int(ctx->stack);
    if (!ctx->comparison_failed && found == ctx->call_idx) {
        report ("Read dependency missing", ctx, ctx->group, ctx->idx, ctx->src2, ti);
    }

    (void) cpy;
}
示例#20
0
文件: lifting.c 项目: iSoron/multirow
int LIFTING_2D_naive(int n_halfspaces,
                     const double *halfspaces,
                     const double *ray,
                     const int *lb,
                     const int *ub,
                     double *value)
{
    int rval = 0;

    *value = INFINITY;
    int best_k0 = 0;
    int best_k1 = 0;

    int margin = 10;

    for(int k0 = lb[0] - margin; k0 <= ub[0] + margin; k0++)
    {
        for(int k1 = lb[1] - margin; k1 <= ub[1] + margin; k1++)
        {
            double q[2] = { ray[0] + k0, ray[1] + k1 };
            double value_q;

            rval = LIFTING_2D_psi(n_halfspaces, halfspaces, q, &value_q);
            abort_if(rval, "LIFTING_2D_ps failed");

            if(value_q < *value)
            {
                best_k0 = k0;
                best_k1 = k1;
                *value = value_q;
                log_debug("  k=%6d %6d value=%12.6lf\n", k0, k1, *value);
            }
        }
    }

//    log_debug("      best_k=(%d %d) value=%.6lf\n", best_k0, best_k1, *value);

CLEANUP:
    return rval;
}
示例#21
0
int RANDOMIZER_generate_triangle(double *f,
                                 double *vertices,
                                 double *lattice_points)
{
    int rval = 0;

    srand((unsigned int) time(0));

    f[0] = DOUBLE_random(0.0, 1.0);
    f[1] = DOUBLE_random(0.0, 1.0);

    double rays[6] = {
            DOUBLE_random(0, 1000.0), DOUBLE_random(0, 1000.0),
            DOUBLE_random(-1000.0, 0), DOUBLE_random(0, 1000.0),
            0, DOUBLE_random(-1000.0, 0)
    };

    log_verbose("r1=%12.8lf %12.8lf\n", rays[0], rays[1]);
    log_verbose("r2=%12.8lf %12.8lf\n", rays[2], rays[3]);
    log_verbose("r3=%12.8lf %12.8lf\n", rays[4], rays[5]);

    double bounds[6];

    rval = GREEDY_2D_compute_bounds(rays, 3, f, bounds);
    abort_if(rval, "GREEDY_2D_compute_bounds failed");

    for (int i = 0; i < 3; i++)
    {
        double *v = &vertices[2 * i];
        double *r = &rays[2 * i];

        v[0] = bounds[i] * r[0] + f[0];
        v[1] = bounds[i] * r[1] + f[1];
    }

CLEANUP:
    return rval;
}
示例#22
0
static void
compare (void *context, transition_info_t *ti, int *dst2, int *cpy)
{
    check_ctx_t        *ctx = (check_ctx_t *) context;

    abort_if (ti->group != ctx->group,
              "Transition info does not return correct group for group %d (found: %d)",
              ctx->group, ti->group);

    int                *dst = isba_index (ctx->stack, ctx->call_idx++);
    int                 idx = find_diff (ctx, dst, dst2);
    ctx->comparison_failed |= ( idx != ctx->N );

    if (ctx->comparison_failed && isba_size_int(ctx->stack) == (size_t)ctx->call_idx) {
        dbg_found_read_dep_error (ctx, dst, dst2, idx);
    }

    for (int *i = ci_begin (ctx->check_must); i != ci_end (ctx->check_must); i++) {
        if (ctx->src2[*i] != ctx->src[*i] && dst2[*i] == ctx->src2[*i]) {
            report ("Must write dependency violated", ctx, ctx->group, *i, ctx->src, ti);
        }
    }
    (void) cpy;
}
示例#23
0
static void
collect (void *context, transition_info_t *ti, int *dst, int *cpy)
{
    check_ctx_t        *ctx = (check_ctx_t *) context;

    abort_if (ti->group != ctx->group,
              "Transition info does not return correct group for group %d (found: %d)",
              ctx->group, ti->group);

    for (int i = 0; i < ctx->N; i++) {
         if (!dm_is_set(ctx->may, ctx->group, i) && ctx->src[i] != dst[i]) {
             report("May write dependency missing", ctx, ctx->group, i, dst, ti);
         }
    }

    ctx->user_cb (ctx->user_ctx, ti, dst, cpy);

    ci_list            *row = ctx->must[ctx->group];
    for (int *i = ci_begin (row); i != ci_end (row); i++) {
        if (dst[*i] == ctx->src[*i]) ci_add (ctx->check_must, *i);
    } // in second round we recheck

    isba_push_int (ctx->stack, dst);
}
示例#24
0
文件: main.c 项目: iSoron/multirow
static int parse_args(int argc,
                      char **argv)
{
    int rval = 0;
    opterr = 0;

    while (1)
    {
        int c = 0;
        int option_index = 0;
        c = getopt_long(argc, argv, "hb:k:s:f:o:nupew:c:a:m", options_tab,
                        &option_index);

        if (c < 0) break;

        switch (c)
        {
        case 'l':
            strcpy(LOG_FILENAME, optarg);
            break;

        case 's':
        {
            int count = sscanf(optarg, "%u", &SEED);
            abort_if(count != 1, "invalid seed");
            break;
        }

        case 'a':
        {
            int count = sscanf(optarg, "%d", &N_SAMPLES_PER_SET);
            abort_if(count != 1, "invalid number of samples");
            abort_if(N_SAMPLES_PER_SET <= 0, "invalid number of samples");
            break;
        }

        case 'f':
        {
            USE_FIXED_BOUNDS = 1;
            int count = sscanf(optarg, "%d", &NAIVE_BIG_M);
            abort_if(count != 1, "invalid fixed bound");
            break;
        }

        case 'o':
            strcpy(STATS_FILENAME, optarg);
            break;

        case 'b':
            strcpy(SETS_FILENAME, optarg);
            break;

        case 'w':
            strcpy(ANSWERS_FILENAME, optarg);
            WRITE_ANSWERS = 1;
            break;

        case 'c':
            strcpy(ANSWERS_FILENAME, optarg);
            CHECK_ANSWERS = 1;
            break;

        case 'n':
            SELECT_NAIVE_ALGORITHM = 1;
            break;

        case 'm':
            SELECT_MIP_ALGORITHM = 1;
            break;

        case 'u':
            SELECT_BOUND_ALGORITHM = 1;
            break;

        case 'p':
            ENABLE_PREPROCESSING = 1;
            break;

        case 'e':
            ENABLE_SHEAR = 1;
            break;

        case 'h':
            print_usage(argv);
            exit(0);

        case ':':
            fprintf(stderr, "%s: option '-%c' requires an argument\n",
                    argv[0], optopt);
            rval = 1;
            goto CLEANUP;

        case '?':
        default:
            fprintf(stderr, "%s: option '-%c' is invalid\n", argv[0],
                    optopt);
            rval = 1;
            goto CLEANUP;

        }
    }

    if ((strlen(SETS_FILENAME) == 0))
    {
        fprintf(stderr, "You must specify a file containing the lattice-free "
                "sets.\n");
        rval = 1;
    }

    if (SELECT_NAIVE_ALGORITHM + SELECT_BOUND_ALGORITHM + SELECT_MIP_ALGORITHM != 1)
    {
        fprintf(stderr, "You must select exactly one algorithm.\n");
        rval = 1;
    }

    if (CHECK_ANSWERS + WRITE_ANSWERS > 1)
    {
        fprintf(stderr, "Cannot write and check answers at same time.\n");
        rval = 1;
    }

CLEANUP:
    if (rval)
        fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
    return rval;
}
示例#25
0
文件: main.c 项目: iSoron/multirow
int benchmark_set_sample(int algorithm,
                         int set_idx,
                         const struct LFreeSet2D *set,
                         const double *rays,
                         const double *pre_m,
                         const double center,
                         int *lb,
                         int *ub,
                         int current_sample,
                         int *wrong_answer)
{
    int rval = 0;

    for (int i = 0; i < N_RAYS; i++)
    {
        double ray[2] = { rays[2 * i], rays[2 * i + 1] };
        double value;

        if(ENABLE_PREPROCESSING)
        {
            double r0 = ray[0], r1 = ray[1];
            ray[0] = pre_m[0] * r0 + pre_m[2] * r1;
            ray[1] = pre_m[1] * r0 + pre_m[3] * r1;

            ray[0] = ray[0] - floor(set->f[0] + ray[0]);
            ray[1] = ray[1] + floor(center + 0.5 - set->f[1] - ray[1]);
        }

        log_debug("    Ray %d (%.6lf,%.6lf)...\n", i, ray[0], ray[1]);

        switch (algorithm)
        {
        case ALGORITHM_BOUND:
            rval = LIFTING_2D_bound(set->n_halfspaces, set->halfspaces, ray,
                                    &value);
            abort_if(rval, "LIFTING_2D_bound failed");
            break;

        case ALGORITHM_NAIVE:
            rval = LIFTING_2D_naive(set->n_halfspaces, set->halfspaces, ray,
                                    lb, ub, &value);
            abort_if(rval, "LIFTING_2D_naive failed");
            break;

        case ALGORITHM_MIP:
            rval = LIFTING_2D_mip(set->n_halfspaces, set->halfspaces, ray,
                                  &value);
            abort_if(rval, "LIFTING_2D_mip failed");
            break;

        default:
            abort_if(1, "Invalid algorithm");
        }

        if(current_sample == 0)
        {
            if(WRITE_ANSWERS)
            {
                abort_iff(!DOUBLE_geq(value, 0),
                          "value should be non-negative (%.8lf)", value);
                fprintf(ANSWERS_FILE, "%d %d %.20lf\n", set_idx, i, value);
            }

            if(CHECK_ANSWERS)
            {
                int count;
                int expected_set_idx, expected_i;
                double expected_value;

                while(1)
                {
                    count = fscanf(ANSWERS_FILE, "%d %d %lf ",
                                   &expected_set_idx, &expected_i, &expected_value);

                    abort_if(count != 3, "error reading answer");
                    if(set_idx == expected_set_idx && i == expected_i) break;
                }

                double delta = fabs(value - expected_value);
                if(delta > 1e-3)
                {
                    log_warn("    wrong answer (set=%d ray=%d answer=%.8lf"
                             " expected=%.8lf delta=%.8lf)\n", set_idx,
                             i, value, expected_value, delta);
                    *wrong_answer = 1;

                    LFREE_2D_print_set(set);
                }
            }

            log_verbose("       %4d %12.8lf\n", j, value);
        }
    }

CLEANUP:
    return rval;
}
示例#26
0
int create_greedy_lp(int nrows,
                            int nrays,
                            const double *f,
                            const double *rays,
                            const double *bounds,
                            double e,
                            struct LP *lp)
{
    int rval = 0;

    double rhs;
    char sense;

    int rmatbeg = 0;
    int* rmatind = 0;
    double *rmatval = 0;

    rmatind = (int *) malloc((nrows + nrays) * sizeof(int));
    rmatval = (double *) malloc((nrows + nrays) * sizeof(double));
    abort_if(!rmatind, "could not allocate rmatind");
    abort_if(!rmatval, "could not allocate rmatval");

    rval = LP_create(lp, "greedy");
    abort_if(rval, "LP_create failed");

    // create x (basic) variables
    for (int i = 0; i < nrows; i++)
    {
        rval = LP_new_col(lp, 0, -MILP_INFINITY, MILP_INFINITY, 'I');
        abort_if(rval, "LP_new_col failed");
    }

    // create s (non-basic) variables
    for (int i = 0; i < nrays; i++)
    {
        rval = LP_new_col(lp, 1.0, 0, MILP_INFINITY, 'C');
        abort_if(rval, "LP_new_col failed");
    }

    // add constraint \sum_{i=1}^m s_i \leq 1
    sense = 'L';
    rhs = 1.0;

    for (int i = 0; i < nrays; i++)
    {
        rmatind[i] = i + nrows;
        rmatval[i] = 1.0;
    }

    rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, rmatval);
    abort_if(rval, "LP_add_rows failed");

    // add constraints x_i - \sum_{j=1}^m min{e,e_j} s_j R_ji = f_i
    for (int i = 0; i < nrows; i++)
    {
        int k = 0;
        sense = 'E';
        rhs = f[i];

        rmatind[k] = i;
        rmatval[k] = 1.0;
        k++;

        for (int j = 0; j < nrays; j++)
        {
            rmatind[k] = j + nrows;
            rmatval[k] = -rays[nrows * j + i] * fmin(e, bounds[j]);
            k++;
        }

        rval = LP_add_rows(lp, 1, nrays + 1, &rhs, &sense, &rmatbeg, rmatind,
                           rmatval);
        abort_if(rval, "LP_add_rows failed");
    }

CLEANUP:
    if (rmatind) free(rmatind);
    if (rmatval) free(rmatval);
    return rval;
}
示例#27
0
文件: flow.c 项目: iSoron/gtsp
int static find_augmenting_path(
        const struct Graph *graph,
        const double *residual_caps,
        struct Node *from,
        struct Node *to,
        int *path_length,
        struct Edge **path_edges,
        double *path_capacity)
{
    int rval = 0;

    struct Node **queue = 0;
    int queue_start = 0;
    int queue_end = 0;

    struct Node **parents = 0;
    struct Edge **parent_edges = 0;

    int node_count = graph->node_count;

    queue = (struct Node **) malloc(node_count * sizeof(struct Node *));
    parents = (struct Node **) malloc(node_count * sizeof(struct Node *));
    parent_edges = (struct Edge **) malloc(node_count * sizeof(struct Edge *));

    abort_if(!queue, "could not allocate queue");
    abort_if(!parents, "could not allocate parents");
    abort_if(!parent_edges, "could not allocate parent_edges");

    for (int i = 0; i < node_count; i++)
        graph->nodes[i].mark = 0;

    int found = 0;
    queue[queue_end++] = from;

    while (queue_end > queue_start)
    {
        struct Node *n = queue[queue_start++];

        n->mark = 1;

        for (int i = 0; i < n->degree; i++)
        {
            struct Node *neighbor = n->adj[i].neighbor;
            struct Edge *edge = n->adj[i].edge;

            if (neighbor->mark > 0) continue;
            if (residual_caps[edge->index] < EPSILON) continue;

            parents[neighbor->index] = n;
            parent_edges[neighbor->index] = edge;

            queue[queue_end++] = neighbor;
            neighbor->mark = 1;

            if (neighbor == to)
            {
                found = 1;
                break;
            }
        }

        if (found) break;
    }

    *path_length = 0;
    *path_capacity = DBL_MAX;

    if (queue_end == queue_start) goto CLEANUP;

    struct Node *n = to;
    while (n != from)
    {
        struct Edge *edge = parent_edges[n->index];
        path_edges[*path_length] = edge;

        double c = residual_caps[edge->index];
        if (c < *path_capacity) *path_capacity = c;

        n = parents[n->index];
        (*path_length)++;
    }

    CLEANUP:
    if (parents) free(parents);
    if (parent_edges) free(parent_edges);
    if (queue) free(queue);
    return rval;
}
示例#28
0
文件: flow.c 项目: iSoron/gtsp
int flow_find_max_flow(
        const struct Graph *digraph,
        const double *capacities,
        struct Node *from,
        struct Node *to,
        double *flow,
        double *value)
{
    int rval = 0;

    FLOW_MAX_FLOW_COUNT++;

    for (int i = 0; i < digraph->node_count; i++)
        digraph->nodes[i].mark = 0;

    log_verbose("Solving flow problem:\n");

    log_verbose("%d %d\n", digraph->node_count, digraph->edge_count);
    log_verbose("%d %d\n", from->index, to->index);
    for (int i = 0; i < digraph->edge_count; i++)
            log_verbose("%d %d %.4lf\n", digraph->edges[i].from->index,
                    digraph->edges[i].to->index, capacities[i]);

    int path_length = 0;
    double path_capacity = 0;
    double *residual_caps = 0;
    struct Edge **path_edges = 0;

    residual_caps = (double *) malloc(digraph->edge_count * sizeof(double));
    abort_if(!residual_caps, "could not allocate residual_caps");

    path_edges = (struct Edge **) malloc(
            digraph->edge_count * sizeof(struct Edge *));
    abort_if(!path_edges, "could not allocate path_edges");

    for (int i = 0; i < digraph->edge_count; i++)
    {
        flow[i] = 0;
        residual_caps[i] = capacities[i];
        abort_if(!digraph->edges[i].reverse,
                "digraph must have reverse edge information");
        abort_if(digraph->edges[i].reverse->reverse != &digraph->edges[i],
                "invalid reverse edge");
    }

    *value = 0;

    while (1)
    {
        find_augmenting_path(digraph, residual_caps, from, to, &path_length,
                path_edges, &path_capacity);

        if (path_length == 0) break;

        log_verbose("Found augmenting path of capacity %.4lf:\n",
                path_capacity);

        (*value) += path_capacity;

        for (int i = 0; i < path_length; i++)
        {
            struct Edge *e = &digraph->edges[path_edges[i]->index];

            log_verbose("  %d %d (%d)\n", e->from->index, e->to->index,
                    e->index);

            residual_caps[e->index] -= path_capacity;
            residual_caps[e->reverse->index] += path_capacity;

            flow[e->index] += path_capacity;
            flow[e->reverse->index] -= path_capacity;
        }

#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
        log_verbose("New residual capacities:\n");
        for (int i = 0; i < digraph->edge_count; i++)
        {
            struct Edge *e = &digraph->edges[i];

            if (residual_caps[i] < EPSILON) continue;

            log_verbose("%d %d %.4lf (%d)\n", e->from->index, e->to->index,
                    e->index, residual_caps[e->index]);
        }
#endif
    }

    log_verbose("No more paths found.\n");

    rval = mark_reachable_nodes(digraph, residual_caps, from);
    abort_if(rval, "mark_reachable_nodes failed");

    CLEANUP:
    if (path_edges) free(path_edges);
    if (residual_caps) free(residual_caps);
    return rval;
}
示例#29
0
int GREEDY_BSEARCH_compute_bounds(int nrows,
                                  int nrays,
                                  const double *f,
                                  const double *rays,
                                  double *bounds)
{
    int rval = 0;

    struct LP lp;
    double e_upper = 2 * GREEDY_BIG_E;
    double e_lower = 0.0;

    int cplex_count = 0;
    double cplex_time = 0;

    int iteration_count = 0;

    double *x = 0;

    x = (double *) malloc((nrays + nrows) * sizeof(double));
    abort_if(!x, "could not allocate x");

    for (int i = 0; i < nrays; i++)
        bounds[i] = GREEDY_BIG_E;

    for (int it = 0;; it++)
    {
        abort_if(it > 2*nrays, "stuck in an infinite loop");

        log_verbose("Starting iteration %d...\n", it);

        iteration_count++;


        int solution_found = 0;
        int inner_count = 0;

        while (fabs(e_upper - e_lower) > GREEDY_MAX_GAP)
        {
            inner_count++;

            double e = (e_upper + e_lower) / 2;
            log_verbose("    e=%.12lf\n", e);

            rval = LP_open(&lp);
            abort_if(rval, "LP_open failed");

            rval = create_greedy_lp(nrows, nrays, f, rays, bounds, e, &lp);
            abort_if(rval, "create_greedy_lp failed");

            if_verbose_level
            {
                rval = LP_write(&lp, "greedy.lp");
                abort_if(rval, "LP_write failed");
            }

            int infeasible;
            cplex_count++;

            double initial_time = get_user_time();

            log_verbose("    Optimizing...\n");
            rval = LP_optimize(&lp, &infeasible);
            if (rval)
            {
                // Workaround for CPLEX bug. If CPLEX tell us that this problem
                // is unbounded, we disable presolve and try again.
                LP_free(&lp);
                LP_open(&lp);

                rval = create_greedy_lp(nrows, nrays, f, rays, bounds, e, &lp);
                abort_if(rval, "create_greedy_lp failed");

                LP_disable_presolve(&lp);

                rval = LP_optimize(&lp, &infeasible);
                abort_if(rval, "LP_optimize failed");
            }

            cplex_time += get_user_time() - initial_time;

            if (infeasible)
            {
                e_lower = e;
                log_verbose("    infeasible\n");
                if (e > GREEDY_BIG_E-1)
                {
                    LP_free(&lp);
                    goto OUT;
                }
            }
            else
            {
                log_verbose("    feasible\n");
                e_upper = e;
                solution_found = 1;

                rval = LP_get_x(&lp, x);
                abort_if(rval, "LP_get_x failed");
            }

            LP_free(&lp);
        }

        if (solution_found)
        {
            for (int j = 0; j < nrays; j++)
            {
                if (!DOUBLE_geq(x[nrows + j], 0.001)) continue;
                bounds[j] = fmin(bounds[j] * 0.99, e_lower * 0.99);
            }
        }

        log_verbose("    %d iterations  %12.8lf gap\n", inner_count, e_upper -
                    e_lower);

        e_lower = e_upper;
        e_upper = 2 * GREEDY_BIG_E;
    }

OUT:
    log_debug("    %6d IPs (%.2lfms per call, %.2lfs total)\n", cplex_count,
                cplex_time * 1000.0 / cplex_count, cplex_time);

    for(int i = 0; i < nrays; i++)
        abort_if(DOUBLE_iszero(bounds[i]), "bounds should be positive");

    if_verbose_level
    {
        time_printf("Bounds:\n");
        for (int k = 0; k < nrays; k++)
            time_printf("    %12.8lf  %12.8lf\n", k, bounds[k], 1 / bounds[k]);
    }

CLEANUP:
    if (x) free(x);
    return rval;
}
示例#30
0
文件: main.c 项目: iSoron/multirow
int main(int argc, char **argv)
{
    int rval = 0;
    double *rays = 0;
    struct LFreeSet2D sets[MAX_N_SETS];

    rval = parse_args(argc, argv);
    if (rval) return 1;

    print_header(argc, argv);

    if (LOG_FILENAME[0])
    {
        LOG_FILE = fopen(LOG_FILENAME, "w");
        abort_if(!LOG_FILE, "could not open log file");
        log_info("Writing log to file: %s\n", LOG_FILENAME);
    }

    if (STATS_FILENAME[0])
    {
        STATS_FILE = fopen(STATS_FILENAME, "w");
        abort_if(!STATS_FILE, "could not open stats file");
        log_info("Writing stats to file: %s\n", STATS_FILENAME);
    }

    if (WRITE_ANSWERS)
    {
        N_SAMPLES_PER_SET = 1;
        ANSWERS_FILE = fopen(ANSWERS_FILENAME, "w");
        abort_if(!ANSWERS_FILE, "could not open answers file");
        log_info("Writing answers to file: %s\n", ANSWERS_FILENAME);
    }

    if (CHECK_ANSWERS)
    {
        ANSWERS_FILE = fopen(ANSWERS_FILENAME, "r");
        abort_if(!ANSWERS_FILE, "could not open answers file");
        log_info("Reading answers from file: %s\n", ANSWERS_FILENAME);
    }

    if(SEED == 0)
    {
        struct timeval t1;
        gettimeofday(&t1, NULL);
        SEED = (unsigned int) (t1.tv_usec * t1.tv_sec) % 10000;
    }

    log_info("Random seed: %u\n", SEED);
    srand(SEED);

    log_info("Generating %d random rays...\n", N_RAYS);

    rays = (double*) malloc(2 * N_RAYS * sizeof(double));
    abort_if(!rays, "could not allocate rays");

    for (int i = 0; i < N_RAYS; i++)
    {
        double *ray = &rays[2 * i];
        ray[0] = DOUBLE_random(0.0, 1.0);
        ray[1] = DOUBLE_random(0.0, 1.0);
    }

    int algorithm = ALGORITHM_BOUND;
    if(SELECT_MIP_ALGORITHM) algorithm = ALGORITHM_MIP;
    else if(SELECT_NAIVE_ALGORITHM) algorithm = ALGORITHM_NAIVE;

    if(algorithm == ALGORITHM_NAIVE)
    {
        log_info("Enabling naive algorithm\n");

        if(USE_FIXED_BOUNDS)
            log_info("Using fixed big M: %d\n", NAIVE_BIG_M);
        else
            log_info("Enabling bounding boxes\n");
    }
    else
    {
        log_info("Enabling bound algorithm\n");
    }

    log_info("Setting %d samples per set\n", N_SAMPLES_PER_SET);

    if(ENABLE_PREPROCESSING)
        log_info("Enabling pre-processing\n");

    log_info("Reading sets from file...\n");
    FILE *sets_file = fopen(SETS_FILENAME, "r");
    abort_iff(!sets_file, "could not read file %s", SETS_FILENAME);

    int line = 0;
    int n_sets = 0;
    while(!feof(sets_file))
    {
        line++;
        struct LFreeSet2D *set = &sets[n_sets];
        LFREE_2D_init(set, 4, 4, 4);

        rval = LFREE_2D_read_next(sets_file, set);
        abort_iff(rval, "LFREE_2D_read_next failed (line %d)", line);

        if(ENABLE_SHEAR)
        {
            double m[4] = { 51.0, 5.0, 10.0, 1.0 };
            rval = LFREE_2D_transform_set(set, m);
            abort_iff(rval, "LFREE_2D_transform_set failed (line %d)", line);
        }

        double dx = -floor(set->f[0]);
        double dy = -floor(set->f[1]);
        rval = LFREE_2D_translate_set(set, dx, dy);
        abort_iff(rval, "LFREE_2D_translate_set failed (line %d)", line);

        if(ENABLE_PREPROCESSING)
        {
            double *pre_m = &PRE_M[n_sets * 4];
            double *center = &CENTER[n_sets];
            rval = LFREE_2D_preprocess(set, pre_m, center);
            abort_iff(rval, "LFREE_2D_preprocess failed (line %d)", line);
        }

        rval = LFREE_2D_compute_halfspaces(set);
        abort_iff(rval, "LFREE_2D_compute_halfspaces failed (line %d)", line);

        rval = LFREE_2D_verify(set);
        if(rval)
        {
            log_warn("    skipping invalid set on line %d\n", line);
            continue;
        }

        n_sets++;
        if(n_sets >= MAX_N_SETS) break;
    }

    fclose(sets_file);
    log_info("Successfully read %d sets\n", n_sets);

    rval = benchmark(n_sets, sets, rays, algorithm);
    abort_if(rval, "benchmark failed");

    log_info("Done.\n");

CLEANUP:
    if (LOG_FILE) fclose(LOG_FILE);
    if (STATS_FILE) fclose(STATS_FILE);
    if (ANSWERS_FILE) fclose(ANSWERS_FILE);
    if (rays) free(rays);
    return rval;
}