nysol-zdd 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/zdd_so/BDD.cc +495 -0
- data/ext/zdd_so/BDD.h +356 -0
- data/ext/zdd_so/BDDDG.cc +1818 -0
- data/ext/zdd_so/BDDDG.h +107 -0
- data/ext/zdd_so/BDDHASH.cc +91 -0
- data/ext/zdd_so/BtoI.cc +503 -0
- data/ext/zdd_so/BtoI.h +144 -0
- data/ext/zdd_so/CtoI.cc +1072 -0
- data/ext/zdd_so/CtoI.h +186 -0
- data/ext/zdd_so/MLZBDDV.cc +153 -0
- data/ext/zdd_so/MLZBDDV.h +42 -0
- data/ext/zdd_so/SOP.cc +608 -0
- data/ext/zdd_so/SOP.h +199 -0
- data/ext/zdd_so/ZBDD.cc +1035 -0
- data/ext/zdd_so/ZBDD.h +243 -0
- data/ext/zdd_so/ZBDDDG.cc +1834 -0
- data/ext/zdd_so/ZBDDDG.h +105 -0
- data/ext/zdd_so/ZBDDHASH.cc +91 -0
- data/ext/zdd_so/bddc.c +2816 -0
- data/ext/zdd_so/bddc.h +132 -0
- data/ext/zdd_so/extconf.rb +25 -0
- data/ext/zdd_so/include/aheap.c +211 -0
- data/ext/zdd_so/include/aheap.h +111 -0
- data/ext/zdd_so/include/base.c +93 -0
- data/ext/zdd_so/include/base.h +60 -0
- data/ext/zdd_so/include/itemset.c +473 -0
- data/ext/zdd_so/include/itemset.h +153 -0
- data/ext/zdd_so/include/problem.c +371 -0
- data/ext/zdd_so/include/problem.h +160 -0
- data/ext/zdd_so/include/queue.c +518 -0
- data/ext/zdd_so/include/queue.h +177 -0
- data/ext/zdd_so/include/sgraph.c +331 -0
- data/ext/zdd_so/include/sgraph.h +170 -0
- data/ext/zdd_so/include/stdlib2.c +832 -0
- data/ext/zdd_so/include/stdlib2.h +746 -0
- data/ext/zdd_so/include/trsact.c +723 -0
- data/ext/zdd_so/include/trsact.h +167 -0
- data/ext/zdd_so/include/vec.c +583 -0
- data/ext/zdd_so/include/vec.h +159 -0
- data/ext/zdd_so/lcm-vsop.cc +596 -0
- data/ext/zdd_so/print.cc +683 -0
- data/ext/zdd_so/table.cc +330 -0
- data/ext/zdd_so/vsop.h +88 -0
- data/ext/zdd_so/zdd_so.cpp +3277 -0
- data/lib/nysol/zdd.rb +31 -0
- metadata +131 -0
data/ext/zdd_so/bddc.h
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
/*****************************************
|
2
|
+
* BDD Package (SAPPORO-1.57) - Header *
|
3
|
+
* (C) Shin-ichi MINATO (June 14, 2013) *
|
4
|
+
******************************************/
|
5
|
+
|
6
|
+
#ifndef bddc_h
|
7
|
+
#define bddc_h
|
8
|
+
|
9
|
+
#if (defined BDD_CPP)||(! defined B_OLDC)
|
10
|
+
# define B_ARG(a) a /* ANSI C style */
|
11
|
+
#else
|
12
|
+
# define B_ARG(a) () /* K&R C style */
|
13
|
+
#endif
|
14
|
+
|
15
|
+
/***************** Internal macro for index *****************/
|
16
|
+
#define B_VAR_WIDTH 16U /* Width of variable index */
|
17
|
+
#define B_VAR_MASK ((1U << B_VAR_WIDTH) - 1U)
|
18
|
+
|
19
|
+
/***************** Internal macro for bddp *****************/
|
20
|
+
#ifdef B_64
|
21
|
+
# define B_MSB_POS 39ULL
|
22
|
+
# define B_LSB_MASK 1ULL
|
23
|
+
#else
|
24
|
+
# define B_MSB_POS 31U
|
25
|
+
# define B_LSB_MASK 1U
|
26
|
+
#endif
|
27
|
+
#define B_MSB_MASK (B_LSB_MASK << B_MSB_POS)
|
28
|
+
#define B_INV_MASK B_LSB_MASK /* Mask of inverter-flag */
|
29
|
+
#define B_CST_MASK B_MSB_MASK /* Mask of constant-flag */
|
30
|
+
#define B_VAL_MASK (B_MSB_MASK - 1U)
|
31
|
+
/* Mask of value-field */
|
32
|
+
|
33
|
+
/***************** For stack overflow limit *****************/
|
34
|
+
extern const int BDD_RecurLimit;
|
35
|
+
extern int BDD_RecurCount;
|
36
|
+
|
37
|
+
/***************** External typedef *****************/
|
38
|
+
typedef unsigned int bddvar;
|
39
|
+
#ifdef B_64
|
40
|
+
typedef unsigned long long bddp;
|
41
|
+
#else
|
42
|
+
typedef unsigned int bddp;
|
43
|
+
#endif
|
44
|
+
|
45
|
+
/***************** External Macro *****************/
|
46
|
+
#define bddvarmax B_VAR_MASK /* Max value of variable index */
|
47
|
+
#define bddnull B_VAL_MASK /* Special value for null pointer */
|
48
|
+
#define bddfalse B_CST_MASK /* bddp of constant false (0) */
|
49
|
+
#define bddtrue (bddfalse ^ B_INV_MASK)
|
50
|
+
/* bddp of constant true (1) */
|
51
|
+
#define bddempty bddfalse /* bddp of empty ZBDD (0) */
|
52
|
+
#define bddsingle bddtrue /* bddp of single unit ZBDD (1) */
|
53
|
+
#define bddconst(c) (((c) & B_VAL_MASK) | B_CST_MASK)
|
54
|
+
/* bddp of a constant valued node */
|
55
|
+
#define bddvalmax B_VAL_MASK /* Max constant value */
|
56
|
+
|
57
|
+
#ifdef BDD_CPP
|
58
|
+
extern "C" {
|
59
|
+
#endif /* BDD_CPP */
|
60
|
+
|
61
|
+
/***************** External operations *****************/
|
62
|
+
|
63
|
+
/***************** Init. and config. ****************/
|
64
|
+
extern int bddinit B_ARG((bddp initsize, bddp limitsize));
|
65
|
+
extern bddvar bddnewvar B_ARG((void));
|
66
|
+
extern bddvar bddnewvaroflev B_ARG((bddvar lev));
|
67
|
+
extern bddvar bddlevofvar B_ARG((bddvar v));
|
68
|
+
extern bddvar bddvaroflev B_ARG((bddvar lev));
|
69
|
+
extern bddvar bddvarused B_ARG((void));
|
70
|
+
|
71
|
+
/************** Basic logic operations *************/
|
72
|
+
extern bddp bddprime B_ARG((bddvar v));
|
73
|
+
extern bddvar bddtop B_ARG((bddp f));
|
74
|
+
extern bddp bddcopy B_ARG((bddp f));
|
75
|
+
extern bddp bddnot B_ARG((bddp f));
|
76
|
+
extern bddp bddand B_ARG((bddp f, bddp g));
|
77
|
+
extern bddp bddor B_ARG((bddp f, bddp g));
|
78
|
+
extern bddp bddxor B_ARG((bddp f, bddp g));
|
79
|
+
extern bddp bddnand B_ARG((bddp f, bddp g));
|
80
|
+
extern bddp bddnor B_ARG((bddp f, bddp g));
|
81
|
+
extern bddp bddxnor B_ARG((bddp f, bddp g));
|
82
|
+
extern bddp bddat0 B_ARG((bddp f, bddvar v));
|
83
|
+
extern bddp bddat1 B_ARG((bddp f, bddvar v));
|
84
|
+
|
85
|
+
/********** Memory management and observation ***********/
|
86
|
+
extern void bddfree B_ARG((bddp f));
|
87
|
+
extern bddp bddused B_ARG((void));
|
88
|
+
extern int bddgc B_ARG((void));
|
89
|
+
extern bddp bddsize B_ARG((bddp f));
|
90
|
+
extern bddp bddvsize B_ARG((bddp *p, int lim));
|
91
|
+
extern void bddexport B_ARG((FILE *strm, bddp *p, int lim));
|
92
|
+
extern int bddimport B_ARG((FILE *strm, bddp *p, int lim));
|
93
|
+
extern void bdddump B_ARG((bddp f));
|
94
|
+
extern void bddvdump B_ARG((bddp *p, int lim));
|
95
|
+
extern void bddgraph B_ARG((bddp f));
|
96
|
+
extern void bddgraph0 B_ARG((bddp f));
|
97
|
+
extern void bddvgraph B_ARG((bddp *p, int lim));
|
98
|
+
extern void bddvgraph0 B_ARG((bddp *p, int lim));
|
99
|
+
|
100
|
+
/************** Advanced logic operations *************/
|
101
|
+
extern bddp bddlshift B_ARG((bddp f, bddvar shift));
|
102
|
+
extern bddp bddrshift B_ARG((bddp f, bddvar shift));
|
103
|
+
extern bddp bddsupport B_ARG((bddp f));
|
104
|
+
extern bddp bdduniv B_ARG((bddp f, bddp g));
|
105
|
+
extern bddp bddexist B_ARG((bddp f, bddp g));
|
106
|
+
extern bddp bddcofactor B_ARG((bddp f, bddp g));
|
107
|
+
extern int bddimply B_ARG((bddp f, bddp g));
|
108
|
+
extern bddp bddrcache B_ARG((unsigned char op, bddp f, bddp g));
|
109
|
+
extern void bddwcache
|
110
|
+
B_ARG((unsigned char op, bddp f, bddp g, bddp h));
|
111
|
+
|
112
|
+
/************** ZBDD operations *************/
|
113
|
+
extern bddp bddoffset B_ARG((bddp f, bddvar v));
|
114
|
+
extern bddp bddonset B_ARG((bddp f, bddvar v));
|
115
|
+
extern bddp bddonset0 B_ARG((bddp f, bddvar v));
|
116
|
+
extern bddp bddchange B_ARG((bddp f, bddvar v));
|
117
|
+
extern bddp bddintersec B_ARG((bddp f, bddp g));
|
118
|
+
extern bddp bddunion B_ARG((bddp f, bddp g));
|
119
|
+
extern bddp bddsubtract B_ARG((bddp f, bddp g));
|
120
|
+
extern bddp bddcard B_ARG((bddp f));
|
121
|
+
extern bddp bddlit B_ARG((bddp f));
|
122
|
+
extern bddp bddlen B_ARG((bddp f));
|
123
|
+
extern int bddimportz B_ARG((FILE *strm, bddp *p, int lim));
|
124
|
+
|
125
|
+
/************** SeqBDD operations *************/
|
126
|
+
extern bddp bddpush B_ARG((bddp f, bddvar v));
|
127
|
+
|
128
|
+
#ifdef BDD_CPP
|
129
|
+
}
|
130
|
+
#endif /* BDD_CPP */
|
131
|
+
|
132
|
+
#endif /* bddc_h */
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
cp = "$(srcdir)"
|
3
|
+
$CFLAGS = " -O3 -Wall -I. -I#{cp}/include -DB_STATIC -D_NO_MAIN_ -DLINE -fPIC -Wno-error=format-security"
|
4
|
+
$CPPFLAGS = " -O3 -Wall -I. -I#{cp}/include -DB_STATIC -D_NO_MAIN_ -DLINE -fPIC -Wno-error=format-security"
|
5
|
+
$CXXFLAGS = " -O3 -Wall -I. -I#{cp}/include -DB_STATIC -D_NO_MAIN_ -DLINE -fPIC -Wno-error=format-security"
|
6
|
+
|
7
|
+
|
8
|
+
$LOCAL_LIBS += " -lstdc++"
|
9
|
+
|
10
|
+
if RUBY_VERSION >= '2.0.0' then
|
11
|
+
if Gem::Platform::local.os =~ /darwin/ then
|
12
|
+
$CFLAGS += " -Wno-error=unused-command-line-argument-hard-error-in-future"
|
13
|
+
$CPPFLAGS += " -Wno-error=unused-command-line-argument-hard-error-in-future"
|
14
|
+
$LOCAL_LIBS += " -Wno-error=unused-command-line-argument-hard-error-in-future"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
if RUBY_VERSION < '1.9.0'
|
20
|
+
$CFLAGS += " -o $@"
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
create_makefile("nysol/zdd_so")
|
25
|
+
|
@@ -0,0 +1,211 @@
|
|
1
|
+
/*
|
2
|
+
array-based simple heap (fixex size)
|
3
|
+
12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp,
|
4
|
+
homepage: http://research.nii.ac.jp/~uno/index.html */
|
5
|
+
/* This program is available for only academic use, basically.
|
6
|
+
Anyone can modify this program, but he/she has to write down
|
7
|
+
the change of the modification on the top of the source code.
|
8
|
+
Neither contact nor appointment to Takeaki Uno is needed.
|
9
|
+
If one wants to re-distribute this code, do not forget to
|
10
|
+
refer the newest code, and show the link to homepage of
|
11
|
+
Takeaki Uno, to notify the news about the codes for the users.
|
12
|
+
For the commercial use, please make a contact to Takeaki Uno. */
|
13
|
+
|
14
|
+
#ifndef _aheap_c_
|
15
|
+
#define _aheap_c_
|
16
|
+
|
17
|
+
#include"aheap.h"
|
18
|
+
|
19
|
+
QSORT_TYPE (AHEAP_KEY, AHEAP_KEY)
|
20
|
+
QSORT_TYPE (AHEAP_ID, AHEAP_ID)
|
21
|
+
AHEAP INIT_AHEAP = {TYPE_AHEAP,NULL,0,0};
|
22
|
+
|
23
|
+
/* allocate memory */
|
24
|
+
void AHEAP_alloc (AHEAP *H, AHEAP_ID num){
|
25
|
+
AHEAP_ID i;
|
26
|
+
#ifdef ERROR_CHECK
|
27
|
+
if ( num<0 ) error_num ("size is out of range", num, EXIT);
|
28
|
+
#endif
|
29
|
+
*H = INIT_AHEAP;
|
30
|
+
if ( num>0 ) malloc2 (H->v, num*2, "AHEAP_alloc: H->v", EXIT);
|
31
|
+
H->end = num;
|
32
|
+
ARY_FILL (H->v, 0, num*2, AHEAP_KEYHUGE);
|
33
|
+
for (i=0 ; i<num-1 ; i=i*2+1);
|
34
|
+
H->base = i - num + 1;
|
35
|
+
}
|
36
|
+
|
37
|
+
/* termination */
|
38
|
+
void AHEAP_end (AHEAP *H){
|
39
|
+
free2 (H->v);
|
40
|
+
*H = INIT_AHEAP;
|
41
|
+
}
|
42
|
+
|
43
|
+
/* return the index of the leaf having the minimum key among the descendants
|
44
|
+
of the given node i. If several leaves with the smallest key are there,
|
45
|
+
return the minimum index among them if f=0, maximum index if f=1, and
|
46
|
+
random choice if f=2 */
|
47
|
+
/* random choice version. choose one child to go down randomly for each node,
|
48
|
+
thus it is not uniformly random */
|
49
|
+
AHEAP_ID AHEAP_findmin_node (AHEAP *H, AHEAP_ID i, int f){
|
50
|
+
if ( H->end <= 0 ) return (-1);
|
51
|
+
while ( i < H->end-1 ){
|
52
|
+
if ( H->v[i*2+1] == H->v[i] )
|
53
|
+
if ( H->v[i*2+2] == H->v[i] )
|
54
|
+
if ( f == 2 ) i = i*2 + 1 + rand()%2;
|
55
|
+
else i = i*2+1+f;
|
56
|
+
else i = i*2+1;
|
57
|
+
else i = i*2+2;
|
58
|
+
}
|
59
|
+
return (AHEAP_IDX(*H, i) );
|
60
|
+
}
|
61
|
+
AHEAP_ID AHEAP_findmin_head (AHEAP *H){ return (AHEAP_findmin_node (H, 0, 0) ); }
|
62
|
+
AHEAP_ID AHEAP_findmin_tail (AHEAP *H){ return (AHEAP_findmin_node (H, 0, 1) ); }
|
63
|
+
AHEAP_ID AHEAP_findmin_rnd (AHEAP *H){ return (AHEAP_findmin_node (H, 0, 2) ); }
|
64
|
+
|
65
|
+
/* return the index of the leaf having smaller value than a among the
|
66
|
+
descendants of the given node i. If several leaves with the smallest key
|
67
|
+
are there, return the minimum index among them if f=0, maximum index if f=1,
|
68
|
+
and random choice if f=2 */
|
69
|
+
AHEAP_ID AHEAP_findlow_node (AHEAP *H, AHEAP_KEY a, AHEAP_ID i, int f){
|
70
|
+
if ( H->end == 0 ) return (-1);
|
71
|
+
if ( H->v[0] > a ) return (-1);
|
72
|
+
while ( i < H->end-1 ){
|
73
|
+
if ( f == 2 ) {
|
74
|
+
if ( H->v[i*2+1] <= a )
|
75
|
+
if ( H->v[i*2+2] <= a ) i = i*2 + 1 + rand()%2;
|
76
|
+
else i = i*2+1;
|
77
|
+
else i = i*2+2;
|
78
|
+
} else if ( H->v[i*2+1] <= a ) i = i*2+1+f; else i = i*2+2-f;
|
79
|
+
}
|
80
|
+
return (AHEAP_IDX(*H, i) );
|
81
|
+
}
|
82
|
+
AHEAP_ID AHEAP_findlow_head (AHEAP *H, AHEAP_KEY a){ return (AHEAP_findlow_node (H, a, 0, 0) ); }
|
83
|
+
AHEAP_ID AHEAP_findlow_tail (AHEAP *H, AHEAP_KEY a){ return (AHEAP_findlow_node (H, a, 0, 1) ); }
|
84
|
+
AHEAP_ID AHEAP_findlow_rnd (AHEAP *H, AHEAP_KEY a){ return (AHEAP_findlow_node (H, a, 0, 2) ); }
|
85
|
+
|
86
|
+
/* return the index of the leaf having smaller value than a next/previous to
|
87
|
+
leaf i. return -1 if such a leaf does not exist */
|
88
|
+
AHEAP_ID AHEAP_findlow_nxt (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){
|
89
|
+
if ( H->end == 0 ) return (-1);
|
90
|
+
for (i=AHEAP_LEAF(*H,i); i>0 ; i=(i-1)/2){
|
91
|
+
/* i is the child of smaller index, and the key of the sibling of i is less than a */
|
92
|
+
if ( i%2 == 1 && H->v[i+1] <= a ) return (AHEAP_findlow_node (H, a, i+1, 0) );
|
93
|
+
}
|
94
|
+
return (-1);
|
95
|
+
}
|
96
|
+
AHEAP_ID AHEAP_findlow_prv (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){
|
97
|
+
if ( H->end == 0 ) return (-1);
|
98
|
+
for (i=AHEAP_LEAF(*H,i); i>0 ; i=(i-1)/2){
|
99
|
+
/* i is the child of larger index, and the key of the sibling of i is less than a */
|
100
|
+
if ( i%2 == 0 && H->v[i-1] <= a ) return (AHEAP_findlow_node (H, a, i-1, 1) );
|
101
|
+
}
|
102
|
+
return (-1);
|
103
|
+
}
|
104
|
+
|
105
|
+
/* change the key of node i to a /Add a to the key of node i, and update heap H */
|
106
|
+
void AHEAP_chg (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){
|
107
|
+
i = AHEAP_LEAF (*H, i);
|
108
|
+
H->v[i] = a;
|
109
|
+
AHEAP_update (H, i);
|
110
|
+
}
|
111
|
+
void AHEAP_add (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){
|
112
|
+
i = AHEAP_LEAF (*H, i);
|
113
|
+
H->v[i] += a;
|
114
|
+
AHEAP_update (H, i);
|
115
|
+
}
|
116
|
+
|
117
|
+
/* update the ancestor of node i */
|
118
|
+
void AHEAP_update (AHEAP *H, AHEAP_ID i){
|
119
|
+
AHEAP_ID j;
|
120
|
+
AHEAP_KEY a = H->v[i];
|
121
|
+
while ( i>0 ){
|
122
|
+
j = i - 1 + (i%2)*2; /* j = the sibling of i */
|
123
|
+
i = (i-1) / 2;
|
124
|
+
if ( H->v[j] < a ) a = H->v[j];
|
125
|
+
if ( a == H->v[i] ) break;
|
126
|
+
H->v[i] = a;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
/* find the leaf with the minimum key value among the leaves having index
|
131
|
+
smaller/larger than i, or between i and j */
|
132
|
+
AHEAP_ID AHEAP_upper_min (AHEAP *H, AHEAP_ID i){
|
133
|
+
AHEAP_ID fi=0, j = AHEAP_LEAF (*H, H->end - 1);
|
134
|
+
AHEAP_KEY fm = AHEAP_KEYHUGE;
|
135
|
+
if ( i == 0 ) return (AHEAP_findmin_head (H) );
|
136
|
+
i = AHEAP_LEAF (*H, i-1);
|
137
|
+
while ( i != j ){
|
138
|
+
if ( i%2 ){ /* if i is the child with smaller index */
|
139
|
+
if ( fm > H->v[i+1] ){
|
140
|
+
fm = H->v[i+1];
|
141
|
+
fi = i+1;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
i = (i-1)/2;
|
145
|
+
if ( j == i ) break; /* stop if the right pointer and the left pointer are the same */
|
146
|
+
j = (j-1)/2;
|
147
|
+
}
|
148
|
+
while ( fi < H->end-1 ) fi = fi*2 + (H->v[fi*2+1]<=fm?1:2);
|
149
|
+
return ( AHEAP_IDX(*H, fi) );
|
150
|
+
}
|
151
|
+
AHEAP_ID AHEAP_lower_min (AHEAP *H, AHEAP_ID i){
|
152
|
+
AHEAP_ID fi=0, j = AHEAP_LEAF (*H, 0);
|
153
|
+
AHEAP_KEY fm = AHEAP_KEYHUGE;
|
154
|
+
if ( i == H->end-1 ) return (AHEAP_findmin_head (H) );
|
155
|
+
i = AHEAP_LEAF (*H, i+1);
|
156
|
+
while ( i != j ){
|
157
|
+
if ( i%2 == 0 ){ /* if i is the child of larger index */
|
158
|
+
if ( fm > H->v[i-1] ){
|
159
|
+
fm = H->v[i-1];
|
160
|
+
fi = i-1;
|
161
|
+
}
|
162
|
+
}
|
163
|
+
j = (j-1)/2;
|
164
|
+
if ( j == i ) break; /* stop if the right pointer and the left pointer are the same */
|
165
|
+
i = (i-1)/2;
|
166
|
+
}
|
167
|
+
while ( fi < H->end-1 ) fi = fi*2 + (H->v[fi*2+1]<=fm?1:2);
|
168
|
+
return (AHEAP_IDX(*H, fi) );
|
169
|
+
}
|
170
|
+
|
171
|
+
/* find the index having the minimum among given two indices */
|
172
|
+
AHEAP_ID AHEAP_interval_min (AHEAP *H, AHEAP_ID i, AHEAP_ID j){
|
173
|
+
AHEAP_ID fi=0;
|
174
|
+
AHEAP_KEY fm = AHEAP_KEYHUGE;
|
175
|
+
if ( i == 0 ) return (AHEAP_lower_min (H, j) );
|
176
|
+
if ( j == H->end-1 ) return (AHEAP_upper_min (H, i) );
|
177
|
+
i = AHEAP_LEAF (*H, i-1);
|
178
|
+
j = AHEAP_LEAF (*H, j+1);
|
179
|
+
while ( i != j && i != j-1 ){
|
180
|
+
if ( i%2 ){ /* if i is the child of smaller index */
|
181
|
+
if ( fm > H->v[i+1] ){
|
182
|
+
fm = H->v[i+1];
|
183
|
+
fi = i+1;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
i = (i-1)/2;
|
187
|
+
if ( j == i || j == i+1 ) break; /* stop if the right pointer and the left pointer are the same */
|
188
|
+
if ( j%2 == 0 ){ /* if j is the child of larger index */
|
189
|
+
if ( fm > H->v[j-1] ){
|
190
|
+
fm = H->v[j-1];
|
191
|
+
fi = j-1;
|
192
|
+
}
|
193
|
+
}
|
194
|
+
j = (j-1)/2;
|
195
|
+
}
|
196
|
+
while ( fi < H->end-1 )
|
197
|
+
fi = fi*2 + (H->v[fi*2+1] <= fm?1:2);
|
198
|
+
return (AHEAP_IDX(*H, fi) );
|
199
|
+
}
|
200
|
+
|
201
|
+
/* print heap keys according to the structure of the heap */
|
202
|
+
void AHEAP_print (AHEAP *H){
|
203
|
+
AHEAP_ID i, j=1;
|
204
|
+
while ( j<=H->end*2-1 ){
|
205
|
+
FLOOP (i, j-1, MIN(j, H->end)*2-1) printf (AHEAP_KEYF ",", H->v[i] );
|
206
|
+
printf ("\n");
|
207
|
+
j = j*2;
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
#endif
|
@@ -0,0 +1,111 @@
|
|
1
|
+
/*
|
2
|
+
array-based simple heap (fixed size)
|
3
|
+
12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp,
|
4
|
+
homepage: http://research.nii.ac.jp/~uno/index.html */
|
5
|
+
/* This program is available for only academic use, basically.
|
6
|
+
Anyone can modify this program, but he/she has to write down
|
7
|
+
the change of the modification on the top of the source code.
|
8
|
+
Neither contact nor appointment to Takeaki Uno is needed.
|
9
|
+
If one wants to re-distribute this code, do not forget to
|
10
|
+
refer the newest code, and show the link to homepage of
|
11
|
+
Takeaki Uno, to notify the news about the codes for the users.
|
12
|
+
For the commercial use, please make a contact to Takeaki Uno. */
|
13
|
+
|
14
|
+
/* bench mark
|
15
|
+
PentiumIII 500MHz, Memory 256MB Linux
|
16
|
+
values 0-1,000,000 : set & del & get 1,000,000 times
|
17
|
+
2.55sec
|
18
|
+
|
19
|
+
# rotation == 1/5 per 1 set/del
|
20
|
+
|
21
|
+
*** simple array ***
|
22
|
+
value 0-1,000,000 set & set & set 1,000,000 times,
|
23
|
+
0.88sec
|
24
|
+
*/
|
25
|
+
|
26
|
+
#ifndef _aheap_h_
|
27
|
+
#define _aheap_h_
|
28
|
+
|
29
|
+
#include"stdlib2.h"
|
30
|
+
|
31
|
+
#ifndef AHEAP_KEY
|
32
|
+
#ifdef AHEAP_KEY_DOUBLE
|
33
|
+
#define AHEAP_KEY double
|
34
|
+
#define AHEAP_KEYHUGE DOUBLEHUGE
|
35
|
+
#define AHEAP_KEYF "%f"
|
36
|
+
#elif defined(AHEAP_KEY_WEIGHT)
|
37
|
+
#define AHEAP_KEY WEIGHT
|
38
|
+
#define AHEAP_KEYHUGE WEIGHTHUGE
|
39
|
+
#define AHEAP_KEYF WEIGHTF
|
40
|
+
#else
|
41
|
+
#define AHEAP_KEY int
|
42
|
+
#define AHEAP_KEYHUGE INTHUGE
|
43
|
+
#define AHEAP_KEYF "%d"
|
44
|
+
#endif
|
45
|
+
#endif
|
46
|
+
|
47
|
+
#ifndef AHEAP_ID
|
48
|
+
#define AHEAP_ID int
|
49
|
+
#define AHEAP_ID_END INTHUGE
|
50
|
+
#define AHEAP_IDF "%d"
|
51
|
+
#endif
|
52
|
+
|
53
|
+
#define AHEAP_IDX(H,i) (((i)+1-(H).base)%(H).end)
|
54
|
+
#define AHEAP_LEAF(H,i) (((i)+(H).base)%(H).end+(H).end-1)
|
55
|
+
#define AHEAP_H(H,i) (H).v[(((i)+(H).base)%(H).end+(H).end-1)]
|
56
|
+
|
57
|
+
typedef struct {
|
58
|
+
unsigned char type;
|
59
|
+
AHEAP_KEY *v; /* array for heap key */
|
60
|
+
int end; /* the number of maximum elements */
|
61
|
+
int base; /* the constant for set 0 to the leftmost leaf */
|
62
|
+
} AHEAP;
|
63
|
+
|
64
|
+
QSORT_TYPE_HEADER (AHEAP_KEY, AHEAP_KEY)
|
65
|
+
QSORT_TYPE_HEADER (AHEAP_ID, AHEAP_ID)
|
66
|
+
extern AHEAP INIT_AHEAP;
|
67
|
+
|
68
|
+
/* initialization. allocate memory for H and fill it by +infinity */
|
69
|
+
void AHEAP_alloc (AHEAP *H, int num);
|
70
|
+
void AHEAP_end (AHEAP *H);
|
71
|
+
|
72
|
+
/* return the index of the leaf having the minimum key among the descendants
|
73
|
+
of the given node i. If several leaves with the smallest key are there,
|
74
|
+
return the minimum index among them if f=0, maximum index if f=1, and
|
75
|
+
random choice if f=2 */
|
76
|
+
AHEAP_ID AHEAP_findmin_node (AHEAP *H, AHEAP_ID i, int f);
|
77
|
+
AHEAP_ID AHEAP_findmin_head (AHEAP *H);
|
78
|
+
AHEAP_ID AHEAP_findmin_tail (AHEAP *H);
|
79
|
+
AHEAP_ID AHEAP_findmin_rnd (AHEAP *H);
|
80
|
+
|
81
|
+
/* return the index of the leaf having smaller value than a among the
|
82
|
+
descendants of the given node i. If several leaves with the smallest key
|
83
|
+
are there, return the minimum index among them if f=0, maximum index if f=1,
|
84
|
+
and random choice if f=2 */
|
85
|
+
AHEAP_ID AHEAP_findlow_node (AHEAP *H, AHEAP_KEY a, AHEAP_ID i, int f);
|
86
|
+
AHEAP_ID AHEAP_findlow_head (AHEAP *H, AHEAP_KEY a);
|
87
|
+
AHEAP_ID AHEAP_findlow_tail (AHEAP *H, AHEAP_KEY a);
|
88
|
+
AHEAP_ID AHEAP_findlow_rnd (AHEAP *H, AHEAP_KEY a);
|
89
|
+
|
90
|
+
/* return the index of the leaf having smaller value than a next/previous to
|
91
|
+
leaf i. return -1 if such a leaf does not exist */
|
92
|
+
AHEAP_ID AHEAP_findlow_nxt (AHEAP *H, AHEAP_ID i, AHEAP_KEY a);
|
93
|
+
AHEAP_ID AHEAP_findlow_prv (AHEAP *H, AHEAP_ID i, AHEAP_KEY a);
|
94
|
+
|
95
|
+
/* change the key of node i to a /Add a to the key of node i, and update heap H */
|
96
|
+
void AHEAP_chg (AHEAP *H, AHEAP_ID i, AHEAP_KEY a);
|
97
|
+
void AHEAP_add (AHEAP *H, AHEAP_ID i, AHEAP_KEY a);
|
98
|
+
|
99
|
+
/* update the ancestor of node i */
|
100
|
+
void AHEAP_update (AHEAP *H, AHEAP_ID i);
|
101
|
+
|
102
|
+
/* find the leaf with the minimum key value among the leaves having index
|
103
|
+
smaller/larger than i, or between i and j */
|
104
|
+
AHEAP_ID AHEAP_upper_min (AHEAP *H, AHEAP_ID i);
|
105
|
+
AHEAP_ID AHEAP_lower_min (AHEAP *H, AHEAP_ID i);
|
106
|
+
AHEAP_ID AHEAP_interval_min (AHEAP *H, AHEAP_ID i, AHEAP_ID j);
|
107
|
+
|
108
|
+
/* print heap keys according to the structure of the heap */
|
109
|
+
void AHEAP_print (AHEAP *H);
|
110
|
+
|
111
|
+
#endif
|