nysol-zdd 3.0.2

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