/** * @brief Returns the problem from the bbob suite that corresponds to the given parameters. * * @param suite The COCO suite. * @param function_idx Index of the function (starting from 0). * @param dimension_idx Index of the dimension (starting from 0). * @param instance_idx Index of the instance (starting from 0). * @return The problem that corresponds to the given parameters. */ static coco_problem_t *suite_bbob_get_problem(coco_suite_t *suite, const size_t function_idx, const size_t dimension_idx, const size_t instance_idx) { coco_problem_t *problem = NULL; const size_t function = suite->functions[function_idx]; const size_t dimension = suite->dimensions[dimension_idx]; const size_t instance = suite->instances[instance_idx]; problem = coco_get_bbob_problem(function, dimension, instance); problem->suite_dep_function = function; problem->suite_dep_instance = instance; problem->suite_dep_index = coco_suite_encode_problem_index(suite, function_idx, dimension_idx, instance_idx); return problem; }
/** * Tests the function coco_suite_get_next_problem_index. */ static void test_coco_suite_encode_problem_index(void **state) { coco_suite_t *suite; size_t index; size_t function_idx = 13, dimension_idx = 0, instance_idx = 10; suite = coco_suite("bbob", NULL, NULL); expect_value(__wrap_coco_suite_encode_problem_index, function_idx, 13); expect_value(__wrap_coco_suite_encode_problem_index, dimension_idx, 0); expect_value(__wrap_coco_suite_encode_problem_index, instance_idx, 10); will_return(__wrap_coco_suite_encode_problem_index, 205); index = coco_suite_encode_problem_index(suite, function_idx, dimension_idx, instance_idx); assert_true(index == 205); coco_suite_free(suite); (void)state; /* unused */ }
/** * @brief Returns the problem from the toy suite that corresponds to the given parameters. * * @param suite The COCO suite. * @param function_idx Index of the function (starting from 0). * @param dimension_idx Index of the dimension (starting from 0). * @param instance_idx Index of the instance (starting from 0). * @return The problem that corresponds to the given parameters. */ static coco_problem_t *suite_toy_get_problem(coco_suite_t *suite, const size_t function_idx, const size_t dimension_idx, const size_t instance_idx) { coco_problem_t *problem = NULL; const size_t function = suite->functions[function_idx]; const size_t dimension = suite->dimensions[dimension_idx]; const size_t instance = suite->instances[instance_idx]; if (function == 1) { problem = f_sphere_allocate(dimension); } else if (function == 2) { problem = f_ellipsoid_allocate(dimension); } else if (function == 3) { problem = f_rastrigin_allocate(dimension); } else if (function == 4) { problem = f_bueche_rastrigin_allocate(dimension); } else if (function == 5) { double xopt[40] = { 5.0 }; problem = f_linear_slope_allocate(dimension, xopt); } else if (function == 6) { problem = f_rosenbrock_allocate(dimension); } else { coco_error("suite_toy_get_problem(): function %lu does not exist in this suite", function); return NULL; /* Never reached */ } problem->suite_dep_function = function; problem->suite_dep_instance = instance; problem->suite_dep_index = coco_suite_encode_problem_index(suite, function_idx, dimension_idx, instance_idx); return problem; }
/** * @brief Returns the problem from the bbob-biobj suite that corresponds to the given parameters. * * Creates the bi-objective problem by constructing it from two single-objective problems from the bbob * suite. If the invoked instance number is not in suite_biobj_instances, the function uses the following * formula to construct a new appropriate instance: * * problem1_instance = 2 * biobj_instance + 1 * * problem2_instance = problem1_instance + 1 * * If needed, problem2_instance is increased (see also the explanation of suite_biobj_get_new_instance). * * @param suite The COCO suite. * @param function_idx Index of the function (starting from 0). * @param dimension_idx Index of the dimension (starting from 0). * @param instance_idx Index of the instance (starting from 0). * @return The problem that corresponds to the given parameters. */ static coco_problem_t *suite_biobj_get_problem(coco_suite_t *suite, const size_t function_idx, const size_t dimension_idx, const size_t instance_idx) { const size_t num_bbob_functions = 10; /* Functions from the bbob suite that are used to construct the bi-objective problem. */ const size_t bbob_functions[] = { 1, 2, 6, 8, 13, 14, 15, 17, 20, 21 }; coco_problem_t *problem1, *problem2, *problem = NULL; size_t function1_idx, function2_idx; size_t instance1 = 0, instance2 = 0; const size_t function = suite->functions[function_idx]; const size_t dimension = suite->dimensions[dimension_idx]; const size_t instance = suite->instances[instance_idx]; suite_biobj_t *data = (suite_biobj_t *) suite->data; size_t i, j; const size_t num_existing_instances = sizeof(suite_biobj_instances) / sizeof(suite_biobj_instances[0]); int instance_found = 0; /* A "magic" formula to compute the BBOB function index from the bi-objective function index */ function1_idx = num_bbob_functions - coco_double_to_size_t( floor(-0.5 + sqrt(0.25 + 2.0 * (double) (suite->number_of_functions - function_idx - 1)))) - 1; function2_idx = function_idx - (function1_idx * num_bbob_functions) + (function1_idx * (function1_idx + 1)) / 2; /* First search for instance in suite_biobj_instances */ for (i = 0; i < num_existing_instances; i++) { if (suite_biobj_instances[i][0] == instance) { /* The instance has been found in suite_biobj_instances */ instance1 = suite_biobj_instances[i][1]; instance2 = suite_biobj_instances[i][2]; instance_found = 1; break; } } if ((!instance_found) && (data)) { /* Next, search for instance in new_instances */ for (i = 0; i < data->max_new_instances; i++) { if (data->new_instances[i][0] == 0) break; if (data->new_instances[i][0] == instance) { /* The instance has been found in new_instances */ instance1 = data->new_instances[i][1]; instance2 = data->new_instances[i][2]; instance_found = 1; break; } } } if (!instance_found) { /* Finally, if the instance is not found, create a new one */ if (!data) { /* Allocate space needed for saving new instances */ data = (suite_biobj_t *) coco_allocate_memory(sizeof(*data)); /* Most often the actual number of new instances will be lower than max_new_instances, because * some of them are already in suite_biobj_instances. However, in order to avoid iterating over * suite_biobj_instances, the allocation uses max_new_instances. */ data->max_new_instances = suite->number_of_instances; data->new_instances = (size_t **) coco_allocate_memory(data->max_new_instances * sizeof(size_t *)); for (i = 0; i < data->max_new_instances; i++) { data->new_instances[i] = (size_t *) malloc(3 * sizeof(size_t)); for (j = 0; j < 3; j++) { data->new_instances[i][j] = 0; } } suite->data_free_function = suite_biobj_free; suite->data = data; } /* A simple formula to set the first instance */ instance1 = 2 * instance + 1; instance2 = suite_biobj_get_new_instance(suite, instance, instance1, num_bbob_functions, bbob_functions); } problem1 = coco_get_bbob_problem(bbob_functions[function1_idx], dimension, instance1); problem2 = coco_get_bbob_problem(bbob_functions[function2_idx], dimension, instance2); problem = coco_problem_stacked_allocate(problem1, problem2); problem->suite_dep_function = function; problem->suite_dep_instance = instance; problem->suite_dep_index = coco_suite_encode_problem_index(suite, function_idx, dimension_idx, instance_idx); /* Use the standard stacked problem_id as problem_name and construct a new suite-specific problem_id */ coco_problem_set_name(problem, problem->problem_id); coco_problem_set_id(problem, "bbob-biobj_f%02d_i%02ld_d%02d", function, instance, dimension); /* Construct problem type */ coco_problem_set_type(problem, "%s_%s", problem1->problem_type, problem2->problem_type); return problem; }