Skip to content

Commit

Permalink
solution: introduce modification neighbourhood iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
Astronomax committed Oct 1, 2024
1 parent 98f9fdb commit 324dc6a
Show file tree
Hide file tree
Showing 31 changed files with 386 additions and 82 deletions.
7 changes: 4 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,18 @@ set (sources
src/c_penalty.c
src/customer.c
src/distance.c
src/ejection.c
src/ejection.c
src/modification.c
src/problem.c
src/random_utils.c
src/route.c
src/solution.c
src/solution.cc
src/tw_penalty.c
src/main.c
)

add_executable(routes ${sources})
target_compile_options(routes PRIVATE -Wall -Wextra -Wpedantic)
target_compile_options(routes PRIVATE -Wall -Wextra -Wpedantic -Wno-gnu-statement-expression)
target_link_libraries(routes small core)

add_subdirectory(test)
9 changes: 9 additions & 0 deletions src/c_penalty.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
struct customer;
struct route;

#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */

void
c_penalty_init(struct route *r);

Expand Down Expand Up @@ -61,4 +65,9 @@ c_penalty_out_relocate_penalty_delta(struct customer *v, struct customer *w);
double
c_penalty_exchange_penalty_delta(struct customer *v, struct customer *w);

#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */


#endif //EAMA_ROUTES_MINIMIZATION_HEURISTIC_C_PENALTY_H
2 changes: 1 addition & 1 deletion src/customer.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ customer_dup(struct customer *c)
void
customer_del(struct customer *c) {
free(c); //TODO: return back to mempool
}
}
2 changes: 2 additions & 0 deletions src/customer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ struct customer {
struct rlist in_eject;
};

#define is_ejected(c) rlist_empty(&c->in_route)

struct customer *
customer_dup(struct customer *c);

Expand Down
2 changes: 1 addition & 1 deletion src/distance.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,4 @@ distance_exchange_distance_delta(struct customer *v, struct customer *w)
- (dist(w_minus, w) + dist(v, v_plus));
return distance_get_replace_delta(v, w)
+ distance_get_replace_delta(w, v);
}
}
2 changes: 1 addition & 1 deletion src/ejection.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* while iterating through feasible ejections.
*/ \
double a_temp; \
double a_quote;
double a_quote

