示例#1
0
void Output(int v)
{
    // Kick out of heap
    heap_remove(Heap, v);

    // In cost < Out cost, should go first
    if (DeltaCost[v] < 0)
    {
        Ordered[iFirst++] = v;
        // Out cost < In cost, should go last
    }
    else if (DeltaCost[v] > 0)
    {
        Ordered[iLast--] = v;
        // In cost == Out cost, check degrees
        // If out degree  is higher, should go first
    }
    else if (InDegree[v] < OutDegree[v])
    {
        Ordered[iFirst++] = v;
        // otherwise should go last
    }
    else
    {
        Ordered[iLast--] = v;
    }

    // Update data due to removal of vertex
    PARC pA = ArcStart[v];

    for (int i = 0; i < ArcCount[v]; i++)
    {
        if (heap_position(Heap, pA[i].j) <= 0) { continue; }

        DeltaCost[pA[i].j] -= pA[i].c;
        heap_update(Heap, pA[i].j, -abs(DeltaCost[pA[i].j]));

        // out arc
        if (pA[i].c > 0)
        {
            InDegree[pA[i].j]--;

            if (InDegree[pA[i].j] == 0 && OutDegree[pA[i].j] != 0)
            {
                Zero[nZero++] = pA[i].j;
            }

            // in arc
        }
        else
        {
            OutDegree[pA[i].j]--;

            if (OutDegree[pA[i].j] == 0 && InDegree[pA[i].j] != 0)
            {
                Zero[nZero++] = pA[i].j;
            }
        }
    }
}
示例#2
0
static void ipfw_cleanup(void)
{
  scamper_firewall_entry_t *entry;

  splaytree_inorder(entries, ipfw_cleanup_foreach, NULL);

  if(freeslots != NULL)
    {
      while((entry = heap_remove(freeslots)) != NULL)
	{
	  firewall_entry_free(entry);
	}

      heap_free(freeslots, NULL);
      freeslots = NULL;
    }

#ifdef WITHOUT_PRIVSEP
  scamper_firewall_ipfw_cleanup();
#else
  if(ipfw_inited != 0)
    scamper_privsep_ipfw_cleanup();
#endif

  return;
}
示例#3
0
void timer_cancel(struct timer *timer)
{
        if (!heap_in(timers, timer)) return; /* Called from this timer */

        heap_remove(timers, timer);
        free(timer);
}
示例#4
0
文件: heap.c 项目: Ikulagin/transmem
int
main ()
{
    puts("Starting...");

    heap_t* heapPtr = heap_alloc(1, compare);

    assert(heapPtr);

    long i;
    for (i = 0; i < global_numData; i++) {
        insertInt(heapPtr, &global_data[i]);
    }

    for (i = 0; i < global_numData; i++) {
        removeInt(heapPtr);
    }

    assert(heap_remove(heapPtr) == NULL); /* empty */

    heap_free(heapPtr);

    puts("Passed all tests.");

    return 0;
}
示例#5
0
static int sort_cat(void)
{
  heap_t        *heap = NULL;
  sort_struct_t *ss = NULL;
  sort_struct_t *s;
  int i;

  if((heap = heap_alloc(sort_struct_cmp)) == NULL)
    {
      goto err;
    }

  if((ss = malloc(sizeof(sort_struct_t) * infile_cnt)) == NULL)
    {
      goto err;
    }
  memset(ss, 0, sizeof(sort_struct_t) * infile_cnt);

  /*
   * start by filling all file slots with the first data object from
   * each file
   */
  for(i=0; i<infile_cnt; i++)
    {
      ss[i].file = i;
      if(sort_cat_fill(heap, &ss[i]) != 0)
	{
	  goto err;
	}
    }

  /*
   * now, read each object off the heap in their appropriate priority and
   * replace each heap object with another from the file until there is
   * nothing left.
   */
  while((s = (sort_struct_t *)heap_remove(heap)) != NULL)
    {
      if(write_obj(s->type, s->data) != 0)
	{
	  goto err;
	}

      if(sort_cat_fill(heap, s) != 0)
	{
	  goto err;
	}
    }

  heap_free(heap, NULL);
  free(ss);

  return 0;

 err:
  if(heap != NULL) heap_free(heap, NULL);
  if(ss != NULL) free(ss);
  return -1;
}
示例#6
0
文件: heap.c 项目: Ikulagin/transmem
static void
removeInt (heap_t* heapPtr)
{
    long* data = heap_remove(heapPtr);
    printf("Removing: %li\n", *data);
    printHeap(heapPtr);
    assert(heap_isValid(heapPtr));
}
示例#7
0
static void threadpool_free_task_queue(threadpool_t *pool) {
    task_t *t;
    while (pool->task_queue.len != 0) {
        t = heap_remove(&pool->task_queue, 0);
        if (t) {
            free(t);
        }
    }
}
示例#8
0
heap_node_t *heap_pop(heap_t *heap)
{
    heap_node_t *node = heap_peek(heap);

    if (NULL != node) {
        heap_remove(node);
    }

    return node;
}
示例#9
0
文件: core.c 项目: catoc/Comojs
int timer_stop (evHandle *handle) {
    if (!handle || !_is_active(handle)) return 0;
    evTimer *timer = handle->ev;
    heap_remove((struct heap*) &handle->loop->timer_heap,
              (struct heap_node*) &timer->heap_node,
              timer_less_than);
    
    handle_stop(handle);
    return 0;
}
示例#10
0
static void* thread_loop(void *arg) {
    threadpool_t *pool = (threadpool_t*)arg;
    task_t *t = NULL;
    struct timespec ts;
    struct timeval  tv;
    int ret;
    int tosignal;

    while (!pool->exit) {
        Pthread_mutex_lock(&pool->mutex);
        gettimeofday(&tv, NULL);
        ts.tv_sec = tv.tv_sec + POOL_MAX_IDLE;
        ts.tv_nsec = tv.tv_usec * 1000;

        while (pool->task_queue.len == 0) {
            ret = Pthread_cond_timedwait(&pool->cond, &pool->mutex, &ts);
            if (ret == 0) {
                if (pool->exit) {
                    goto EXIT;
                }
                break;
            } else if (ret == ETIMEDOUT) {
                goto EXIT;
            }
        }

        --pool->threads_idle;
        t = heap_remove(&pool->task_queue, 0);
        tosignal = (pool->task_queue.len == 0) ? 1 : 0;
        Pthread_mutex_unlock(&pool->mutex);

        if (tosignal) {
            Pthread_cond_broadcast(&pool->task_over_cond);
        }

        if (t) {
            t->func(t->arg);
            free(t);
        }

        Pthread_mutex_lock(&pool->mutex);
        ++pool->threads_idle;
        Pthread_mutex_unlock(&pool->mutex);
    }

    Pthread_mutex_lock(&pool->mutex);
EXIT:
    --pool->threads_idle;
    tosignal = --pool->threads_num ? 0 : 1;
    Pthread_mutex_unlock(&pool->mutex);
    if (tosignal) {
        Pthread_cond_broadcast(&pool->exit_cond);
    }
    return NULL;
}
示例#11
0
void
sim_event_dispatch_pending()
{
  sim_event_t *ev = heap_peek(gQueue->activeEventHeap);
  while (ev && ev->fireTime < sim_time_get_time_stamp()) {
    heap_remove(gQueue->activeEventHeap);
    ev->handler(ev->data);
    sim_event_release(ev);
    ev = heap_peek(gQueue->activeEventHeap);
  }
}
示例#12
0
文件: timer.c 项目: Kitware/CMake
int uv_timer_stop(uv_timer_t* handle) {
  if (!uv__is_active(handle))
    return 0;

  heap_remove(timer_heap(handle->loop),
              (struct heap_node*) &handle->heap_node,
              timer_less_than);
  uv__handle_stop(handle);

  return 0;
}
示例#13
0
int main (int argc, char * argv[])
{
    long int array[] = { 10, 3, 4, 8, 2, 9, 7, 1, 2, 6, 5 };

    Heap * heap = heap_new_with_data ((void**)array, 11, 0, NULL, NULL);

    heap_remove(heap, (void *)2);

    while (heap_size(heap) > 0) {
        printf ("%li\n", (long int)heap_pop(heap));
    }
    return 0;
}
示例#14
0
文件: prob2.c 项目: FEUP-MIEEC/Prog2
int proximas_n_chegadas(lista *tempos, lista *origens, lista *aeroportos, int n) {
    /* prob 2.1 - a implementar */
    /* _1_> Alocar memória para lista de aeroportos. */
	elemento *a=aeroportos->inicio; int i=0;
	char** aero = malloc(sizeof(char**)*aeroportos->tamanho);
	while(a!=NULL){	
		aero[i]=malloc(sizeof(char*)*50);
		strcpy(aero[i], a->str);
		a=a->proximo;
		i++;
	}
	
	/* FIM _1_ */
	
	/* _2_> Inserir na Heap */
	
	heap* heapvoos=heap_nova(tempos->tamanho);
	elemento* tempo=tempos->inicio;
	elemento* orig=origens->inicio;
	while(tempo!=NULL){
		heap_insere(heapvoos, aero[atoi(orig->str)], atoi(tempo->str));
		tempo=tempo->proximo;
		orig=orig->proximo;
	}
	
	// Libertar memória já não necessária
	for(i=0; i<aeroportos->tamanho; i++){
		free(aero[i]);
	}
	free(aero);
	
	/* FIM _2_*/
	
	/* _3_> Retirar da Heap */
	
	for (int i = 0; i < n; ++i)
    {
        char * str;
        printf("[%d]: %s\n", i+1, str = heap_remove(heapvoos));
        free(str);
    }
	
    heap_apaga(heapvoos);	
	/* FIM _3_*/
	
	
    return 1;
}
示例#15
0
文件: timers.c 项目: artisdom/mipv6
void
timer_remove_debug(const char *function, const char *file, int line,
		   suptimer_t *tmr)
{
	debug_assert(tmr->target != IMPOSSIBLE_FUTURE,
		     "Stopping timer (%s) which is not running at %s in %s:%i.",
		     tmr->name, function, file, line);

#if DEBUG_TIMERS
	debug_log(10, "remove_timer(%s)\n", tmr->name);
#endif

	heap_remove(&timers, &tmr->item);

	tmr->target = IMPOSSIBLE_FUTURE;
}
示例#16
0
// Implementation from:
// https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Using_a_priority_queue
void dijkstra(list_t graph, int width, int height, point_t* source)
{
    // set distance to self to 0
    source->prev = source;
    source->dist = 0;

    // create priority queue
    heap_t queue;
    heap_create(&queue, width * height);

    heap_insert(queue, 0, source);

    while (heap_size(queue) > 0)
    {
        // find vertex u with minimal cost
        point_t* u;
        heap_remove(queue, &u);

        // for neighbour v to u
        for (int i = MAX(u->x - 1, 0); i <= MIN(u->x + 1, width - 1); ++i)
        {
            for (int j = MAX(u->y - 1, 0); j <= MIN(u->y + 1, height - 1); ++j)
            {
                if (i != u->x || j != u->y) // u can't be its own neighbour
                {
                    point_t* v = graph_find(graph, width, height, i, j);

                    // is the current distance to u shorter through v?
                    int alt = u->dist + v->cost;

                    if (alt < v->dist) 
                    {
                        v->dist = alt;
                        v->prev = u;

                        heap_insert(queue, alt, v);
                    }
                }
            }
        }
    }

    heap_free(queue, NULL, NULL);
}
示例#17
0
文件: heap.c 项目: flygoast/filmond
void heap_destroy(heap_t *h) {
    void *data;
    while (h->len) {
        data = heap_remove(h, 0);
        if (h->ent_free && data) {
            h->ent_free(data);
        }
    }

    if (h->data) {
        free(h->data);
        h->data = NULL;
    }
    h->cap = 0;
    h->len = 0;
    h->less = NULL;
    h->record = NULL;
    h->ent_free = NULL;
}
示例#18
0
文件: heap.c 项目: flygoast/filmond
int main(int argc, char **argv) {
    int i;
    heap_t *h = heap_create();
    h->less = less;
    srand(time(NULL));
    for (i = 0; i < TEST_NUMBER; ++i) {
        assert(heap_insert(h, (void *)(long)(rand() % TEST_NUMBER)) == 0);
    }

    printf("Original\n==========================================\n");
    for (i = 0; i < h->len; ++i) {
        printf("%ld\n", (long)h->data[i]);
    }

    printf("Sorted\n==========================================\n");
    while (h->len != 0) {
        void *value = heap_remove(h, 0);
        printf("%ld\n", (long)value);
    }
    heap_free(h);
}
示例#19
0
static void
break_ccpair (struct ropa_ccpair *cc, Bool notify_clientp)
{
    AFSCBFids fids;
    AFSCBs cbs;
    int ret;

    debug_print_callbacks();

    cc->expire = 0;

    if (cc->li)
	listdel (lru_ccpair, cc->li);

    if (notify_clientp) {
	fids.len = 1;
	fids.val = &cc->cb->fid;
	cbs.len = 0;
	notify_client (cc->client, &fids, &cbs);
    }

    if (cc->cb_li) {
	listdel (cc->cb->ccpairs, cc->cb_li);
	cc->cb_li = NULL;
    }

    /* The reverse of these are in add_client */
    ret = hashtabdel (ht_ccpairs, cc);
    assert (ret == 0);
    client_deref (cc->client);
    cc->client = NULL;
    callback_deref (cc->cb);
    cc->cb = NULL;

    heap_remove (heap_ccpairs, cc->heap);
    
    cc->li = listaddtail (lru_ccpair, cc);

    debug_print_callbacks();
}
示例#20
0
static void merge_opt_Tdt(int k1, int k2, merge_alpha_t *M) {
int d;
  struct heap_s up;
  struct heap_s down;
  /*
   *    sorting on moves,
   *    stores doc index for 
   */
  uint32_t *Tdt_up;
  uint32_t *Tdt_down;
  /*
   *     change from incr/decr this docs Tdt
   */
  float *score_up;
  float *score_down;

  Tdt_up = u32vec(ddN.DT);
  Tdt_down = u32vec(ddN.DT);
  score_up = fvec(ddN.DT);
  score_down = fvec(ddN.DT);
  if ( !score_down || !score_up || !Tdt_up || !Tdt_down )
    yap_quit("Out of memory in likemerge()\n");
  /*
   *  initialise sort
   */
  for (d=0; d<ddN.DT; d++) {
    assert(M->Tdt[d]<=M->Ndt[d]);
    /*   don't change for some docs */
    Tdt_up[d] = d;
    Tdt_down[d] = d;
    if ( M->Tdt[d]<M->Ndt[d] )
      score_up[d] = (ddP.bpar + ddP.apar*M->TdT[d]) 
	* S_V(ddC.SX,M->Ndt[d],M->Tdt[d]+1);
    else 
      score_up[d] = 0;
    if ( M->Tdt[d]>1 )
      score_down[d] = 1.0 / S_V(ddC.SX,M->Ndt[d],M->Tdt[d])
	/(ddP.bpar + ddP.apar*(M->TdT[d]-1));
    else
      score_down[d] = 0;    
    assert((M->Tdt[d]>1)||score_down[d]==0);
    assert((M->Tdt[d]<M->Ndt[d])||score_up[d]==0);
    assert(M->Tdt[d]<=M->Ndt[d]);
  }
  assert(M->TDt>0);

  /*  
   *  use a heap, so only top of heap is least 
   */
  heap_init(&up, Tdt_up, ddN.DT, fveccmp, (void *)score_up);
  heap_init(&down, Tdt_down, ddN.DT, fveccmp, (void *)score_down);

  while ( 1 ) {
    float upv;
    float downv;
    upv = merge_alphabasetopicprob(M->TDTm+M->TDt, M->TDt, k1)
      *score_up[heap_front(&up)];
    if ( M->TDt>1 )
      downv = score_down[heap_front(&down)] 
        / merge_alphabasetopicprob(M->TDTm+M->TDt-1, M->TDt-1, k1);
    else
      downv = 0.0;
    if ( downv>upv && downv>1.0 ){
      //  decrement this
      d = heap_front(&down); 
      M->TdT[d]--;
      M->Tdt[d]--;
      assert(M->Tdt[d]>0);
      M->TDt--;
      heap_pop(&down);
      heap_remove(&up,d);
    } else if ( downv<upv && upv>1.0 ){
      //  increment this
      d = heap_front(&up);
      M->TdT[d]++;
      M->Tdt[d]++;
      assert(M->Tdt[d]<=M->Ndt[d]);
      M->TDt++;
      heap_pop(&up);
      heap_remove(&down,d);
    } else {
      //  none are better so quit
      break;
    }
    if ( M->Tdt[d]<M->Ndt[d] )
      score_up[d] = (ddP.bpar + ddP.apar*M->TdT[d]) 
	* S_V(ddC.SX,M->Ndt[d],M->Tdt[d]+1);
    else 
      score_up[d] = 0;
    if ( M->Tdt[d]>1 )
      score_down[d] = 1.0 / S_V(ddC.SX,M->Ndt[d],M->Tdt[d])
	/(ddP.bpar + ddP.apar*(M->TdT[d]-1));
    else
      score_down[d] = 0;
    assert(M->Tdt[d]>1||score_down[d]==0);
    assert(M->Tdt[d]<M->Ndt[d] ||score_up[d]==0);
    assert(M->Tdt[d]<=M->Ndt[d]);
    /*
     *  now adjust the two heaps for new vals for [d]
     */
    heap_push(&down,d);
    heap_push(&up,d);
  }  
  free(score_up);
  free(score_down);
  heap_free(&up);
  heap_free(&down);
}
示例#21
0
void timer_reset(struct timer *timer, float delay_seconds)
{
        timer->time = get_now() + delay_seconds;
        heap_remove(timers, timer);
        heap_insert(timers, timer);
}
示例#22
0
文件: worker.c 项目: russross/envoy
void worker_wake_up_next(void) {
    Worker *next = heap_remove(worker_ready_to_run);
    if (next == NULL)
        return;
    cond_signal(next->sleep);
}
示例#23
0
文件: search.c 项目: tbullard/npuzzle
list* search_a_star(void* state,
                    void* state_world,
                    search_is_goal state_goal_func,
                    search_gen_successors state_gen_func,
                    search_link_parent state_link_func,
                    search_goal_backtrace state_back_func,
                    search_trans_cost state_trans_func,
                    search_heuristic state_heur_func,
                    search_set_f_cost state_f_cost_set_func,
                    hash_func state_hash_alg,
                    generic_comp state_comp_func,
                    generic_cpy state_copy_func,
                    generic_op state_free_func,
                    heap_comp state_heap_func) {
    int* g_cost_ptr, *f_cost_ptr, f_cost, tmp_f, g_cost, found;
    void* current_state, *successor_state, *heap_memory_location;
    list* states_overflow, *successor_list, *path;
    hash_table* states_closed_set, *states_open_set;
    hash_map* states_g_cost, *states_f_cost, *states_heap_index;
    heap* states_heap;

    states_overflow = list_create(NULL,
                                  NULL,
                                  state_free_func);

    states_closed_set = hash_table_create(89,
                                          .75,
                                          state_hash_alg,
                                          state_comp_func,
                                          state_copy_func,
                                          state_free_func);

    states_open_set = hash_table_create(89,
                                        .75,
                                        state_hash_alg,
                                        state_comp_func,
                                        state_copy_func,
                                        state_free_func);

    states_g_cost = hash_map_create(89,
                                    .75,
                                    state_hash_alg,
                                    state_comp_func,
                                    NULL,
                                    NULL,
                                    NULL,
                                    state_free_func,
                                    (generic_op)free);

    states_f_cost = hash_map_create(89,
                                    .75,
                                    state_hash_alg,
                                    state_comp_func,
                                    NULL,
                                    NULL,
                                    NULL,
                                    state_free_func,
                                    (generic_op)free);

    states_heap_index = hash_map_create(89,
                                        .75,
                                        state_hash_alg,
                                        state_comp_func,
                                        NULL,
                                        NULL,
                                        NULL,
                                        NULL,
                                        NULL);

    states_heap = heap_create(89,
                              state_heap_func,
                              state_comp_func,
                              state_copy_func,
                              state_free_func);
    current_state = state;
    f_cost = state_heur_func(current_state, NULL);
    state_f_cost_set_func(current_state, f_cost);
    g_cost = 0;
    g_cost_ptr = malloc(sizeof(int));
    *g_cost_ptr = g_cost;
    f_cost_ptr = malloc(sizeof(int));
    *f_cost_ptr = f_cost;
    hash_map_insert(states_g_cost, current_state, g_cost_ptr, 0);
    heap_memory_location = heap_add(states_heap, state_copy_func(current_state));
    hash_table_insert(states_open_set, state_copy_func(current_state), 0);
    hash_map_insert(states_f_cost, state_copy_func(current_state), f_cost_ptr, 0);
    hash_map_insert(states_heap_index, current_state, heap_memory_location, 1);
    path = NULL;
    found = 0;
    while(!heap_is_empty(states_heap) && !found) {
        current_state = state_copy_func(heap_peek(states_heap));
        heap_remove(states_heap);
        hash_table_remove(states_open_set, current_state);
        hash_map_remove(states_heap_index, current_state);
        if(state_goal_func(current_state, state_world)) {
            path = state_back_func(current_state);
            found = 1;
        } else {
            if(!hash_table_insert(states_closed_set, current_state, 0)) {
                list_push_front(states_overflow, current_state);
            }
            successor_list = state_gen_func(current_state, state_world);
            while(!list_is_empty(successor_list)) {
                successor_state = list_front(successor_list);
                g_cost = *(int*)hash_map_get(states_g_cost, current_state) +
                    state_trans_func(current_state, successor_state, state_world);
                f_cost = g_cost + state_heur_func(successor_state, state_world);
                tmp_f = hash_map_contains_key(states_f_cost, successor_state) ?
                    *(int*)hash_map_get(states_f_cost, successor_state) : UINT_MAX;
                if(hash_table_contains(states_closed_set, successor_state) && f_cost > tmp_f) {
                    list_remove_front(successor_list);
                    continue;
                }
                if(!hash_table_contains(states_open_set, successor_state) || f_cost < tmp_f) {
                    state_f_cost_set_func(successor_state, f_cost);
                    state_link_func(successor_state, current_state);
                    g_cost_ptr = malloc(sizeof(int));
                    f_cost_ptr = malloc(sizeof(int));
                    *g_cost_ptr = g_cost;
                    *f_cost_ptr = f_cost;
                    if(!hash_table_contains(states_open_set, successor_state)) {
                        hash_table_insert(states_open_set, successor_state, 0);
                        heap_memory_location = heap_add(states_heap, state_copy_func(successor_state));
                        hash_map_insert(states_heap_index, successor_state,  heap_memory_location, 1);
                    } else {
                        heap_memory_location = hash_map_get(states_heap_index, successor_state);
                        heap_up_mod_data(states_heap, heap_memory_location,  successor_state);
                    }
                    if(!hash_map_set(states_g_cost, successor_state, g_cost_ptr)) {
                        hash_map_insert(states_g_cost, state_copy_func(successor_state), g_cost_ptr, 0);
                    }
                    if(!hash_map_set(states_f_cost, successor_state, f_cost_ptr)) {
                        hash_map_insert(states_f_cost, state_copy_func(successor_state), f_cost_ptr, 0);
                    }
                    list_pop(successor_list);
                } else {
                    list_remove_front(successor_list);
                }
            }
            list_kill(successor_list);
        }
    }
    heap_kill(states_heap);
    list_kill(states_overflow);
    hash_map_kill(states_g_cost);
    hash_map_kill(states_f_cost);
    hash_table_kill(states_open_set);
    hash_table_kill(states_closed_set);
    hash_map_dissolve(states_heap_index);
    return path;
}
示例#24
0
static scamper_firewall_entry_t *firewall_entry_get(void)
{
  return heap_remove(freeslots);
}
示例#25
0
// Implementation from:
// https://en.wikipedia.org/wiki/A*_search_algorithm#Pseudocode
int a_star(list_t graph, int width, int height, point_t* start, point_t* goal)
{
    list_t closed;
    list_create(&closed, width * height);

    start->dist = 0;
    f_score[start->x][start->y] = start->dist + heuristic_cost_estimate(start, goal);

    heap_t open;
    heap_create(&open, width * height);

    heap_insert(open, 0, start);

    while (heap_size(open) > 0)
    {
        // find node with minimal f_score value
        point_t* current;
        heap_remove(open, &current);

        if (current == goal)
        {
            list_free(closed, NULL, NULL);
            heap_free(open, NULL, NULL);
            return EXIT_SUCCESS;
        }

        // remove from open list and insert into closed list
        list_insert(closed, current->id, current);

        // for neighbours of current
        for (int i = MAX(current->x - 1, 0); i <= MIN(current->x + 1, width - 1); ++i)
        {
            for (int j = MAX(current->y - 1, 0); j <= MIN(current->y + 1, height - 1); ++j)
            {
                if (i != current->x || j!= current->y) // skip self
                {
                    point_t* neighbour = graph_find(graph, width, height, i, j);

                    if (list_search(closed, neighbour->id, NULL))
                    {
                        continue; // ignore neighbour which is already evaluated
                    }

                    int tentative_g_score = current->dist + neighbour->cost;

                    if (tentative_g_score < neighbour->dist)
                    {
                        neighbour->prev = current;
                        neighbour->dist = tentative_g_score;
                        f_score[i][j] = neighbour->dist + heuristic_cost_estimate(neighbour, goal);

                        heap_insert(open, neighbour->dist, neighbour);
                    }
                }
            }
        }
    }

    list_free(closed, NULL, NULL);
    heap_free(open, NULL, NULL);
    return EXIT_FAILURE;
}