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,177 @@
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_h_
14
+ #define _queue_h_
15
+
16
+ #include"stdlib2.h"
17
+
18
+ #ifndef QUEUE_INT
19
+ #ifdef QUEUE_INT_LONG
20
+ #define QUEUE_INT LONG // define the type before if change is needed
21
+ #define QUEUE_INTHUGE LONGHUGE // comment out if QUEUE_INT is "short"
22
+ #define QUEUE_INTF "%lld"
23
+ #else
24
+ #define QUEUE_INT int // define the type before if change is needed
25
+ #define QUEUE_INTHUGE INTHUGE // comment out if QUEUE_INT is "short"
26
+ #define QUEUE_INTF "%d"
27
+ #endif
28
+ #endif
29
+
30
+ #ifndef QUEUE_ID
31
+ #ifdef QUEUE_ID_LONG
32
+ #define QUEUE_ID LONG // define the type before if change is needed
33
+ #define QUEUE_IDHUGE LONGHUGE // comment out if QUEUE_INT is "short"
34
+ #define QUEUE_IDF "%lld"
35
+ #else
36
+ #define QUEUE_ID int // define the type before if change is needed
37
+ #define QUEUE_IDHUGE INTHUGE // comment out if QUEUE_INT is "short"
38
+ #define QUEUE_IDF "%d"
39
+ #endif
40
+ #endif
41
+ #define SWAP_QUEUE_INT(a,b) (common_QUEUE_INT=a,a=b,b=common_QUEUE_INT)
42
+ #define SWAP_QUEUE_ID(a,b) (common_QUEUE_ID=a,a=b,b=common_QUEUE_ID)
43
+
44
+ typedef struct {
45
+ unsigned char type; // type of the structure
46
+ QUEUE_INT *v; // pointer to the array
47
+ QUEUE_ID end; // the length of the array
48
+ QUEUE_ID t; // end position+1
49
+ QUEUE_ID s; // start position
50
+ } QUEUE;
51
+
52
+ /* QUEUE stores at most end-1 elements. Overflow occurs after inserting end-1 elements */
53
+
54
+ #define QUEUE_INCREMENT(Q,i) ((i)=((i)>=(Q).end-1)?0:(i)+1)
55
+ #define QUEUE_DECREMENT(Q,i) ((i)=(i)==0?(Q).end-1:(i)-1)
56
+ #define QUEUE_LENGTH(Q) (((Q).t-(Q).s+(Q).end)%(Q).end)
57
+ #define QUEUE_LENGTH_(Q) ((Q).t-(Q).s)
58
+
59
+ /* macro for loop w.r.t., QUEUE */
60
+ #define QUEUE_F_LOOP(Q,i) for((i)=(Q).s;(i)!=(Q).t;((i)=((i)>=(Q).end-1)?0:(i)+1))
61
+ #define QUEUE_F_LOOP_(Q,i) for((i)=(Q).s;(i)<(Q).t;(i)++)
62
+ #define QUEUE_FE_LOOP(Q,i,x) for((i)=(Q).s,x=(Q).v[i];(i)!=(Q).t;((i)=((i)>=(Q).end-1)?0:(i)+1),x=(Q).v[i])
63
+ #define QUEUE_FE_LOOP_(Q,i,x) for((i)=(Q).s,x=(Q).v[i];(i)<(Q).t;(i)++,x=(Q).v[i])
64
+ #define QUEUE_B_LOOP(Q,i) for((i)=(Q).t==0?(Q).end-1:(Q).t-1;(i)!=(Q).s;(i)=(i)==0?(Q).end-1:(i)-1)
65
+ #define QUEUE_B_LOOP_(Q,i) for((i)=(Q).t-1;(i)>=(Q).s;(i)--)
66
+ #define QUEUE_BE_LOOP(Q,i,x) for((i)=(Q).t==0?(Q).end-1:(Q).t-1,x=(Q).v[i];(i)!=(Q).s;(i)=(i)==0?(Q).end-1:(i)-1,x=(Q).v[i])
67
+ #define QUEUE_BE_LOOP_(Q,i,x) for((i)=(Q).t-1;((i)>=(Q).s)?((x=(Q).v[i])||1):0;(i)--)
68
+
69
+ #define QUEUE_RMALL(Q) ((Q).t=(Q).s)
70
+ #define QUEUE_RMALL_(Q) ((Q).t=0)
71
+ #define QUEUE_HEAD(Q) ((Q).v[(Q).s])
72
+ #define QUEUE_TAIL_(Q) ((Q).v[(Q).t-1])
73
+
74
+ extern QUEUE INIT_QUEUE;
75
+ extern QUEUE_INT common_QUEUE_INT, *common_QUEUE_INTp;
76
+ QSORT_TYPE_HEADER(QUEUE_INT, QUEUE_INT)
77
+ QSORT_TYPE_HEADER(QUEUE_ID, QUEUE_ID)
78
+
79
+
80
+ /* initialization, not fill the memory by 0 */
81
+ void QUEUE_alloc (QUEUE *Q, QUEUE_ID siz);
82
+
83
+ /* termination processing */
84
+ void QUEUE_end (QUEUE *Q);
85
+
86
+ /* delivery: transpose that matrinx (transaction database) Q. Each row of the
87
+ transposed matrix is called occurrence.
88
+
89
+ variables to be set.
90
+ OQ:array for occurrences, c: for counting frequency, jump: list of items with non-empty OQ
91
+ if c!=NULL, count the frequency and set to c, and set occurrences to OQ, otherwise.
92
+ if jump==NULL, then the list of non-empty item will not be generated
93
+ Q:matrix, of an array of QUEUE, occ: list of rows of Q to be scaned, t; maximum ID of the
94
+ row to be scaned; if occ==NULL, occ will be ignored, otherwise t will be ignored.
95
+ M: end mark of each QUEUE. */
96
+ void QUEUE_delivery(QUEUE *OQ, VEC_ID *c, QUEUE *jump, QUEUE *Q, QUEUE *occ, VEC_ID t, QUEUE_INT M);
97
+ /* sort a QUEUE with WEIGHT, with already allocated memory (size have to no less than the size of QUEUE) */
98
+ void QUEUE_perm_WEIGHT (QUEUE *Q, WEIGHT *w, PERM *invperm, int flag);
99
+
100
+ /* remove (or unify) the consecutive same ID's in a QUEUE (duplication delete, if sorted) */
101
+ void QUEUE_rm_dup_WEIGHT (QUEUE *Q, WEIGHT *w);
102
+
103
+ /***********************************************************************/
104
+ /* duplicate occ's in jump, ( copy occ's to allocated QUEUE array) */
105
+ /* Q[i].end := original item, clear each original occ */
106
+ /* buffer size is multiplied by u */
107
+ /*******************************************************/
108
+
109
+
110
+ void QUEUE_occ_dup (QUEUE *jump, QUEUE **QQ, QUEUE *Q, WEIGHT **ww, WEIGHT *w, WEIGHT **ppw, WEIGHT *pw, int u);
111
+
112
+ /* return the position of the first element having value e. return -1 if no such element exists */
113
+ LONG QUEUE_ele (QUEUE *Q, QUEUE_INT e);
114
+
115
+ /* insert an element to the tail/head */
116
+ void QUEUE_ins_ (QUEUE *Q, QUEUE_INT e);
117
+ void QUEUE_ins (QUEUE *Q, QUEUE_INT e);
118
+ void QUEUE_ins_head_ (QUEUE *Q, QUEUE_INT e);
119
+ void QUEUE_ins_head (QUEUE *Q, QUEUE_INT e);
120
+
121
+ /* extract an element from the head/tail, without checking the underflow */
122
+ QUEUE_INT QUEUE_ext_ (QUEUE *Q);
123
+ QUEUE_INT QUEUE_ext (QUEUE *Q);
124
+ QUEUE_INT QUEUE_ext_tail_ (QUEUE *Q);
125
+ QUEUE_INT QUEUE_ext_tail (QUEUE *Q);
126
+
127
+ /* remove the j-th element and replace it by the tail/head or shift */
128
+ void QUEUE_rm_ (QUEUE *Q, QUEUE_ID j);
129
+ void QUEUE_rm (QUEUE *Q, QUEUE_ID j);
130
+ void QUEUE_rm_head_ (QUEUE *Q, QUEUE_ID j);
131
+ void QUEUE_rm_head (QUEUE *Q, QUEUE_ID j);
132
+ int QUEUE_rm_ele_ (QUEUE *Q, QUEUE_INT e);
133
+
134
+ /* Append Q2 to the tail of Q1. Q2 will (not) be deleted */
135
+ void QUEUE_append_ (QUEUE *Q1, QUEUE *Q2);
136
+ void QUEUE_append (QUEUE *Q1, QUEUE *Q2);
137
+ void QUEUE_concat_ (QUEUE *Q1, QUEUE *Q2);
138
+ void QUEUE_concat (QUEUE *Q1, QUEUE *Q2);
139
+
140
+ /* Append from j to jj th elements to the tail of Q1. Q2 will not be deleted */
141
+ void QUEUE_subconcat_ (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj);
142
+ void QUEUE_subconcat (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj);
143
+
144
+ /* initialize Q1 by length of Q2, and copy Q2 to Q1 */
145
+ void QUEUE_store_ (QUEUE *Q1, QUEUE *Q2);
146
+ void QUEUE_store (QUEUE *Q1, QUEUE *Q2);
147
+ /* copy Q2 to Q1 and delete Q2 */
148
+ void QUEUE_restore_ (QUEUE *Q1, QUEUE *Q2);
149
+ void QUEUE_restore (QUEUE *Q1, QUEUE *Q2);
150
+
151
+ /* copy Q2 to Q1 */
152
+ void QUEUE_cpy_ (QUEUE *Q1, QUEUE *Q2);
153
+ void QUEUE_cpy (QUEUE *Q1, QUEUE *Q2);
154
+ QUEUE QUEUE_dup_ (QUEUE *Q);
155
+ /* copy l elements of Q2 starting from s2 to the s1th position of Q1.
156
+ size of Q1 is not increasing */
157
+ void QUEUE_subcpy_ (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l);
158
+ void QUEUE_subcpy (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l);
159
+
160
+ /* merge/minum/intersection of Q1 and Q2, and set Q1 to it.
161
+ Both Q1 and Q2 have to be sorted in increasing order */
162
+ void QUEUE_merge_ (QUEUE *Q1, QUEUE *Q2);
163
+ void QUEUE_merge (QUEUE *Q1, QUEUE *Q2);
164
+ void QUEUE_minus_ (QUEUE *Q1, QUEUE *Q2);
165
+ void QUEUE_minus (QUEUE *Q1, QUEUE *Q2);
166
+ void QUEUE_and_ (QUEUE *Q1, QUEUE *Q2);
167
+ void QUEUE_and (QUEUE *Q1, QUEUE *Q2);
168
+
169
+ /* insertion sort */
170
+ void QUEUE_sort (QUEUE *Q);
171
+
172
+ /* print */
173
+ void QUEUE_print (QUEUE *Q);
174
+ void QUEUE_print_ (QUEUE *Q);
175
+
176
+
177
+ #endif
@@ -0,0 +1,331 @@
1
+ /* graph library by array list
2
+ 12/Feb/2002 by Takeaki Uno
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 _sgraph_c_
14
+ #define _sgraph_c_
15
+
16
+ #include"sgraph.h"
17
+ #include"vec.c"
18
+
19
+ SGRAPH INIT_SGRAPH = {TYPE_SGRAPH,INIT_SETFAMILY_,INIT_SETFAMILY_,INIT_SETFAMILY_,0,0,NULL,NULL};
20
+
21
+ /* initialization */
22
+ void SGRAPH_alloc (SGRAPH *G, QUEUE_ID nodes, size_t edge_num, size_t arc_num){
23
+ if ( edge_num > 0 ){
24
+ SETFAMILY_alloc (&G->edge, nodes, NULL, nodes, edge_num);
25
+ if ( G->flag&LOAD_EDGEW && (!ERROR_MES) ) SETFAMILY_alloc_weight (&G->edge);
26
+ }
27
+ if ( arc_num > 0 ){
28
+ SETFAMILY_alloc (&G->in, nodes, NULL, nodes, arc_num);
29
+ SETFAMILY_alloc (&G->out, nodes, NULL, nodes, arc_num);
30
+ if ( G->flag&LOAD_EDGEW && (!ERROR_MES) ){
31
+ SETFAMILY_alloc_weight (&G->in);
32
+ SETFAMILY_alloc_weight (&G->out);
33
+ }
34
+ }
35
+ if (G->flag&LOAD_NODEW) calloc2 (G->node_w, nodes, "SGRAPH_alloc: node_w", G->node_w=0);
36
+ if ( ERROR_MES ){ SGRAPH_end (G); EXIT; }
37
+ }
38
+
39
+ /* copy graph G to graph G2. Underconstruction */
40
+ //void SGRAPH_cpy (SGRAPH *G2, SGRAPH *G){}
41
+
42
+ /* free graph object */
43
+ void SGRAPH_end (SGRAPH *G){
44
+ SETFAMILY_end (&G->edge);
45
+ SETFAMILY_end (&G->in);
46
+ SETFAMILY_end (&G->out);
47
+ mfree (G->wbuf, G->perm);
48
+ *G = INIT_SGRAPH;
49
+ }
50
+
51
+
52
+ /* make an edge between u and v.
53
+ If they are already connected, it will be a multiple edge */
54
+ void SGRAPH_edge_mk (SGRAPH *G, QUEUE_INT u, QUEUE_INT v, WEIGHT w){
55
+ if ( G->edge.w ){
56
+ G->edge.w[u][G->edge.v[u].t] = w;
57
+ G->edge.w[v][G->edge.v[v].t] = w;
58
+ }
59
+ ARY_INS (G->edge.v[u], v);
60
+ ARY_INS (G->edge.v[v], u);
61
+ G->edge.eles += 2;
62
+ }
63
+
64
+ /* make an arc between u and v.
65
+ If they are already connected, it will be a multiple arc */
66
+ void SGRAPH_arc_mk (SGRAPH *G, QUEUE_INT u, QUEUE_INT v, WEIGHT w){
67
+ if ( G->out.w ) G->out.w[u][G->out.v[u].t] = w;
68
+ if ( G->in.w ) G->in.w[v][G->in.v[v].t] = w;
69
+ ARY_INS (G->out.v[u], v);
70
+ ARY_INS (G->in.v[v], u);
71
+ G->in.eles++;
72
+ G->out.eles++;
73
+ }
74
+
75
+ /* Delete the edge connecting u and v. If edge (u,v) does not exist, nothing will occur. */
76
+ void SGRAPH_edge_rm_iter (SETFAMILY *M, QUEUE_INT u, QUEUE_INT v){
77
+ QUEUE_INT i;
78
+ if ( (i = (QUEUE_INT)QUEUE_ele (&M->v[u], v)) >= 0 ){
79
+ QUEUE_rm (&M->v[u], i);
80
+ if ( M->w ) M->w[u][i] = M->w[u][M->v[u].t];
81
+ M->eles--;
82
+ }
83
+ }
84
+
85
+ /* Delete the edge connecting u and v. If edge (u,v) does not exist, nothing will occur. */
86
+ void SGRAPH_edge_rm (SGRAPH *G, QUEUE_INT u, QUEUE_INT v){
87
+ SGRAPH_edge_rm_iter (&G->edge, u, v);
88
+ SGRAPH_edge_rm_iter (&G->edge, v, u);
89
+ }
90
+
91
+ /* Delete the arc connecting u and v. If arc (u,v) does not exist, nothing will occur. */
92
+ void SGRAPH_arc_rm (SGRAPH *G, QUEUE_INT u, QUEUE_INT v){
93
+ SGRAPH_edge_rm_iter (&G->out, u, v);
94
+ SGRAPH_edge_rm_iter (&G->in, v, u);
95
+ }
96
+
97
+ /* print graph by numbers */
98
+ void SGRAPH_print (SGRAPH *G){
99
+ VEC_ID i;
100
+ QUEUE_ID j;
101
+ QUEUE_INT e;
102
+
103
+ printf ("#node "VEC_IDF" ,#edge %zd ,#arc %zd\n", SGRAPH_NODE_NUM(*G), G->edge.eles, G->in.eles);
104
+ FLOOP (i, 0, SGRAPH_NODE_NUM(*G)){
105
+ printf ("NODE "VEC_IDF" ", i);
106
+ if ( G->node_w ){ putchar ('('); print_WEIGHT (G->node_w[i]); putchar (')'); }
107
+ printf (" >>\n");
108
+ if ( G->edge.v && G->edge.v[i].t ){
109
+ printf (" edge : ");
110
+ ARY_FLOOP (G->edge.v[i], j, e){
111
+ printf (VEC_IDF, e);
112
+ if ( G->edge.w ){ putchar ('('); print_WEIGHT (G->edge.w[i][j]); putchar (')'); }
113
+ putchar (',');
114
+ }
115
+ putchar ('\n');
116
+ }
117
+ if ( G->in.w ){
118
+ if ( G->in.v[i].t ){
119
+ printf (" in-arc : ");
120
+ ARY_FLOOP (G->in.v[i], j, e){
121
+ printf (VEC_IDF, e);
122
+ if ( G->in.w ){ putchar ('('); print_WEIGHT (G->in.w[i][j]); putchar (')'); }
123
+ putchar (',');
124
+ }
125
+ putchar ('\n');
126
+ }
127
+ }
128
+ if ( G->out.w ){
129
+ if ( G->out.v[i].t ){
130
+ printf (" out-arc : ");
131
+ ARY_FLOOP (G->out.v[i], j, e){
132
+ printf (VEC_IDF, e);
133
+ if ( G->out.w ){ putchar ('('); print_WEIGHT (G->out.w[i][j]); putchar (')');}
134
+ putchar (',');
135
+ }
136
+ putchar ('\n');
137
+ }
138
+ }
139
+ }
140
+ }
141
+
142
+ /* Output a graph to file
143
+ Vertices, edges, arcs less than node_num, edge_num, arc_num are written to the file. Input parameters are
144
+ (graph) (file name) (flag)
145
+ SGRAPH_READ_NODEW 512 // read node weight
146
+ SGRAPH_READ_EDGEW 1024 // read edge weight
147
+ */
148
+ /*
149
+ format of file:(including notifications to make input file)
150
+
151
+ the ith row corresponds to node i-1, and
152
+ ID list of nodes adjacent to i, and having ID > i, for undirected graph
153
+ ID list of nodes adjacent to i by out-going arc of i, for directed graph
154
+ Separator is ",", but graph load routine accepts any letter for
155
+ separator but not a number.
156
+ If the graph has both edges and arcs, write them in two lines separately,
157
+ so a node then uses two lines, and #nodes = #lines/2.
158
+
159
+ == Notifications to make input file ==
160
+ Notice that if 0th line has node 2, and the 2nd line has 0, then there
161
+ will be multiple edge (0,2) and (2,0).
162
+ The read routine does not make error with multiple edges, it is allowed.
163
+
164
+ The ID of nodes begin from 0. After reading graph, node_num is set to
165
+ node_end.
166
+
167
+ Input file example, without weights, E={(0,1),(0,2),(1,1),(1,3),(2,3)}
168
+ ===========
169
+ 1,2
170
+ 1 3
171
+ 3
172
+
173
+ [EOF]
174
+ =========
175
+ Nodes are 0,1, and 2, both edges and arcs exist, with node/edge/arc weights)
176
+ 5000,1,30
177
+ 0,50,1,20,
178
+ 100,1,3
179
+ 2,20
180
+ 200
181
+
182
+ [EOF]
183
+ =======
184
+ where node weights are 5000, 100, 200, and edges and their weights are
185
+ (0,1),30, (1,1),3
186
+ arcs and their weights are (0,0),50, (0,1), 20, (1,2), 20
187
+
188
+ In the case of bipartite graph, write the adjacent-node lists only for
189
+ the node in node set one.
190
+
191
+
192
+ */
193
+
194
+ /* graph load routine. Allocate memory as much as the size of input file.
195
+ parameters are,
196
+ (graph) (file name)
197
+ LOAD_EDGE // read undirected edge from file
198
+ LOAD_ARC // read directed arc from file
199
+ LOAD_BIPARTITE // load bipartite graph
200
+ LOAD_NODEW // read node weight
201
+ LOAD_EDGEW // read edge weight
202
+ */
203
+ /* In the bipartite case, even if the IDs of node set 2 begin from 0, i.e.,
204
+ overlaps with node 1, the routine automatically correct them. */
205
+ /* Directed bipartite graph, all arcs are considered to be from node set 1
206
+ to node set 2. If both directions exist, read as a general graph, and set
207
+ node1_num later in some way. */
208
+ /* The routine compares the maximum node index and #lines, and set #node
209
+ to the larger one. However, if node weight exists, weights will be included
210
+ in the candidates of maximum index, thus in this case we fix #node := #lines.
211
+ In the case of bipartite graph, the routine compares, but the weights of
212
+ non-existing lines will be -1. */
213
+
214
+ /* make the opposite direction edge, for each edge; buffers have to be already doubly allocated */
215
+ void SGRAPH_load_delivery (SGRAPH *G, SETFAMILY *OO, SETFAMILY *MM, QUEUE_ID *c){
216
+ VEC_ID i;
217
+ QUEUE_ID j;
218
+ QUEUE_INT e;
219
+ FLOOP (i, 0, MM->t) c[i] = MM->v[i].t;
220
+ FLOOP (i, 0, MM->t){
221
+ FLOOP (j, 0, c[i]){
222
+ e = MM->v[i].v[j];
223
+ if ( OO->w ) OO->w[e][OO->v[e].t] = MM->w[i][j];
224
+ ARY_INS (OO->v[e], i);
225
+ }
226
+ }
227
+ }
228
+
229
+ /* make the opposite direction edge, for each edge; buffers have to be already doubly allocated */
230
+ void SGRAPH_mk_opposite_edge (SGRAPH *G, QUEUE_ID *c){
231
+ VEC_ID i;
232
+ size_t j, jj;
233
+ j = G->edge.eles; // shift the arrays to insert edges of opposite directions
234
+ BLOOP (i, G->edge.t, 0){
235
+ j -= G->edge.v[i].t+c[i];
236
+ jj = G->edge.v[i].t+1;
237
+ do {
238
+ jj--;
239
+ G->edge.buf[j+i+jj] = G->edge.v[i].v[jj];
240
+ } while ( jj>0 );
241
+ G->edge.v[i].end += c[i];
242
+ G->edge.v[i].v = &G->edge.buf[j+i];
243
+ if ( G->edge.w ){
244
+ memcpy ( &G->edge.buf[j], G->edge.w[i], sizeof(WEIGHT)*G->edge.v[i].t );
245
+ G->edge.w[i] = &G->edge.wbuf[j];
246
+ }
247
+ }
248
+ }
249
+
250
+ /* load edges/arcs (determined by G->flag) from file */
251
+ void SGRAPH_load (SGRAPH *G, char *fname, char *wfname){
252
+ VEC_ID i;
253
+ QUEUE_ID *c;
254
+ SETFAMILY *F1, *F2;
255
+
256
+ if ( G->flag&LOAD_EDGE ){ F1 = F2 = &G->edge; G->edge.flag |= LOAD_DBLBUF; }
257
+ else { F1 = &G->in; F2 = &G->out; }
258
+ SETFAMILY_load (F1, fname, wfname);
259
+ // adjact so that #rows and #colums are the same
260
+ if ( !(G->flag&LOAD_BIPARTITE)){
261
+ if ( F1->clms < F1->t ){
262
+ F1->clms = F1->t;
263
+ FLOOP (i, 0, F1->t) F1->v[i].v[F1->v[i].t] = F1->t; // re-set endmark
264
+ } else if ( F1->clms > F1->t ){
265
+ reallocx_ (F1->v, F1->t, F1->clms, INIT_QUEUE, "SGRAPH_load: v", EXIT);
266
+ FLOOP (i, F1->t, F1->clms){
267
+ F1->v[i].v = F1->v[F1->t -1].v +F1->v[F1->t -1].t +1 +(i -(F1->t-1));
268
+ F1->v[i].v[0] = F1->clms;
269
+ } // re-set endmark
270
+ F1->t = F1->clms;
271
+ }
272
+ }
273
+
274
+ calloc2 (c, F1->t, "SGRAPH_load: c", EXIT);
275
+ QUEUE_delivery (NULL, c, NULL, F1->v, NULL, F1->t, F1->t);
276
+ // SETFAMILY_print (stdout, F1);
277
+
278
+ if ( F1 != F2 ) SETFAMILY_alloc (F2, F1->t, c, F1->t, 0);
279
+ else {
280
+ G->edge.eles *= 2; G->edge.ele_end *= 2;
281
+ SGRAPH_mk_opposite_edge (G, c); // shift the arrays to insert edges of opposite directions
282
+ }
283
+
284
+ SGRAPH_load_delivery (G, F2, F1, c);
285
+ free (c);
286
+ F2->clms = F2->t; FLOOP (i, 0, F2->t) F2->v[i].v[F2->v[i].t] = F2->t; // re-set endmark
287
+
288
+ F1->flag |= G->flag; SETFAMILY_sort (F1);
289
+ if ( F1 != F2 ){ F2->flag |= G->flag; SETFAMILY_sort (F2); }
290
+ }
291
+
292
+ /* replace node i by perm[i] */
293
+ void SGRAPH_replace_index (SGRAPH *G, PERM *perm, PERM *invperm){
294
+ QUEUE_INT *x;
295
+ VEC_ID i;
296
+ QUEUE Q;
297
+ WEIGHT *w, ww;
298
+
299
+ FLOOP (i, 0, G->edge.t)
300
+ if ( G->edge.v ){
301
+ MQUE_FLOOP (G->edge.v[i], x) *x = perm[*x];
302
+ ARY_INVPERMUTE (G->edge.v, invperm, Q, G->edge.t, "SGRAPH_repl_ind:", EXIT);
303
+ }
304
+ if ( G->in.v ){
305
+ MQUE_FLOOP (G->in.v[i], x) *x = perm[*x];
306
+ ARY_INVPERMUTE (G->in.v, invperm, Q, G->edge.t, "SGRAPH_repl_ind:", EXIT);
307
+ }
308
+ if ( G->out.v ){
309
+ MQUE_FLOOP (G->out.v[i], x) *x = perm[*x];
310
+ ARY_INVPERMUTE (G->out.v, invperm, Q, G->edge.t, "SGRAPH_repl_ind:", EXIT);
311
+ }
312
+ if ( G->edge.w ) ARY_INVPERMUTE (G->edge.w, invperm, w, G->edge.t, "SGRAPH_repl_ind:", EXIT);
313
+ if ( G->in.w ) ARY_INVPERMUTE (G->in.w, invperm, w, G->edge.t, "SGRAPH_repl_ind:", EXIT);
314
+ if ( G->out.w ) ARY_INVPERMUTE (G->out.w, invperm, w, G->edge.t, "SGRAPH_repl_ind:", EXIT);
315
+ if ( G->node_w ) ARY_INVPERMUTE (G->node_w, invperm, ww, G->edge.t, "SGRAPH_repl_ind:", EXIT);
316
+ G->perm = perm;
317
+ }
318
+
319
+ /* sort the nodes by Q->t, increasing if flag=1, decreasing if flag=-1 */
320
+ void SGRAPH_perm_node (SGRAPH *G, PERM *tmp){
321
+ VEC_ID c1=0, c2=G->node1_num, i;
322
+ PERM *perm;
323
+ malloc2 (perm, G->edge.t, "SGRAPH_perm_node", {free(tmp);EXIT;});
324
+ FLOOP (i, 0, G->edge.t)
325
+ if ( tmp[i]<G->node1_num ) perm[tmp[i]] = c1++; else perm[tmp[i]] = c2++;
326
+ ARY_INV_PERM_ (tmp, perm, G->edge.t);
327
+ SGRAPH_replace_index (G, perm, tmp);
328
+ free2 (tmp);
329
+ }
330
+
331
+ #endif