/**
* @brief Iterate over feasible ejections (a subsets of route customers such
Expand Down
19 changes: 18 additions & 1 deletion src/lib/core/fiber.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,17 @@ fiber_yield(void)
fiber_yield_impl();
}

void
fiber_gc(void)
{
if (region_used(&fiber()->gc) < 128 * 1024) {
region_reset(&fiber()->gc);
return;
}

region_free(&fiber()->gc);
}

/** Destroy an active fiber and prepare it for reuse or delete it. */
static void
fiber_recycle(struct fiber *fiber)
Expand All @@ -233,6 +244,7 @@ fiber_recycle(struct fiber *fiber)
/* no exceptions are leaking */
assert(diag_is_empty(&fiber->diag));
fiber->f = NULL;
region_free(&fiber->gc);
if (fiber_is_reusable(fiber->flags)) {
rlist_move_entry(&cord()->dead, fiber, link);
} else {
Expand Down Expand Up @@ -402,6 +414,8 @@ fiber_new_ex(const struct fiber_attr *fiber_attr, fiber_func f)
coro_create(&fiber->ctx, fiber_loop, NULL,
fiber->stack, fiber->stack_size);

region_create(&fiber->gc, &cord->slabc);

diag_create(&fiber->diag);

rlist_add_entry(&cord->alive, fiber, link);
Expand Down Expand Up @@ -436,6 +450,7 @@ fiber_destroy(struct cord *cord, struct fiber *f)
{
assert(f != cord->fiber);
rlist_del(&f->link);
region_destroy(&f->gc);
fiber_stack_destroy(f, &cord->slabc);
diag_destroy(&f->diag);
TRASH(f);
Expand Down Expand Up @@ -483,6 +498,7 @@ cord_create(struct cord *cord)
/* sched fiber is not present in alive/dead list. */
rlist_create(&cord->sched.link);
diag_create(&cord->sched.diag);
region_create(&cord->sched.gc, &cord->slabc);
cord->fiber = &cord->sched;
cord->sched.flags = FIBER_IS_RUNNING;

Expand Down Expand Up @@ -517,7 +533,8 @@ cord_destroy(struct cord *cord)
slab_cache_set_thread(&cord->slabc);
fiber_delete_all(cord);
cord->fiber = NULL;
fiber_destroy(cord, &cord->sched);
region_destroy(&cord->sched.gc);
diag_destroy(&cord->sched.diag);
slab_cache_destroy(&cord->slabc);
}

Expand Down
5 changes: 5 additions & 0 deletions src/lib/core/fiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ struct fiber {
void *stack;
/** Coro stack size. */
size_t stack_size;
/* A garbage-collected memory pool. */
struct region gc;
/**
* The fiber which should be scheduled when
* this fiber yields.
Expand Down Expand Up @@ -310,6 +312,9 @@ cord_collect_garbage(struct cord *cord);
void
fiber_init(int (*fiber_invoke)(fiber_func f, va_list ap));

void
fiber_gc(void);

void
fiber_call(struct fiber *callee);

Expand Down
27 changes: 5 additions & 22 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
#include "problem.h"
#include "customer.h"
#include "problem.h"
#include "solution.h"

#include "core/fiber.h"
#include "core/memory.h"

static int
test_fiber_f(va_list ap)
{
int n = va_arg(ap, int);
for (int i = 0; i < n; i++) {
printf("test_fiber_f\n");
fflush(stdout);
fiber_yield();
}
return 0;
}

int
main(int argc, char **argv)
{
global_problem_init();
solution_init();

memory_init();
fiber_init(fiber_c_invoke);
struct fiber *f = fiber_new(test_fiber_f);
fiber_start(f, 2);
while(!fiber_is_dead(f)) {
printf("main\n");
fflush(stdout);
fiber_call(f);
}
memory_free();
return 0;
}
}
2 changes: 1 addition & 1 deletion src/modification.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,4 @@ modification_delta(struct modification m, double alpha, double beta)
default:
unreachable();
}
}
}
10 changes: 9 additions & 1 deletion src/modification.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@

#include "customer.h"

#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */

enum modification_type {
TWO_OPT,
OUT_RELOCATE,
EXCHANGE,
INSERT,
EJECT,
modification_count
modification_max
};

struct modification {
Expand All @@ -28,4 +32,8 @@ modification_apply(struct modification m);
double
modification_delta(struct modification m, double alpha, double beta);

#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */

#endif //EAMA_ROUTES_MINIMIZATION_HEURISTIC_MODIFICATION_H
4 changes: 2 additions & 2 deletions src/problem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
struct problem p;

void
global_problem_init()
global_problem_init(void)
{
p.vc = 100.;
}
}
4 changes: 3 additions & 1 deletion src/problem.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "customer.h"
#include "small/rlist.h"

#define MAX_N_CUSTOMERS 2000

struct problem {
double vc;
struct customer *depot;
Expand All @@ -13,6 +15,6 @@ struct problem {

extern struct problem p;

void global_problem_init();
void global_problem_init(void);

#endif //EAMA_ROUTES_MINIMIZATION_HEURISTIC_PROBLEM_H
6 changes: 3 additions & 3 deletions src/random_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "utils.h"

void
random_subset(int *arr, int n, int k)
random_subset(struct customer **arr, int n, int k)
{
for (int i = 0; i < k; i++) {
int j = (int)pseudo_random_in_range(i, n - 1);
Expand All @@ -14,7 +14,7 @@ random_subset(int *arr, int n, int k)
}

void
random_shuffle(int *arr, int n)
random_shuffle(struct customer **arr, int n)
{
random_subset(arr, n, n - 1);
}
}
14 changes: 12 additions & 2 deletions src/random_utils.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#ifndef EAMA_ROUTES_MINIMIZATION_HEURISTIC_RANDOM_UTILS_H
#define EAMA_ROUTES_MINIMIZATION_HEURISTIC_RANDOM_UTILS_H

#include "customer.h"

#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */

void
random_subset(int *arr, int n, int k);
random_subset(struct customer **arr, int n, int k);

void
random_shuffle(int *arr, int n);
random_shuffle(struct customer **arr, int n);

#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */

#endif //EAMA_ROUTES_MINIMIZATION_HEURISTIC_RANDOM_UTILS_H
4 changes: 2 additions & 2 deletions src/route.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "route.h"

struct route *
route_new()
route_new(void)
{
struct route *r = malloc(sizeof(*r)); //TODO: use mempool
rlist_create(&r->list);
Expand Down Expand Up @@ -75,4 +75,4 @@ route_find_customer_by_id(struct route *r, int id)
if (id == c->id)
return c;
return NULL;
}
}
34 changes: 21 additions & 13 deletions src/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@

#include "customer.h"

#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */

struct route {
/**
* List of customers. Contract:
* rlist_first_entry(&list, in_route) ==
* rlist_last_entry(&list, in_route) ==
* p->depot
*/
struct rlist list;
struct rlist in_routes;
/**
* List of customers. Contract:
* rlist_first_entry(&list, in_route) ==
* rlist_last_entry(&list, in_route) ==
* p->depot
*/
struct rlist list;
struct rlist in_routes;
};

#define route_check(r) \
assert(rlist_first_entry(&r->list, struct customer, in_route)->id == 0); \
assert(rlist_last_entry(&r->list, struct customer, in_route)->id == 0)
assert(rlist_first_entry(&r->list, struct customer, in_route)->id == 0); \
assert(rlist_last_entry(&r->list, struct customer, in_route)->id == 0)

#define route_foreach(c, r) rlist_foreach_entry(c, &r->list, in_route)
#define route_foreach_from(c, from, r) \
for (c = from; !rlist_entry_is_head(c, &r->list, in_route); \
c = rlist_next_entry(c, in_route))
for (c = from; !rlist_entry_is_head(c, &r->list, in_route); \
c = rlist_next_entry(c, in_route))

#define depot_head(r) rlist_first_entry(&r->list, struct customer, in_route)
#define depot_tail(r) rlist_last_entry(&r->list, struct customer, in_route)
Expand All @@ -32,7 +36,7 @@ struct route {
#define route_next(c) rlist_next_entry(c, in_route)

struct route *
route_new();
route_new(void);

void
route_init(struct route *r, struct customer **arr, int n);
Expand All @@ -49,4 +53,8 @@ route_del(struct route *r);
struct customer *
route_find_customer_by_id(struct route *r, int id);

#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */

#endif //EAMA_ROUTES_MINIMIZATION_HEURISTIC_ROUTE_H
2 changes: 0 additions & 2 deletions src/solution.c

This file was deleted.

Loading

0 comments on commit 324dc6a

Please sign in to comment.