int coco_archive_add_solution(coco_archive_t *archive, const double f1, const double f2, const char *text) { coco_archive_avl_item_t* insert_item = coco_archive_node_item_create(f1, f2, text); double *insert_objectives, *node_objectives; avl_node_t *node, *next_node; int update = 0; int dominance; insert_objectives = coco_archive_node_item_get_vector(insert_item); /* Find the first point that is not worse than the new point (NULL if such point does not exist) */ node = avl_item_search_right(archive->tree, insert_item, NULL); if (node == NULL) { /* The new point is an extremal point */ update = 1; next_node = archive->tree->head; } else { node_objectives = coco_archive_node_item_get_vector((coco_archive_avl_item_t*) node->item); dominance = mo_get_dominance(insert_objectives, node_objectives, archive->number_of_objectives); coco_free_memory(node_objectives); if (dominance > -1) { update = 1; next_node = node->next; if (dominance == 1) { /* The new point dominates the next point, remove the next point */ avl_node_delete(archive->tree, node); } } else { /* The new point is dominated, nothing more to do */ update = 0; } } if (!update) { coco_archive_node_item_free(insert_item, NULL); } else { /* Perform tree update */ while (next_node != NULL) { /* Check the dominance relation between the new node and the next node. There are only two possibilities: * dominance = 0: the new node and the next node are nondominated * dominance = 1: the new node dominates the next node */ node = next_node; node_objectives = coco_archive_node_item_get_vector((coco_archive_avl_item_t*) node->item); dominance = mo_get_dominance(insert_objectives, node_objectives, archive->number_of_objectives); coco_free_memory(node_objectives); if (dominance == 1) { /* The new point dominates the next point, remove the next point */ next_node = node->next; avl_node_delete(archive->tree, node); } else { break; } } avl_item_insert(archive->tree, insert_item); archive->is_up_to_date = 0; } coco_free_memory(insert_objectives); return update; }
int coco_archive_add_solution(coco_archive_t *archive, const double y1, const double y2, const char *text) { coco_archive_avl_item_t* insert_item; avl_node_t *node, *next_node; int update = 0; int dominance; double *y = coco_allocate_vector(2); y[0] = y1; y[1] = y2; insert_item = coco_archive_node_item_create(y, archive->ideal, archive->nadir, archive->number_of_objectives, text); coco_free_memory(y); /* Find the first point that is not worse than the new point (NULL if such point does not exist) */ node = avl_item_search_right(archive->tree, insert_item, NULL); if (node == NULL) { /* The new point is an extreme point */ update = 1; next_node = archive->tree->head; } else { dominance = mo_get_dominance(insert_item->normalized_y, ((coco_archive_avl_item_t*) node->item)->normalized_y, archive->number_of_objectives); if (dominance > -1) { update = 1; next_node = node->next; if (dominance == 1) { /* The new point dominates the next point, remove the next point */ assert((node != archive->extreme1) && (node != archive->extreme2)); avl_node_delete(archive->tree, node); } } else { /* The new point is dominated or equal to an existing one, ignore */ update = 0; } } if (!update) { coco_archive_node_item_free(insert_item, NULL); } else { /* Perform tree update */ while (next_node != NULL) { /* Check the dominance relation between the new node and the next node. There are only two possibilities: * dominance = 0: the new node and the next node are nondominated * dominance = 1: the new node dominates the next node */ node = next_node; dominance = mo_get_dominance(insert_item->normalized_y, ((coco_archive_avl_item_t*) node->item)->normalized_y, archive->number_of_objectives); if (dominance == 1) { next_node = node->next; /* The new point dominates the next point, remove the next point */ assert((node != archive->extreme1) && (node != archive->extreme2)); avl_node_delete(archive->tree, node); } else { break; } } if(avl_item_insert(archive->tree, insert_item) == NULL) { coco_warning("Solution %s did not update the archive", text); update = 0; } archive->is_up_to_date = 0; } return update; }