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
@@ -0,0 +1,160 @@
|
|
1
|
+
/* Common problem input/output routines /structure
|
2
|
+
25/Nov/2007 by Takeaki Uno e-mail:uno@nii.jp,
|
3
|
+
homepage: http://research.nii.ac.jp/~uno/index.html */
|
4
|
+
/* This program is available for only academic use, basically.
|
5
|
+
Anyone can modify this program, but he/she has to write down
|
6
|
+
the change of the modification on the top of the source code.
|
7
|
+
Neither contact nor appointment to Takeaki Uno is needed.
|
8
|
+
If one wants to re-distribute this code, do not forget to
|
9
|
+
refer the newest code, and show the link to homepage of
|
10
|
+
Takeaki Uno, to notify the news about the codes for the users.
|
11
|
+
For the commercial use, please make a contact to Takeaki Uno. */
|
12
|
+
|
13
|
+
/***************************************************/
|
14
|
+
|
15
|
+
#ifndef _problem_h_
|
16
|
+
#define _problem_h_
|
17
|
+
|
18
|
+
#include"stdlib2.h"
|
19
|
+
#include"queue.h"
|
20
|
+
#include"itemset.h"
|
21
|
+
|
22
|
+
#define PROBLEM_FREQSET 1
|
23
|
+
#define PROBLEM_MAXIMAL 2
|
24
|
+
#define PROBLEM_CLOSED 4
|
25
|
+
#define PROBLEM_EX_MAXIMAL 8
|
26
|
+
#define PROBLEM_EX_CLOSED 16
|
27
|
+
|
28
|
+
/***** parameters for PROBLEM initialization, given to flag *****/
|
29
|
+
|
30
|
+
#define PROBLEM_PRINT_DENSE 4 // print density threshold
|
31
|
+
#define PROBLEM_PRINT_SHRINK 8 // print properties of shrinked database
|
32
|
+
#define PROBLEM_PRINT_FRQ 16 // print density threshold
|
33
|
+
#define PROBLEM_NORMALIZE 32 // print density threshold
|
34
|
+
|
35
|
+
#define PROBLEM_ITEMARY 128 // alloc itemary
|
36
|
+
#define PROBLEM_ITEMJUMP 256 // alloc itemjump
|
37
|
+
#define PROBLEM_ITEMFLAG 512 // alloc itemflag
|
38
|
+
#define PROBLEM_ITEMMARK 1024 // alloc itemmark
|
39
|
+
#define PROBLEM_ITEMCAND 2048 // alloc itemcand
|
40
|
+
#define PROBLEM_VECARY 4096 // alloc itemary
|
41
|
+
#define PROBLEM_VECJUMP 8192 // alloc vecjump
|
42
|
+
#define PROBLEM_VECFLAG 16384 // alloc vecflag
|
43
|
+
#define PROBLEM_VECMARK 32768 // alloc vecmark
|
44
|
+
#define PROBLEM_VECCAND 65536 // alloc veccand
|
45
|
+
//4194304
|
46
|
+
#define PROBLEM_OCC_T 524288 // alloc occ_t
|
47
|
+
#define PROBLEM_SHIFT 1048576 // allocate shift
|
48
|
+
#define PROBLEM_OCC_W 2097152 // weight/positive-weight sum for items
|
49
|
+
#define PROBLEM_OCC_PW 4194304 // weight/positive-weight sum for items
|
50
|
+
#define PROBLEM_OCC_W2 8388608 // weight/positive-weight sum for items
|
51
|
+
|
52
|
+
#define PROBLEM_OCC1 16 // alloc occ
|
53
|
+
#define PROBLEM_OCC2 32 // alloc occ and ins all to list 0
|
54
|
+
#define PROBLEM_OCC3 48 // alloc occ and ins all to list "siz"
|
55
|
+
|
56
|
+
typedef struct {
|
57
|
+
clock_t start_time, end_time;
|
58
|
+
int problem;
|
59
|
+
LONG prog;
|
60
|
+
int prog2;
|
61
|
+
double dense;
|
62
|
+
char *input_fname;
|
63
|
+
char *output_fname;
|
64
|
+
char *weight_fname;
|
65
|
+
char *table_fname, *table2_fname;
|
66
|
+
char *position_fname, *position2_fname;
|
67
|
+
|
68
|
+
char *sgraph_fname, *sgraph2_fname;
|
69
|
+
char *sgraph_wfname, *sgraph2_wfname;
|
70
|
+
char *agraph_fname, *agraph2_fname;
|
71
|
+
char *trsact_fname, *trsact_fname2, *trsact_wfname, *trsact_wfname2, *trsact_pfname;
|
72
|
+
char *trsact2_fname, *trsact2_fname2, *trsact2_wfname, *trsact2_wfname2, *trsact2_pfname;
|
73
|
+
char *seq_fname, *seq2_fname;
|
74
|
+
char *fstar_fname, *fstar2_fname;
|
75
|
+
char *mat_fname, *mat2_fname;
|
76
|
+
char *smat_fname, *smat2_fname;
|
77
|
+
char *setfamily_fname, *setfamily2_fname;
|
78
|
+
char *setfamily_wfname, *setfamily2_wfname;
|
79
|
+
|
80
|
+
ITEMSET II, II2;
|
81
|
+
QUEUE ff; // for agraph search
|
82
|
+
int *vf, *dep; // for agraph search
|
83
|
+
|
84
|
+
int root, dir, edge_dir;
|
85
|
+
double th, th2, th3; // thresholds
|
86
|
+
double ratio, ratio2; // ratio
|
87
|
+
int num, siz, dim, len;
|
88
|
+
QUEUE_INT clms;
|
89
|
+
VEC_ID rows;
|
90
|
+
|
91
|
+
QUEUE_ID **shift;
|
92
|
+
QUEUE itemjump, itemcand, vecjump, veccand, *OQ, *OQ2, *VQ, *VQ2; // for delivery
|
93
|
+
QUEUE_INT *itemary;
|
94
|
+
int *itemmark, *itemflag, *vecmark, *vecflag; // mark for vector
|
95
|
+
VEC_ID *vecary, *occ_t;
|
96
|
+
WEIGHT *occ_w, *occ_pw, *occ_w2, *occ_pw2;
|
97
|
+
QUEUE oo;
|
98
|
+
|
99
|
+
char *pat; // pattern string
|
100
|
+
int plen, perr; // pattern length and #error allowed
|
101
|
+
|
102
|
+
#ifdef _alist_h_
|
103
|
+
MALIST occ;
|
104
|
+
#endif
|
105
|
+
|
106
|
+
#ifdef _sgraph_h_
|
107
|
+
SGRAPH SG, SG2;
|
108
|
+
#endif
|
109
|
+
|
110
|
+
#ifdef _agraph_h_
|
111
|
+
AGRAPH AG, AG2;
|
112
|
+
#endif
|
113
|
+
|
114
|
+
#ifdef _trsact_h_
|
115
|
+
TRSACT TT, TT2;
|
116
|
+
#endif
|
117
|
+
|
118
|
+
#ifdef _seq_h_
|
119
|
+
SEQ SS, SS2;
|
120
|
+
#endif
|
121
|
+
|
122
|
+
#ifdef _fstar_h_
|
123
|
+
FSTAR FS, FS2;
|
124
|
+
#endif
|
125
|
+
|
126
|
+
#ifdef _vec_h_
|
127
|
+
MAT MM, MM2;
|
128
|
+
SMAT SM, SM2;
|
129
|
+
SETFAMILY FF, FF2;
|
130
|
+
#endif
|
131
|
+
|
132
|
+
} PROBLEM;
|
133
|
+
|
134
|
+
|
135
|
+
/***** print filename information ****/
|
136
|
+
void PROBLEM_print (PROBLEM *P);
|
137
|
+
|
138
|
+
/***** print usage of the program *****/
|
139
|
+
void PROBLEM_error ();
|
140
|
+
|
141
|
+
/***** read parameters given by command line *****/
|
142
|
+
void PROBLEM_read_param (int argc, char *argv[], PROBLEM *P);
|
143
|
+
|
144
|
+
/***** PROBLEM and ITEMSET initialization *****/
|
145
|
+
/* all pointers are set to NULL, but don't touch filenames */
|
146
|
+
void PROBLEM_init (PROBLEM *P);
|
147
|
+
|
148
|
+
/***** PROBLEM initialization: load the files given by filenames ******/
|
149
|
+
void PROBLEM_init2 (PROBLEM *P, int flag);
|
150
|
+
|
151
|
+
/***** allocate memory according to flag *****/
|
152
|
+
void PROBLEM_alloc (PROBLEM *PP, QUEUE_ID siz, QUEUE_ID siz2, size_t siz3, PERM *p, int f);
|
153
|
+
|
154
|
+
/* termination of problem */
|
155
|
+
void PROBLEM_end (PROBLEM *PP);
|
156
|
+
|
157
|
+
|
158
|
+
#endif
|
159
|
+
|
160
|
+
|
@@ -0,0 +1,518 @@
|
|
1
|
+
/* Library of queue: spped priority implementation
|
2
|
+
12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp,
|
3
|
+
homepage: http://research.nii.ac.jp/~uno/index.html */
|
4
|
+
/* This program is available for only academic use, basically.
|
5
|
+
Anyone can modify this program, but he/she has to write down
|
6
|
+
the change of the modification on the top of the source code.
|
7
|
+
Neither contact nor appointment to Takeaki Uno is needed.
|
8
|
+
If one wants to re-distribute this code, do not forget to
|
9
|
+
refer the newest code, and show the link to homepage of
|
10
|
+
Takeaki Uno, to notify the news about the codes for the users.
|
11
|
+
For the commercial use, please make a contact to Takeaki Uno. */
|
12
|
+
|
13
|
+
#ifndef _queue_c_
|
14
|
+
#define _queue_c_
|
15
|
+
|
16
|
+
|
17
|
+
#include"queue.h"
|
18
|
+
#include"stdlib2.c"
|
19
|
+
|
20
|
+
QSORT_TYPE(QUEUE_INT, QUEUE_INT)
|
21
|
+
QSORT_TYPE(QUEUE_ID, QUEUE_ID)
|
22
|
+
QUEUE INIT_QUEUE = {TYPE_QUEUE,NULL,0,0,0};
|
23
|
+
QUEUE_INT *common_QUEUE_INTp;
|
24
|
+
|
25
|
+
/* initialization, not fill the memory by 0 */
|
26
|
+
void QUEUE_alloc (QUEUE *Q, QUEUE_ID siz){
|
27
|
+
*Q = INIT_QUEUE;
|
28
|
+
Q->end = siz+1;
|
29
|
+
malloc2 (Q->v, siz+1, "QUEUE_alloc: Q->v", EXIT);
|
30
|
+
}
|
31
|
+
|
32
|
+
/* termination processing */
|
33
|
+
void QUEUE_end (QUEUE *Q){
|
34
|
+
free2 (Q->v);
|
35
|
+
*Q = INIT_QUEUE;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
/* tranpose the matrix ; counting/transpose/memory_allocate */
|
40
|
+
void QUEUE_delivery(QUEUE *OQ, VEC_ID *c, QUEUE *jump, QUEUE *Q, QUEUE *occ, VEC_ID t, QUEUE_INT M){ VEC_ID i, e;
|
41
|
+
QUEUE_INT *x;
|
42
|
+
FLOOP(i, 0, occ? occ->t: t){
|
43
|
+
e = occ? occ->v[i]: i;
|
44
|
+
if ( c ){
|
45
|
+
if ( jump ){ MLOOP (x, Q[e].v, M){ if ( c[*x]==0 ) ARY_INS (*jump, *x); c[*x]++; }
|
46
|
+
} else { MLOOP (x, Q[e].v, M){ c[*x]++; }}
|
47
|
+
} else {
|
48
|
+
if ( jump ){ MLOOP (x, Q[e].v, M){ if ( OQ[*x].t==0 ) ARY_INS (*jump, *x); ARY_INS (OQ[*x], e); }
|
49
|
+
} else MLOOP (x, Q[e].v, M){ ARY_INS (OQ[*x], e); }
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
/* sort a QUEUE with WEIGHT, with already allocated memory */
|
55
|
+
void QUEUE_perm_WEIGHT (QUEUE *Q, WEIGHT *w, PERM *invperm, int flag){
|
56
|
+
WEIGHT y;
|
57
|
+
if ( w ){
|
58
|
+
qsort_perm__QUEUE_INT (Q->v, Q->t, invperm, flag);
|
59
|
+
ARY_INVPERMUTE_ (w, invperm, y, Q->t);
|
60
|
+
}
|
61
|
+
qsort_QUEUE_INT (Q->v, Q->t, flag);
|
62
|
+
}
|
63
|
+
|
64
|
+
/* remove (or unify) the consecutive same ID's in a QUEUE (duplication delete, if sorted) */
|
65
|
+
void QUEUE_rm_dup_WEIGHT (QUEUE *Q, WEIGHT *w){
|
66
|
+
VEC_ID j, jj=0;
|
67
|
+
if ( w ){
|
68
|
+
FLOOP (j, 1, Q->t){
|
69
|
+
if ( Q->v[j-1] != Q->v[j] ){
|
70
|
+
Q->v[++jj] = Q->v[j];
|
71
|
+
w[jj] = w[j];
|
72
|
+
} else w[jj] += w[j];
|
73
|
+
}
|
74
|
+
} else FLOOP (j, 1, Q->t){
|
75
|
+
if ( Q->v[j-1] != Q->v[j] ) Q->v[++jj] = Q->v[j];
|
76
|
+
}
|
77
|
+
if ( Q->t>0 ) Q->t = jj+1;
|
78
|
+
}
|
79
|
+
|
80
|
+
/***********************************************************************/
|
81
|
+
/* duplicate occ's in jump, ( copy occ's to allocated QUEUE array) */
|
82
|
+
/* Q[i].end := original item, clear each original occ */
|
83
|
+
/* buffer size is multiplied by u */
|
84
|
+
/*******************************************************/
|
85
|
+
void QUEUE_occ_dup (QUEUE *jump, QUEUE **QQ, QUEUE *Q, WEIGHT **ww, WEIGHT *w, WEIGHT **ppw, WEIGHT *pw, int u){
|
86
|
+
QUEUE_ID i, l=QUEUE_LENGTH_(*jump);
|
87
|
+
size_t cnt=0;
|
88
|
+
QUEUE_INT e, *x;
|
89
|
+
char *buf;
|
90
|
+
int unit = sizeof(*Q) + (w?sizeof(*w):0) + (pw?sizeof(*pw):0);
|
91
|
+
|
92
|
+
ENMAX (u, sizeof(*x));
|
93
|
+
MQUE_FLOOP (*jump, x) cnt += Q[*x].t;
|
94
|
+
if ( cnt == 0 ){ *QQ=NULL; return; }
|
95
|
+
malloc2 (buf, l*unit + (cnt+l)*u, "QUEUE_occ_dup: buf", EXIT);
|
96
|
+
*QQ = (QUEUE*)buf; buf += sizeof(*Q) *l;
|
97
|
+
if ( w ){ *ww = (WEIGHT *)buf; buf += sizeof(*w)*l; }
|
98
|
+
if ( pw ){ *ppw = (WEIGHT *)buf; buf += sizeof(*pw)*l; }
|
99
|
+
ARY_FLOOP (*jump, i, e){
|
100
|
+
(*QQ)[i].end = e;
|
101
|
+
(*QQ)[i].v = (QUEUE_INT *)buf;
|
102
|
+
(*QQ)[i].t = Q[e].t;
|
103
|
+
memcpy (buf, Q[e].v, (Q[e].t+1)*u);
|
104
|
+
buf += (Q[e].t+1) *u;
|
105
|
+
if ( w ) (*ww)[i] = w[e];
|
106
|
+
if ( pw ) (*ppw)[i] = pw[e];
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
/* return the position of the first element having value e. return -1 if no such element exists */
|
112
|
+
LONG QUEUE_ele (QUEUE *Q, QUEUE_INT e){
|
113
|
+
QUEUE_INT *x;
|
114
|
+
MQUE_FLOOP (*Q, x)
|
115
|
+
if ( *x == e ) return (x - Q->v);
|
116
|
+
return (-1);
|
117
|
+
}
|
118
|
+
|
119
|
+
/* insert an element to the tail */
|
120
|
+
void QUEUE_ins_ (QUEUE *Q, QUEUE_INT e){
|
121
|
+
Q->v[Q->t] = e;
|
122
|
+
Q->t++;
|
123
|
+
}
|
124
|
+
void QUEUE_ins (QUEUE *Q, QUEUE_INT e){
|
125
|
+
Q->v[Q->t] = e;
|
126
|
+
QUEUE_INCREMENT (*Q, Q->t);
|
127
|
+
if (Q->s == Q->t ) error_num ("QUEUE_ins: overflow", Q->s, EXIT);
|
128
|
+
}
|
129
|
+
|
130
|
+
/* insert an element to the head */
|
131
|
+
void QUEUE_ins_head_ (QUEUE *Q, QUEUE_INT e){
|
132
|
+
Q->s--;
|
133
|
+
Q->v[Q->s] = e;
|
134
|
+
}
|
135
|
+
void QUEUE_ins_head (QUEUE *Q, QUEUE_INT e){
|
136
|
+
QUEUE_DECREMENT(*Q,Q->s);
|
137
|
+
Q->v[Q->s] = e;
|
138
|
+
if (Q->s == Q->t ) error_num ("QUEUE_ins_head: underflow", Q->s, EXIT);
|
139
|
+
}
|
140
|
+
|
141
|
+
/* extract an element from the head, without checking underflow */
|
142
|
+
QUEUE_INT QUEUE_ext_ (QUEUE *Q){
|
143
|
+
(Q->s)++;
|
144
|
+
return (Q->v[Q->s-1]);
|
145
|
+
}
|
146
|
+
QUEUE_INT QUEUE_ext (QUEUE *Q){
|
147
|
+
QUEUE_INT e;
|
148
|
+
if (Q->s == Q->t ) error_num ("QUEUE_ext: empty queue", Q->s, EXIT0);
|
149
|
+
e = Q->v[Q->s];
|
150
|
+
QUEUE_INCREMENT(*Q,Q->s);
|
151
|
+
return ( e);
|
152
|
+
}
|
153
|
+
|
154
|
+
/* extract an element from the tail, without checking underflow */
|
155
|
+
QUEUE_INT QUEUE_ext_tail_ (QUEUE *Q){
|
156
|
+
(Q->t)--;
|
157
|
+
return (Q->v[Q->t]);
|
158
|
+
}
|
159
|
+
QUEUE_INT QUEUE_ext_tail (QUEUE *Q){
|
160
|
+
if ( Q->s == Q->t ) error_num ("QUEUE_ext_tail: empty queue", Q->s, EXIT0);
|
161
|
+
QUEUE_DECREMENT(*Q,Q->t);
|
162
|
+
return (Q->v[Q->t]);
|
163
|
+
}
|
164
|
+
|
165
|
+
/* remove the j-th element and replace it by the tail */
|
166
|
+
void QUEUE_rm_ (QUEUE *Q, QUEUE_ID j){
|
167
|
+
Q->t--;
|
168
|
+
Q->v[j] = Q->v[Q->t];
|
169
|
+
}
|
170
|
+
void QUEUE_rm (QUEUE *Q, QUEUE_ID j){
|
171
|
+
if ( Q->s <= Q->t ){
|
172
|
+
if ( j < Q->s || j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT);
|
173
|
+
} else if ( j < Q->s && j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT);
|
174
|
+
QUEUE_DECREMENT(*Q,Q->t);
|
175
|
+
Q->v[j] = Q->v[Q->t];
|
176
|
+
}
|
177
|
+
|
178
|
+
/* remove the j-th element and replace it by the head */
|
179
|
+
void QUEUE_rm_head_ (QUEUE *Q, QUEUE_ID j){
|
180
|
+
Q->v[j] = Q->v[Q->s];
|
181
|
+
Q->s++;
|
182
|
+
}
|
183
|
+
void QUEUE_rm_head (QUEUE *Q, QUEUE_ID j){
|
184
|
+
if ( Q->s <= Q->t ){
|
185
|
+
if ( j < Q->s || j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT);
|
186
|
+
} else if ( j < Q->s && j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT);
|
187
|
+
Q->v[j] = Q->v[Q->s];
|
188
|
+
QUEUE_INCREMENT(*Q,Q->s);
|
189
|
+
}
|
190
|
+
|
191
|
+
/* remove the j-th element and shift the following elements to fill the gap */
|
192
|
+
int QUEUE_rm_ele_ (QUEUE *Q, QUEUE_INT e){
|
193
|
+
QUEUE_ID i;
|
194
|
+
QUEUE_F_LOOP (*Q, i){
|
195
|
+
if ( Q->v[i] == e ){
|
196
|
+
memcpy ( &(Q->v[i]), &(Q->v[i+1]), (Q->t-i-1)*sizeof(QUEUE_INT));
|
197
|
+
Q->t--;
|
198
|
+
return (1);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
return (0);
|
202
|
+
}
|
203
|
+
/* insert e to the position determined by the increasing order of elements */
|
204
|
+
void QUEUE_ins_ele_ (QUEUE *Q, QUEUE_INT e){
|
205
|
+
QUEUE_ID i;
|
206
|
+
QUEUE_INT ee;
|
207
|
+
QUEUE_BE_LOOP_ (*Q, i, ee){
|
208
|
+
if ( ee<e ) break;
|
209
|
+
Q->v[i+1] = ee;
|
210
|
+
}
|
211
|
+
Q->v[i+1] = e;
|
212
|
+
Q->t++;
|
213
|
+
}
|
214
|
+
|
215
|
+
/* Append Q2 to the tail of Q1. Q2 will not be deleted */
|
216
|
+
void QUEUE_concat_ (QUEUE *Q1, QUEUE *Q2){
|
217
|
+
memcpy ( &(Q1->v[Q1->t]), &(Q2->v[Q2->s]), (Q2->t-Q2->s)*sizeof(QUEUE_INT));
|
218
|
+
Q1->t += Q2->t-Q2->s;
|
219
|
+
}
|
220
|
+
void QUEUE_concat (QUEUE *Q1, QUEUE *Q2){
|
221
|
+
QUEUE_ID e = Q2->s;
|
222
|
+
while ( e != Q2->t){
|
223
|
+
QUEUE_ins (Q1, Q2->v[e]);
|
224
|
+
QUEUE_INCREMENT(*Q2,e);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
/* Append Q2 to the tail of Q1. Q2 will be deleted */
|
228
|
+
void QUEUE_append_ (QUEUE *Q1, QUEUE *Q2){
|
229
|
+
QUEUE_concat_ (Q1, Q2);
|
230
|
+
QUEUE_RMALL (*Q2);
|
231
|
+
}
|
232
|
+
void QUEUE_append (QUEUE *Q1, QUEUE *Q2){ // more improvement can be
|
233
|
+
while ( Q2->s != Q2->t )
|
234
|
+
QUEUE_ins (Q1, QUEUE_ext(Q2));
|
235
|
+
}
|
236
|
+
|
237
|
+
/* Append from j to jj th elements to the tail of Q1. Q2 will not be deleted */
|
238
|
+
void QUEUE_subconcat_ (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj){
|
239
|
+
for ( ; j<=jj ; j++){
|
240
|
+
Q1->v[Q1->t] = Q2->v[j];
|
241
|
+
Q1->t++;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
void QUEUE_subconcat (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj){
|
245
|
+
while (1){
|
246
|
+
QUEUE_ins (Q1, Q2->v[j]);
|
247
|
+
if ( j == jj ) break;
|
248
|
+
QUEUE_INCREMENT(*Q2,j);
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
/* initialize Q1 by length of Q2, and copy Q2 to Q1 */
|
253
|
+
void QUEUE_store_ (QUEUE *Q1, QUEUE *Q2){
|
254
|
+
QUEUE_alloc (Q1, QUEUE_LENGTH(*Q2));
|
255
|
+
QUEUE_concat_ (Q1, Q2);
|
256
|
+
}
|
257
|
+
void QUEUE_store (QUEUE *Q1, QUEUE *Q2){
|
258
|
+
QUEUE_alloc (Q1, QUEUE_LENGTH(*Q2));
|
259
|
+
QUEUE_concat (Q1, Q2);
|
260
|
+
}
|
261
|
+
/* copy Q2 to Q1 and delete Q2 */
|
262
|
+
void QUEUE_restore_ (QUEUE *Q1, QUEUE *Q2){
|
263
|
+
QUEUE_RMALL (*Q1);
|
264
|
+
QUEUE_concat_ (Q1, Q2);
|
265
|
+
QUEUE_end (Q2);
|
266
|
+
}
|
267
|
+
void QUEUE_restore (QUEUE *Q1, QUEUE *Q2){
|
268
|
+
QUEUE_RMALL (*Q1);
|
269
|
+
QUEUE_concat (Q1, Q2);
|
270
|
+
QUEUE_end (Q2);
|
271
|
+
}
|
272
|
+
|
273
|
+
/* copy Q2 to Q1 */
|
274
|
+
void QUEUE_cpy_ (QUEUE *Q1, QUEUE *Q2){
|
275
|
+
Q1->s = Q1->t = 0;
|
276
|
+
QUEUE_concat_ (Q1, Q2);
|
277
|
+
}
|
278
|
+
void QUEUE_cpy (QUEUE *Q1, QUEUE *Q2){
|
279
|
+
QUEUE_RMALL (*Q1);
|
280
|
+
QUEUE_concat (Q1, Q2);
|
281
|
+
}
|
282
|
+
/* copy l elements of Q2 starting from s2 to the s1th position of Q1.
|
283
|
+
size of Q1 is not increasing */
|
284
|
+
void QUEUE_subcpy_ (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l){
|
285
|
+
memcpy ( &(Q1->v[s1]), &(Q2->v[s2]), (l-s2)*sizeof(QUEUE_INT));
|
286
|
+
}
|
287
|
+
void QUEUE_subcpy (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l){
|
288
|
+
for ( ; s2!=l ; QUEUE_INCREMENT(*Q1,s1),QUEUE_INCREMENT(*Q2,s2) )
|
289
|
+
Q1->v[s1] = Q2->v[s2];
|
290
|
+
Q1->v[s1] = Q2->v[s2];
|
291
|
+
}
|
292
|
+
|
293
|
+
/* duplicate Q2 to Q1. The memory size will be the length of Q2 */
|
294
|
+
QUEUE QUEUE_dup_ (QUEUE *Q){
|
295
|
+
QUEUE QQ;
|
296
|
+
QUEUE_alloc (&QQ, QUEUE_LENGTH_(*Q));
|
297
|
+
QUEUE_cpy_ (&QQ, Q);
|
298
|
+
return (QQ);
|
299
|
+
}
|
300
|
+
|
301
|
+
/* merge Q1 and Q2 by insert all elements of Q2 to Q1 with deleting duplications. Both Q1 and Q2 have to be sorted in increasing order */
|
302
|
+
void QUEUE_merge_ (QUEUE *Q1, QUEUE *Q2){
|
303
|
+
QUEUE_ID i=Q1->t-1, j=Q2->t-1, t=i+j-Q2->s+1;
|
304
|
+
QUEUE_INT ei, ej;
|
305
|
+
if ( i+1 == Q1->s || j+1 == Q2->s ){
|
306
|
+
QUEUE_concat_ (Q1, Q2);
|
307
|
+
return;
|
308
|
+
}
|
309
|
+
Q1->t = t+1;
|
310
|
+
ei = Q1->v[i];
|
311
|
+
ej = Q2->v[j];
|
312
|
+
while (1){
|
313
|
+
if ( ei > ej ){
|
314
|
+
Q1->v[t] = ei;
|
315
|
+
if ( i == Q1->s ){
|
316
|
+
QUEUE_subcpy_ (Q1, Q1->s, Q2, Q2->s, j);
|
317
|
+
return;
|
318
|
+
}
|
319
|
+
i--;
|
320
|
+
ei = Q1->v[i];
|
321
|
+
} else {
|
322
|
+
Q1->v[t] = ej;
|
323
|
+
if ( j == Q2->s ) return;
|
324
|
+
j--;
|
325
|
+
ej = Q2->v[j];
|
326
|
+
}
|
327
|
+
t--;
|
328
|
+
}
|
329
|
+
}
|
330
|
+
void QUEUE_merge (QUEUE *Q1, QUEUE *Q2){
|
331
|
+
QUEUE_ID i=Q1->t, j=Q2->t;
|
332
|
+
QUEUE_INT ei, ej;
|
333
|
+
QUEUE_ID t = (Q1->t + QUEUE_LENGTH(*Q2)-1) % Q1->end;
|
334
|
+
if ( QUEUE_LENGTH(*Q1) + QUEUE_LENGTH(*Q2) >= Q1->end ){
|
335
|
+
printf ("QUEUE_merge: overflow Q1->end="QUEUE_INTF", Q1length="QUEUE_INTF", Q2length="QUEUE_INTF"\n", Q1->end, QUEUE_LENGTH(*Q1), QUEUE_LENGTH(*Q2));
|
336
|
+
exit (1);
|
337
|
+
}
|
338
|
+
if ( i == Q1->s || j == Q2->s ){
|
339
|
+
QUEUE_concat (Q1, Q2);
|
340
|
+
return;
|
341
|
+
}
|
342
|
+
|
343
|
+
Q1->t = t;
|
344
|
+
QUEUE_DECREMENT(*Q1,i);
|
345
|
+
QUEUE_DECREMENT(*Q2,j);
|
346
|
+
ei = Q1->v[i];
|
347
|
+
ej = Q2->v[j];
|
348
|
+
while (1){
|
349
|
+
if ( ei > ej ){
|
350
|
+
Q1->v[t] = ei;
|
351
|
+
if ( i == Q1->s ){
|
352
|
+
QUEUE_subcpy (Q1, Q1->s, Q2, Q2->s, (j+Q2->end-Q2->s)%Q2->end);
|
353
|
+
return;
|
354
|
+
}
|
355
|
+
QUEUE_DECREMENT(*Q1,i);
|
356
|
+
ei = Q1->v[i];
|
357
|
+
} else {
|
358
|
+
Q1->v[t] = ej;
|
359
|
+
if ( j == Q2->s ) return;
|
360
|
+
QUEUE_DECREMENT(*Q2,j);
|
361
|
+
ej = Q2->v[j];
|
362
|
+
}
|
363
|
+
QUEUE_DECREMENT(*Q1,t);
|
364
|
+
}
|
365
|
+
}
|
366
|
+
|
367
|
+
/* delete all elements of Q1 included in Q2.
|
368
|
+
both Q1 and Q2 have to be sorted in increasing order */
|
369
|
+
void QUEUE_minus_ (QUEUE *Q1, QUEUE *Q2){
|
370
|
+
QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s;
|
371
|
+
while ( i != Q1->t && i2 != Q2->t){
|
372
|
+
if (Q1->v[i] > Q2->v[i2] ) i2++;
|
373
|
+
else {
|
374
|
+
if (Q1->v[i] < Q2->v[i2] ){
|
375
|
+
Q1->v[ii] = Q1->v[i];
|
376
|
+
ii++;
|
377
|
+
}
|
378
|
+
i++;
|
379
|
+
}
|
380
|
+
}
|
381
|
+
while ( i != Q1->t ){
|
382
|
+
Q1->v[ii] = Q1->v[i];
|
383
|
+
i++;
|
384
|
+
ii++;
|
385
|
+
}
|
386
|
+
Q1->t = ii;
|
387
|
+
}
|
388
|
+
void QUEUE_minus (QUEUE *Q1, QUEUE *Q2){
|
389
|
+
QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s;
|
390
|
+
while ( i != Q1->t && i2 != Q2->t ){
|
391
|
+
if ( Q1->v[i] > Q2->v[i2] ) QUEUE_INCREMENT (*Q2, i2);
|
392
|
+
else {
|
393
|
+
if ( Q1->v[i] < Q2->v[i2] ){
|
394
|
+
Q1->v[ii] = Q1->v[i];
|
395
|
+
QUEUE_INCREMENT (*Q1, ii);
|
396
|
+
}
|
397
|
+
QUEUE_INCREMENT (*Q1, i);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
while ( i != Q1->t ){
|
401
|
+
Q1->v[ii] = Q1->v[i];
|
402
|
+
QUEUE_INCREMENT (*Q1, i);
|
403
|
+
QUEUE_INCREMENT (*Q1, ii);
|
404
|
+
}
|
405
|
+
Q1->t = ii;
|
406
|
+
}
|
407
|
+
|
408
|
+
/* Delete all elements of Q1 which are not included in Q2.
|
409
|
+
both Q1 and Q2 have to be sorted in increasing order */
|
410
|
+
QUEUE_ID QUEUE_intsec_ (QUEUE *Q1, QUEUE *Q2){
|
411
|
+
QUEUE_ID i=Q1->s, i2 = Q2->s, c=0;
|
412
|
+
while ( i != Q1->t ){
|
413
|
+
if ( Q1->v[i] > Q2->v[i2] ){
|
414
|
+
if ( ++i2 == Q2->t ) break;
|
415
|
+
} else {
|
416
|
+
if ( Q1->v[i] == Q2->v[i2] ) c++;
|
417
|
+
i++;
|
418
|
+
}
|
419
|
+
}
|
420
|
+
return (c);
|
421
|
+
}
|
422
|
+
void QUEUE_and_ (QUEUE *Q1, QUEUE *Q2){
|
423
|
+
QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s;
|
424
|
+
while ( i != Q1->t ){
|
425
|
+
if ( Q1->v[i] > Q2->v[i2] ){
|
426
|
+
if ( ++i2 == Q2->t ) break;
|
427
|
+
} else {
|
428
|
+
if ( Q1->v[i] == Q2->v[i2] ) Q1->v[ii++] = Q1->v[i];
|
429
|
+
i++;
|
430
|
+
}
|
431
|
+
}
|
432
|
+
Q1->t = ii;
|
433
|
+
}
|
434
|
+
void QUEUE_and (QUEUE *Q1, QUEUE *Q2){
|
435
|
+
QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s;
|
436
|
+
while ( i != Q1->t && i2 != Q2->t){
|
437
|
+
if ( Q1->v[i] > Q2->v[i2] ) QUEUE_INCREMENT (*Q2, i2);
|
438
|
+
else {
|
439
|
+
if ( Q1->v[i] == Q2->v[i2] ){
|
440
|
+
Q1->v[ii] = Q1->v[i];
|
441
|
+
QUEUE_INCREMENT (*Q1, ii);
|
442
|
+
}
|
443
|
+
QUEUE_INCREMENT (*Q1, i);
|
444
|
+
}
|
445
|
+
}
|
446
|
+
Q1->t = ii;
|
447
|
+
}
|
448
|
+
|
449
|
+
/* insertion sort */
|
450
|
+
void QUEUE_sort (QUEUE *Q){
|
451
|
+
QUEUE_ID i = Q->s, j, jj;
|
452
|
+
QUEUE_INT e;
|
453
|
+
if ( i== Q->t ) return;
|
454
|
+
QUEUE_INCREMENT(*Q,i);
|
455
|
+
for ( ; i!=Q->t ; QUEUE_INCREMENT(*Q,i) ){
|
456
|
+
e=Q->v[i];
|
457
|
+
j=i;
|
458
|
+
while (1){
|
459
|
+
jj = j;
|
460
|
+
QUEUE_DECREMENT(*Q,j);
|
461
|
+
if ( Q->v[j] <= e ) { Q->v[jj] = e; break; }
|
462
|
+
Q->v[jj] = Q->v[j];
|
463
|
+
if ( j == Q->s) { Q->v[j] = e; break; }
|
464
|
+
}
|
465
|
+
}
|
466
|
+
}
|
467
|
+
|
468
|
+
|
469
|
+
/* print a queue */
|
470
|
+
void QUEUE_print (QUEUE *Q){
|
471
|
+
QUEUE_ID i;
|
472
|
+
for ( i=Q->s ; i!=Q->t ; ){
|
473
|
+
printf (QUEUE_INTF" ", Q->v[i]);
|
474
|
+
QUEUE_INCREMENT(*Q,i);
|
475
|
+
}
|
476
|
+
printf ("\n");
|
477
|
+
}
|
478
|
+
/* permutation version */
|
479
|
+
void QUEUE_perm_print (QUEUE *Q, QUEUE_ID *q){
|
480
|
+
QUEUE_ID i;
|
481
|
+
for ( i=Q->s ; i!=Q->t ; ){
|
482
|
+
printf (QUEUE_INTF" ", q[Q->v[i]]);
|
483
|
+
QUEUE_INCREMENT(*Q,i);
|
484
|
+
}
|
485
|
+
printf ("\n");
|
486
|
+
}
|
487
|
+
void QUEUE_printn (QUEUE *Q){
|
488
|
+
QUEUE_ID i;
|
489
|
+
for ( i=Q->s ; i!=Q->t ; ){
|
490
|
+
printf (QUEUE_INTF" ", Q->v[i]);
|
491
|
+
QUEUE_INCREMENT(*Q,i);
|
492
|
+
}
|
493
|
+
}
|
494
|
+
void QUEUE_perm_printn (QUEUE *Q, QUEUE_ID *q){
|
495
|
+
QUEUE_ID i;
|
496
|
+
for ( i=Q->s ; i!=Q->t ; ){
|
497
|
+
printf (QUEUE_INTF" ",q[Q->v[i]]);
|
498
|
+
QUEUE_INCREMENT(*Q,i);
|
499
|
+
}
|
500
|
+
}
|
501
|
+
void QUEUE_print_ (QUEUE *Q){
|
502
|
+
QUEUE_ID i;
|
503
|
+
printf("s="QUEUE_IDF",t="QUEUE_INTF": ", Q->s, Q->t);
|
504
|
+
for ( i=Q->s ; i!=Q->t ; ){
|
505
|
+
printf (QUEUE_INTF" ",Q->v[i]);
|
506
|
+
QUEUE_INCREMENT(*Q,i);
|
507
|
+
}
|
508
|
+
printf ("\n");
|
509
|
+
}
|
510
|
+
|
511
|
+
void QUEUE_print__ (QUEUE *Q){
|
512
|
+
QUEUE_ID i;
|
513
|
+
printf("s="QUEUE_IDF",t="QUEUE_IDF": ", Q->s, Q->t);
|
514
|
+
for ( i=Q->s ; i!=Q->t ; i++ ) printf (QUEUE_INTF" ",Q->v[i]);
|
515
|
+
printf ("\n");
|
516
|
+
}
|
517
|
+
|
518
|
+
#endif
|