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
@@ -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
|