void heap_decrease_key(heap** H, elem* x, int newKey){ assert(H && *H); assert(x && x->key >= newKey); x->key = newKey; if(x->parent && x->parent->key > newKey){ if (x->left == x){ assert(x->parent->degree == 2); x->parent->kid = NULL; }else{ assert(x->parent->degree > 2); x->left->right = x->right; x->right->left = x->left; x->parent->kid = x->left; } x->parent->degree--; heap_add(H, x); if (! x->parent->hasLostKid){ x->parent->hasLostKid = 1; }else{ heap_decrease_key(H, x->parent, x->parent->key); } }else{ if (newKey < (*H)->key){ assert(!x->parent); *H = x; } } }
int main() { heap_node* n[5]; heap *ph = heap_new(); n[4] = heap_insert(ph, 4); n[1] = heap_insert(ph, 1); n[0] = heap_insert(ph, 0); n[3] = heap_insert(ph, 3); n[2] = heap_insert(ph, 2); int i; for(i=0; i<5; i++) { n[i]->value.v_in_mst = -i; n[i]->value.v_not_in_mst = i; } heap_decrease_key(ph, n[3], -1); for(i=0; i<5; i++) { int v_not_in_mst = heap_min(ph); heap_value* val = &n[v_not_in_mst]->value; printf("%d %d %f\n", val->v_in_mst, v_not_in_mst, val->weight); heap_delete_min(ph); } return 0; }
void relax(Heap *heap, Grafo *grafo, int u, int v){ int alt = grafo->lista[u]->d + peso(grafo,u,v); if(grafo->lista[v]->d > alt){ heap_decrease_key(heap, v, alt); grafo->lista[v]->d = alt; //grafo->lista[v]->pi = grafo->lista[u]; } }
HEAP_ERR_E heap_min_insert (HEAP_T* h, unsigned long key, void* data, unsigned long* i) { if (h->type != DS_HEAP_MIN) return HEAP_ERR_WRONG_TYPE; heap_add (h, HEAP_NIL_KEY, data, i); heap_decrease_key (h, h->heap_size-1, key); return HEAP_ERR_OK; }
/** * @brief Dijkstra's shortest path algorithm * * @param[in] g The graph to operate on * @param[in] s The starting vertex * @param[in] cb The function to call when a shortest spath vertex is determined. */ void sp_dijkstra (GRAPH_T* g, unsigned long s, SP_DJ_FP_T cb) { HEAP_T* h; VTX_D_T* u = NULL; VTX_D_T* v; unsigned long key, no; char* ctx = NULL; EDGE_T* e; void* p; initialize_single_source (g, s); h = heap_create (DS_HEAP_MIN, GRAPH_NO_VERTICES(g)); while (NULL != (u = graph_vertex_next_get (g, u))) { heap_min_insert (h, D_SP_AUX_SPEST(u), u, &D_SP_AUX_I(u)); } while (HEAP_SIZE(h)) { heap_extract_min (h, &p, &key); u = (VTX_D_T*)p; ctx = NULL; no = ((VTX_D_T*)u)->no; while (no) { e = graph_vertex_next_edge_get (g, u, &ctx); if (e->v1 == u) v = e->v2; else v = e->v1; if (v->id.iid == s) { no--; continue; } DEBUG_PRINT ("Relaxing v=%lu (OLD weight: %lu; NEW weight: u=%lu w=%lu)\n", v->id.iid, D_SP_AUX_SPEST(v), u->id.iid, e->weight); relax (g, u, v, e->weight); heap_decrease_key (h, D_SP_AUX_I(v), D_SP_AUX_SPEST(v)); no--; } } if (cb) { v = NULL; while (NULL != (v = graph_vertex_next_get (g, v))) { cb (v); //fprintf (stderr, "vid = %lu sp=%lu\n", v->id.iid, D_SP_AUX_SPEST(v)); } } }
void min_heap_insert(heap* A, node* t) { // node* tmp = get_node(ch,INT_MAX); int key = t->freq; t->freq = INT_MAX; A->heap_size++; A->arr[A->heap_size] = t; heap_decrease_key(A,A->heap_size,key); return; }
void dijkstra(long s){ heap* pq=heap_init(); elem* entries[n+1]; edge result; memset(result.i,0,n+1); int i,ml[n+1]; for(i=1;i<=n;++i){ ml[i]=i; entries[i]=heap_insert(&pq,MAX,ml+i); //printf("%d %lld\n",*(int*)entries[i]->value,entries[i]->key); } heap_decrease_key(&pq,entries[s],0); //printf("%d %lld\n",*(int*)entries[s]->value,entries[s]->key); //printf("decrease ok\n"); while(!is_empty(pq)){ data curr=heap_extract_min(&pq); //print_data(curr); int cv=*(int*) curr.value; result.i[cv]=1; result.v[cv]=curr.key; for(i=1;i<=n;++i){ if(has(result,i)) continue; if(!has(g.v[cv],i)){ continue; } printf("path %d ->%d\n",cv,i); ll pathCost=index(result,i)+ g.v[cv].v[i]; elem* dest=entries[i]; printf("pC=%lld key=%lld\n",pathCost,dest->key); if( dest->key> pathCost){ printf("desc key\n"); heap_decrease_key(&pq,dest,pathCost); } } } for(i=1;i<=n;++i){ res[s][i]=result.v[i]; } }
void heap_insert(heap_t h, uint64_t key, void *user) { if (unlikely(h->size == h->max_size)) { h->max_size *= 2; h->nodes = xrealloc(h->nodes, h->max_size * sizeof(struct node)); } ++(h->size); KEY(h, h->size) = UINT64_MAX; USER(h, h->size) = user; heap_decrease_key(h, h->size, key); }
void ShortestPath_Dijekstra(struct graph *g, int src, int *d, int *prev) { struct heap *prio_q; prio_q = heap_create(g->nvertices); int v; for (v = 1; v <= g->nvertices; v++) { if (v != src) { g->visited[v] = 0; d[v] = INT_MAX; prev[v] = -1; heap_insert(prio_q, d[v], v); } } d[src] = 0; prev[src] = -1; g->visited[src] = 0; heap_insert(prio_q, d[src], src); struct heapnode node; int tmp; for (v = 1; v <= g->nvertices; v++) { node = heap_extract_min(prio_q); tmp = node.value; g->visited[tmp] = 1; /*printf("vert %d\n\n", v); printf("min prio %d to vert %d\n", node.key, node.value);*/ for (int u = 1; u <= g->nvertices; u++) { int way = graph_get_edge(g, tmp, u); if ((way != 0) && (g->visited[u] != 1)) { //printf("sm ne pos vert %d\nway %d\n", u, way); if (d[tmp] + way < d[u]) { d[u] = d[tmp] + way; //printf("path do %d = %d\n", u, d[u]); heap_decrease_key(prio_q, u, d[u]); prev[u] = tmp; } } } } }
void compute_shortest_path(std::vector< NUM_T >& d, std::vector< NODE_T >& prev, NODE_T from, std::vector< std::list< edge1<NUM_T> > >& cost_forward, std::vector< std::list< edge2<NUM_T> > >& cost_backward, const std::vector<NUM_T>& e, NODE_T& l) { //---------------------------------------------------------------- // Making heap (all inf except 0, so we are saving comparisons...) //---------------------------------------------------------------- std::vector< edge3<NUM_T> > Q(_num_nodes); Q[0]._to= from; _nodes_to_Q[from]= 0; Q[0]._dist= 0; NODE_T j=1; // TODO: both of these into a function? {for (NODE_T i=0; i<from; ++i) { Q[j]._to= i; _nodes_to_Q[i]= j; Q[j]._dist= std::numeric_limits<NUM_T>::max(); ++j; }} {for (NODE_T i=from+1; i<_num_nodes; ++i) { Q[j]._to= i; _nodes_to_Q[i]= j; Q[j]._dist= std::numeric_limits<NUM_T>::max(); ++j; }} //---------------------------------------------------------------- //---------------------------------------------------------------- // main loop //---------------------------------------------------------------- std::vector<NODE_T> finalNodesFlg(_num_nodes, false); do { NODE_T u= Q[0]._to; d[u]= Q[0]._dist; // final distance finalNodesFlg[u]= true; if (e[u]<0) { l= u; break; } heap_remove_first(Q, _nodes_to_Q); // neighbors of u {for (typename std::list< edge1<NUM_T> >::const_iterator it= cost_forward[u].begin(); it!=cost_forward[u].end(); ++it) { assert (it->_reduced_cost>=0); NUM_T alt= d[u]+it->_reduced_cost; NODE_T v= it->_to; if ( (_nodes_to_Q[v]<Q.size()) && (alt<Q[_nodes_to_Q[v]]._dist) ) { //cout << "u to v==" << u << " to " << v << " " << alt << endl; heap_decrease_key(Q,_nodes_to_Q, v,alt); prev[v]= u; } }} //it {for (typename std::list< edge2<NUM_T> >::const_iterator it= cost_backward[u].begin(); it!=cost_backward[u].end(); ++it) { if (it->_residual_capacity>0) { assert (it->_reduced_cost>=0); NUM_T alt= d[u]+it->_reduced_cost; NODE_T v= it->_to; if ( (_nodes_to_Q[v]<Q.size()) && (alt<Q[_nodes_to_Q[v]]._dist) ) { //cout << "u to v==" << u << " to " << v << " " << alt << endl; heap_decrease_key(Q,_nodes_to_Q, v,alt); prev[v]= u; } } }} //it } while (!Q.empty()); //tmp_tic_toc.tic(); //--------------------------------------------------------------------------------- // reduced costs for forward edges (c[i,j]-pi[i]+pi[j]) {for (NODE_T from=0; from<_num_nodes; ++from) { {for (typename std::list< edge1<NUM_T> >::iterator it= cost_forward[from].begin(); it!=cost_forward[from].end(); ++it) { if (finalNodesFlg[from]) { it->_reduced_cost+= d[from] - d[l]; } if (finalNodesFlg[it->_to]) { it->_reduced_cost-= d[it->_to] - d[l]; } } } }} // reduced costs and capacity for backward edges (c[j,i]-pi[j]+pi[i]) {for (NODE_T from=0; from<_num_nodes; ++from) { { for (typename std::list< edge2<NUM_T> >::iterator it= cost_backward[from].begin(); it!=cost_backward[from].end(); ++it) { if (finalNodesFlg[from]) { it->_reduced_cost+= d[from] - d[l]; } if (finalNodesFlg[it->_to]) { it->_reduced_cost-= d[it->_to] - d[l]; } } }// it }} //--------------------------------------------------------------------------------- //tmp_tic_toc.toc(); //---------------------------------------------------------------- } // compute_shortest_path
main() { int i,ch,H[20],ps,ky; printf("Input array length: "); scanf("%d",&len); printf("\nInput array -\n"); for(i=0;i<len;i++) scanf("%d",&H[i]); heapsize=len; //build_maxheap(H); build_minheap(H); printf("\nDisplaying heap -\n"); display_heap(H); //printf("\n---------PRIORITY QUEUE-----------\n\n1.) Print maximum value in queue\n2.) Print and extract maximum value in queue\n3.) Increase key for an element in the queue\n4.) Insert key into the queue\n"); printf("\n---------PRIORITY QUEUE-----------\n\n1.) Print minimum value in queue\n2.) Print and extract minimum value in queue\n3.) Decrease key for an element in the queue\n4.) Insert key into the queue\n"); printf("\nEnter choice (1-4): "); scanf("%d",&ch); printf("\n"); switch(ch) { case 1: //printf("%d\n",heap_maximum(H)); printf("%d\n",heap_minimum(H)); printf("Displaying PriorityQ: "); display_heap(H); break; case 2: //printf("%d\n",heap_max_extract(H)); printf("%d\n",heap_min_extract(H)); printf("Displaying PriorityQ: "); display_heap(H); break; case 3: //printf("Enter position of the queue element whose key you want to increase (1-%d): ",len); printf("Enter position of the queue element whose key you want to decrease (1-%d): ",len); scanf("%d",&ps); printf("Enter new key: "); scanf("%d",&ky); //heap_increase_key(H,ps,ky); heap_decrease_key(H,ps,ky); printf("Displaying PriorityQ: "); display_heap(H); break; case 4: printf("Enter the new key you want to insert: "); scanf("%d",&ky); //maxheap_insert(H,ky); minheap_insert(H,ky); printf("Displaying PriorityQ: "); display_heap(H); break; default: break; } printf("\n"); }
void heap_delete(heap** H, elem* x){ heap_decrease_key(H, x, INT_MIN); heap_extract_min(H); }