nysol-zdd 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|