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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/ext/zdd_so/BDD.cc +495 -0
  3. data/ext/zdd_so/BDD.h +356 -0
  4. data/ext/zdd_so/BDDDG.cc +1818 -0
  5. data/ext/zdd_so/BDDDG.h +107 -0
  6. data/ext/zdd_so/BDDHASH.cc +91 -0
  7. data/ext/zdd_so/BtoI.cc +503 -0
  8. data/ext/zdd_so/BtoI.h +144 -0
  9. data/ext/zdd_so/CtoI.cc +1072 -0
  10. data/ext/zdd_so/CtoI.h +186 -0
  11. data/ext/zdd_so/MLZBDDV.cc +153 -0
  12. data/ext/zdd_so/MLZBDDV.h +42 -0
  13. data/ext/zdd_so/SOP.cc +608 -0
  14. data/ext/zdd_so/SOP.h +199 -0
  15. data/ext/zdd_so/ZBDD.cc +1035 -0
  16. data/ext/zdd_so/ZBDD.h +243 -0
  17. data/ext/zdd_so/ZBDDDG.cc +1834 -0
  18. data/ext/zdd_so/ZBDDDG.h +105 -0
  19. data/ext/zdd_so/ZBDDHASH.cc +91 -0
  20. data/ext/zdd_so/bddc.c +2816 -0
  21. data/ext/zdd_so/bddc.h +132 -0
  22. data/ext/zdd_so/extconf.rb +25 -0
  23. data/ext/zdd_so/include/aheap.c +211 -0
  24. data/ext/zdd_so/include/aheap.h +111 -0
  25. data/ext/zdd_so/include/base.c +93 -0
  26. data/ext/zdd_so/include/base.h +60 -0
  27. data/ext/zdd_so/include/itemset.c +473 -0
  28. data/ext/zdd_so/include/itemset.h +153 -0
  29. data/ext/zdd_so/include/problem.c +371 -0
  30. data/ext/zdd_so/include/problem.h +160 -0
  31. data/ext/zdd_so/include/queue.c +518 -0
  32. data/ext/zdd_so/include/queue.h +177 -0
  33. data/ext/zdd_so/include/sgraph.c +331 -0
  34. data/ext/zdd_so/include/sgraph.h +170 -0
  35. data/ext/zdd_so/include/stdlib2.c +832 -0
  36. data/ext/zdd_so/include/stdlib2.h +746 -0
  37. data/ext/zdd_so/include/trsact.c +723 -0
  38. data/ext/zdd_so/include/trsact.h +167 -0
  39. data/ext/zdd_so/include/vec.c +583 -0
  40. data/ext/zdd_so/include/vec.h +159 -0
  41. data/ext/zdd_so/lcm-vsop.cc +596 -0
  42. data/ext/zdd_so/print.cc +683 -0
  43. data/ext/zdd_so/table.cc +330 -0
  44. data/ext/zdd_so/vsop.h +88 -0
  45. data/ext/zdd_so/zdd_so.cpp +3277 -0
  46. data/lib/nysol/zdd.rb +31 -0
  47. 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