nodeset_t nodeset_new_str (const char *s) { nodeset_t n = nodeset_new (); if (!nodeset_add_str (n, s)) { nodeset_destroy (n); return NULL; } return n; }
static ns_t *ns_guess (flux_t h) { ns_t *ns = xzmalloc (sizeof (*ns)); uint32_t size, rank; uint32_t r; if (flux_info (h, &rank, &size, NULL) < 0) err_exit ("flux_info"); ns->ok = nodeset_new (); ns->slow = nodeset_new (); ns->fail = nodeset_new (); ns->unknown = nodeset_new (); if (!ns->ok || !ns->slow || !ns->fail || !ns->unknown) oom (); nodeset_add_rank (ns->ok, rank); for (r = 0; r < size; r++) { if (r != rank) nodeset_add_rank (ns->unknown, r); } return ns; }
nodeset_t nodeset_new_rank (uint32_t r) { nodeset_t n = nodeset_new (); nodeset_add_rank (n, r); return n; }
nodeset_t nodeset_new_range (uint32_t a, uint32_t b) { nodeset_t n = nodeset_new (); nodeset_add_range (n, a, b); return n; }
struct a_star_path *a_star(void *context, void *start, void *goal, int maxnodes, a_star_node_cost_fn distance, a_star_node_cost_fn cost_estimate, a_star_neighbor_iterator_fn nth_neighbor) { struct nodeset *openset, *closedset; struct node_map *came_from; struct score_map *gscore, *fscore; void *neighbor, *current; float tentative_gscore; int i, n; void **answer = NULL; int answer_count = 0; struct a_star_path *return_value; closedset = nodeset_new(maxnodes); openset = nodeset_new(maxnodes); came_from = node_map_new(maxnodes); gscore = score_map_new(maxnodes); fscore = score_map_new(maxnodes); nodeset_add_node(openset, start); score_map_add_score(gscore, start, 0.0); score_map_add_score(fscore, start, cost_estimate(context, start, goal)); while (!nodeset_empty(openset)) { current = lowest_score(openset, fscore); if (current == goal) { reconstruct_path(came_from, current, &answer, &answer_count, maxnodes); break; } nodeset_remove_node(openset, current); nodeset_add_node(closedset, current); n = 0; while ((neighbor = nth_neighbor(context, current, n))) { n++; if (nodeset_contains_node(closedset, neighbor)) continue; tentative_gscore = score_map_get_score(gscore, current) + distance(context, current, neighbor); if (!nodeset_contains_node(openset, neighbor)) nodeset_add_node(openset, neighbor); else if (tentative_gscore >= score_map_get_score(gscore, neighbor)) continue; node_map_set_from(came_from, neighbor, current); score_map_add_score(gscore, neighbor, tentative_gscore); score_map_add_score(fscore, neighbor, score_map_get_score(gscore, neighbor) + cost_estimate(context, neighbor, goal)); } } free(closedset); free(openset); free(came_from); free(gscore); free(fscore); if (answer_count == 0) { return_value = NULL; } else { return_value = malloc(sizeof(*return_value) + sizeof(return_value->path[0]) * answer_count); return_value->node_count = answer_count; for (i = 0; i < answer_count; i++) { return_value->path[answer_count - i - 1] = answer[i]; } } free(answer); return return_value; }