⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heap.cpp

📁 最快速的可满足性分析工具软件
💻 CPP
字号:
/* * heap.cpp * (based on MiniSat's Heap.C) * This file contains functions related to the implementation * of the variable heap for ordering variables. *  * The following functions are in this file: * - gt (comparison function) * - percolate_up * - percolate_down * - init_heap * - insert * - increase * - decrease * - get_min_element * - empty * - in_heap * - update * - update2 * - undo * - dequeue * - increment_literal_score * - rescale_variable_scores * - increment_clause_score * - rescale_clause_scores * - free_heap * - reset_heap * * (printing and debuggin) * - check_heap_property * - print_indices * - print_order *  * */#include <stdlib.h>#include <stdio.h>#include <math.h>#include "constants.h"#include "flags.h"#include "structures.h"extern my_manager* my_m;extern double* scores;#if(ALLOW_PARTIAL_ORDER)extern int* partial_order;#endifinline char gt(my_var v1,my_var v2){#if(ALLOW_PARTIAL_ORDER)  int ps1 = partial_order[v1];  int ps2 = partial_order[v2];  if(ps1!=ps2){    return ps1 > ps2;  }#endif    double s1 = scores[v1];  double s2 = scores[v2];  return s1>s2;}/* * Percolate node i up the heap until it reaches its appropriate position. * */inline void percolate_up(heap* h,int i){  my_var* order = h->order;  int* indices = h->indices;  my_var v = order[i];  int parent_index = parent(i);  //while v's score is still greater than that of its parent  //i is the order index of the current position of the thing we are percolating  while(parent_index!=0 && gt(v,order[parent_index])){    int ind = order[parent_index];    order[i] = ind;    indices[ind] = i;    i = parent_index;          //i moves up    parent_index = parent(i);  //parent = next parent  }//end while  order[i] = v;  indices[v] = i;}/* * Percolate node i down the heap into its appropriate position. * */inline void percolate_down(heap* h,int i){  my_var* order = h->order;  int* indices = h->indices;  my_var v = order[i];    int h_size = h->size;  //until we run out of heap elements  while(left(i) <= h_size){    int left_index = left(i);    int right_index = right(i);    int bigger_child = ((right_index<=h->size && gt(order[right_index],order[left_index])) ? right_index:left_index);            if(!gt(order[bigger_child],v)){      //found the place      break;    }    order[i] = order[bigger_child];    indices[order[i]] = i;    i = bigger_child;  }//end while  order[i] = v;  indices[v] = i;}/* * Initialize heap h by allocating space for all n variables. * * Initially, set size to 0 as there is nothing in the heap. */void init_heap(heap* h,int n){  h->order = (my_var*)calloc(n+1,sizeof(my_var));  //+1 because order[0] is not used  h->indices = (int*)calloc(n+1,sizeof(int));  h->size = 0;}/*  * Put variable v in the heap (for the first time) based on v's score. *  */void insert(heap* h,my_var v){    int position = (++h->size);    h->indices[v] = position; //put l in the last position in the heap  h->order[position] = v;  percolate_up(h,position);}/* * Get the variable with index v to the right position * Assume that the right position of v is above (or equal to) its current position. * */void increase(heap* h,my_var v){  percolate_up(h,h->indices[v]);}/* * Get the variable with index v to the right position. * Assume that the right position of v is below (or equal to) its current position. * */void decrease(heap* h,my_var v){  percolate_down(h,h->indices[v]);}/* * Return the index of the variable with highest score in the heap. * Also remove that variable from the heap. * */my_var get_min_element(heap* h) {  my_var r = h->order[1];   //min element is always kept in [1].  h->order[1] = h->order[h->size];  //replace min with the last element to keep the heap's shape correct.  h->size--;                        //decrement the heap's size.  h->indices[h->order[1]] = 1;  h->indices[r] = 0;             //r is now out of the heap. Set indices[r] to 0 to reflect that.  if(h->size > 1){    percolate_down(h,1);            //adjust the position of the top element  }    return r;}/* * Return 1 iff there is currently no element in the heap. * */char empty(heap* h){  return h->size==0;}/* * Return 1 iff variable v is currently in the heap. * */char in_heap(heap* h,my_var v){  return h->indices[v]!=0;}/* * Update the position of variable with index v in the heap. * Assume that its correct position is above (or equal to) its current position. *  */void update(heap* h,my_var v){  if(in_heap(h,v)){    increase(h,v);  }}/* * Update the position of variable with index v in the heap. * Assume that its correct position is below (or equal to) its current position. *  */void update2(heap* h,my_var v){  if(in_heap(h,v)){    decrease(h,v);  }}/* * Essentially put the variable v back in the heap (assuming that we has a space for it). * */void undo(heap* h,my_var v){  if(!in_heap(h,v)){    insert(h,v);  }}/* * Dequeue a variable from the implication queue (which is really just a heap of variable). * */my_var dequeue(implication_queue* h){  while(!empty(h)){    my_var next = get_min_element(h);   //this takes care of restructuring heap    return next;  }//end while  //no more free variable  return 0;}/* * Divide the scores of all variables and score_inc by * SCORE_DIVIDIER. * */void rescale_variable_scores(){   int size = my_m->vc;  for (int i = 1; i <= size; i++){        scores[i] *= SCORE_DIVIDER;  }  my_m->score_inc *= SCORE_DIVIDER;}/* * Increment the score of variable var(l) by my_m->score_inc. * Also update the position of var(l) in the variable heap. * */void increment_literal_score(my_lit l){  my_var v = var(l);  double score = my_m->score_inc;  scores[v] += score;  score = scores[v];  if(score > SCORE_LIMIT){    rescale_variable_scores();  }  update(my_m->var_order_heap,v);}/* * Divide the scores of all clauses and my_m->clause_score_inc by * CLAUSE_SCORE_DIVIDER; * */void rescale_clause_scores(){  int size = my_m->cur_cdc_count;  double* scores = my_m->learned_clause_scores;  for(int i=0;i<size;i++){    scores[i] *= CLAUSE_SCORE_DIVIDER;  }  my_m->clause_score_inc *= CLAUSE_SCORE_DIVIDER;}/* * Increment the score of the *learned* clause c by * my_m->clause_score_inc. * */void increment_clause_score(my_clause* c){  if((my_m->learned_clause_scores[c->index] += my_m->clause_score_inc) > CLAUSE_SCORE_LIMIT){    rescale_clause_scores();  }}/* * Debugging utility:  * Check the consistency of the heap h * Side effect: will exit and print out useful information if inconsistency is detected. * */void check_heap_property(heap* h,int var_count){  my_var* order = h->order;  int* indices = h->indices;  int size = h->size;    for(int i=1;i<=var_count;i++){    if(indices[i]!=0){      if(i!=order[indices[i]]){	printf("indices array is corrupted at i=%d\n",i);	print_indices(h,var_count);	exit(0);      }    }  }//end for i  //check to make sure the ordering of node (wrt its parent) is correct.  for(int i=2;i<size;i++){    //-    double cur_score = scores[order[i]];    double parent_score = scores[order[parent(i)]];    if(cur_score>parent_score){      printf("heap order is corrupted at i=%d | cur_score = %.3f , parent's score = %.3f\n",i,cur_score,parent_score);      print_order(h);      exit(0);    }  }}/* * Print the indices array of the heap. * */void print_indices(heap* h,int var_count){  printf("Indices Array:\n");  for(int i=1;i<=var_count;i++){    printf("[%d-->%d(%d)] ",i,h->indices[i],h->order[h->indices[i]]);  }  printf("\n\n");}/* * Print the order array of the heap. * */void print_order(heap* h){  printf("\nHeap contains %d variables\n",h->size);  for(int i=1;i<=h->size;i++){    printf("[%d|%d] (%.4f)\n",i,h->order[i],my_m->score[h->order[i]]);  }    printf("\n\n");}/* * Free memory related to the heap h. */void free_heap(heap* h){  free(h->order);  free(h->indices);}/* * Reinitialize the heap h. * */void reset_heap(heap* h){  int size = my_m->vc;  for(int i=0;i<=size;i++){    h->indices[i] = 0;  }  h->size = 0;   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -