Orbiter 2022
Combinatorial Objects
tdo_data.cpp
Go to the documentation of this file.
1// tdo_data.cpp
2// Anton Betten
3//
4// started: January 30, 2007
5
6#include "foundations.h"
7
8
9using namespace std;
10
11
12namespace orbiter {
13namespace layer1_foundations {
14namespace combinatorics {
15
16
18{
19 types_first = NULL;
20 types_len = NULL;
21 only_one_type = NULL;
23 multiple_types = NULL;
25 types_first2 = NULL;
26 D1 = NULL;
27 D2 = NULL;
28}
29
31{
32 free();
33}
34
36{
37 int verbose_level = 0;
38 int f_v = (verbose_level >= 1);
39
40 if (f_v) {
41 cout << "tdo_data::free" << endl;
42 }
43 if (types_first) {
45 types_first = NULL;
46 }
47 if (types_len) {
49 types_len = NULL;
50 }
51 if (only_one_type) {
53 only_one_type = NULL;
54 }
55 if (multiple_types) {
57 multiple_types = NULL;
58 }
59 if (types_first2) {
61 types_first2 = NULL;
62 }
63 if (f_v) {
64 cout << "tdo_data::free before D1" << endl;
65 }
66 if (D1) {
68 D1 = NULL;
69 }
70 if (f_v) {
71 cout << "tdo_data::free before D2" << endl;
72 }
73 if (D2) {
75 D2 = NULL;
76 }
77 if (f_v) {
78 cout << "tdo_data::free done" << endl;
79 }
80}
81
83{
84 types_first = NEW_int(R + 1);
85 types_len = NEW_int(R);
91}
92
93int tdo_data::solve_first_system(int verbose_level,
94 int *&line_types, int &nb_line_types, int &line_types_allocated)
95{
96 int f_v = (verbose_level >= 1);
97 int f_vv = (verbose_level >= 2);
98 int f_vvv = (verbose_level >= 3);
99 int i, nb_sol, nb_vars;
100
101 if (f_v) {
102 cout << "tdo_data::solve_first_system D1->n=" << D1->n << endl;
103 }
104 nb_vars = D1->n;
105 nb_sol = 0;
106 if (D1->solve_first(0/*verbose_level - 4*/)) {
107
108 while (TRUE) {
109 if (nb_line_types >= line_types_allocated) {
110 int new_nb_line_types = line_types_allocated + 100;
111 if (f_v) {
112 cout << "tdo_data::solve_first_system reallocating to " << new_nb_line_types << endl;
113 }
114 int *new_line_types = NEW_int(new_nb_line_types * nb_vars);
115 for (i = 0; i < nb_line_types * nb_vars; i++) {
116 new_line_types[i] = line_types[i];
117 }
118 FREE_int(line_types);
119 line_types = new_line_types;
120 line_types_allocated = new_nb_line_types;
121 }
122
123 if (f_vvv) {
124 cout << nb_sol << " : ";
125 for (i = 0; i < nb_vars; i++) {
126 cout << " " << D1->x[i];
127 }
128 cout << endl;
129 }
130 for (i = 0; i < nb_vars; i++) {
131 line_types[nb_line_types * nb_vars + i] = D1->x[i];
132 }
133 nb_line_types++;
134 nb_sol++;
135 if (!D1->solve_next()) {
136 break;
137 }
138 }
139 }
140 if (f_vv) {
141 cout << "tdo_data::solve_first_system: found " << nb_sol
142 << " refined types" << endl;
143 }
144 if (f_v) {
145 cout << "tdo_data::solve_first_system done" << endl;
146 }
147 return nb_sol;
148}
149
151 int *classes_len,
152 int *&line_types, int &nb_line_types,
153 int *&distributions, int &nb_distributions,
154 int omit)
155{
156 int f_v = (verbose_level >= 1);
157 int f_vv = (verbose_level >= 2);
158 int nb_sol;
159
160 if (f_v) {
161 cout << "tdo_data::solve_second_system_omit omit=" << omit << endl;
162 }
163 int s, i, r = 0, f, l, h, j, u, first, len, N, a, ii, f_bad;
164
165 f = types_first2[0];
166 l = 0;
167 s = 0;
168 for (i = 0; i < nb_multiple_types - omit; i++) {
169 r = multiple_types[i];
170 l += types_len[r];
171 s += classes_len[r];
172 }
174 int nb_eqns_replaced;
175 int *eqns_replaced;
176 int *eqn_number;
177
178 if (f_v) {
179 cout << r << " : " << setw(3) << classes_len[r] << " : "
180 << setw(3) << f << " : " << setw(3) << l << endl;
181 cout << "nb_multiple_types=" << nb_multiple_types << endl;
182 cout << "omit=" << omit << endl;
183 cout << "calling D2->project f=" << f << " l=" << l << endl;
184 }
185 D2->project(&D, f, l, eqn_number, nb_eqns_replaced,
186 eqns_replaced, verbose_level - 1);
187 D.f_has_sum = TRUE;
188 D.sum = s;
189 if (f_vv) {
190 cout << "after projection:" << endl;
191 D.print();
192 D.write_xml(cout, "projected");
193 }
194 D.nb_steps_betten = 0;
195 //nb_sol = D.solve_once_mckay(verbose_level);
196 //nb_sol = D.solve_all_mckay(verbose_level);
197 nb_sol = D.solve_all_betten(0 /*verbose_level*/);
198 if (f_v) {
199 cout << "number of solutions = " << nb_sol << " in "
200 << D.nb_steps_betten << " steps" << endl;
201 }
202 nb_distributions = 0;
203 distributions = NEW_int(nb_sol * nb_line_types);
204
205
206 for (N = 0; N < nb_sol; N++) {
207
208 if (f_v) {
209 cout << "tdo_data::solve_second_system_omit "
210 "N=" << N << " / " << nb_sol << endl;
211 }
212 f_bad = FALSE;
213 for (j = 0; j < nb_line_types; j++) {
214 distributions[nb_distributions * nb_line_types + j] = 0;
215 }
216 for (j = 0; j < D.n; j++) {
217 D.x[j] = D._results.front()[j];
218 }
219 if (f_v) {
220 cout << "solution " << N << ":" << endl;
221 for (j = 0; j < D.n; j++) {
222 cout << setw(3) << D.x[j] << " ";
223 }
224 cout << endl;
225 }
226 D._results.pop_front();
228 for (i = 0; i < D2->m; i++) {
229 D2->RHS1[i] = 0;
230 }
231 for (i = 0; i < D.m; i++) {
232 a = D.RHS1[i];
233 ii = eqn_number[i];
234 D2->RHS1[ii] = a;
235 }
236 if (f_vv) {
237 cout << "RHS1" << endl;
238 for (i = 0; i < D.m; i++) {
239 cout << "equation ";
240 if (D.eqn_label[i])
241 cout << D.eqn_label[i];
242 cout << " : " << D.RHS1[i] << endl;
243 }
244 }
245
247 int nb_eqns_replaced2;
248 int *eqns_replaced2;
249 int *eqn_number2;
250 int F, L, nb_sol2;
251 F = l;
252 L = 0;
253 s = 0;
254 for (i = nb_multiple_types - omit;
255 i < nb_multiple_types; i++) {
256 r = multiple_types[i];
257 L += types_len[r];
258 s += classes_len[r];
259 }
260 if (f_v) {
261 cout << "tdo_data::solve_second_system_omit "
262 "N=" << N << " / " << nb_sol << endl;
263 cout << "calling D2->project F=" << F << " L=" << L << endl;
264 }
265 D2->project(&DD, F, L, eqn_number2,
266 nb_eqns_replaced2, eqns_replaced2,
267 verbose_level - 1);
268 DD.f_has_sum = TRUE;
269 DD.sum = s;
270 for (i = 0; i < DD.m; i++) {
271 ii = eqn_number2[i];
272 a = D2->RHS1[ii];
273 DD.RHS[i] -= a;
274 if (DD.RHS[i] < 0) {
275 f_bad = TRUE;
276 break;
277 }
278 }
279 if (f_vv) {
280 cout << "after projection:" << endl;
281 DD.print();
282 }
283 if (f_bad) {
284 cout << "solutions does not extend (bad RHS in eqn "
285 << i << "), skipping" << endl;
286 continue;
287 }
288
289 if (FALSE) {
290 // here we test if a givemn solution of the projected system
291 // extends to a global solution.
292 // Since out solver finds in fact all solutions, this test is
293 // too expensive, hence we do not do it any more.
294
295 long int nb_backtrack;
296 nb_sol2 = DD.solve_all_mckay(nb_backtrack, INT_MAX, 0/*verbose_level*/);
297 if (f_v) {
298 cout << "N=" << N << " / " << nb_sol
299 << " number of solutions = " << nb_sol2 << endl;
300 }
301 if (nb_sol2 == 0) {
302 cout << "solutions does not extend "
303 "(no solution), skipping" << endl;
304 continue;
305 }
306 }
307 FREE_int(eqns_replaced2);
308 FREE_int(eqn_number2);
309
310
311 for (h = 0; h < nb_only_one_type; h++) {
312 r = only_one_type[h];
313 u = types_first[r];
314 //cout << "only one type, r=" << r << " u=" << u << endl;
315 distributions[nb_distributions * nb_line_types + u] =
316 classes_len[r];
317 }
318 for (i = 0; i < nb_multiple_types - omit; i++) {
319 r = multiple_types[i];
320 F = types_first2[i];
321 first = types_first[r];
322 len = types_len[r];
323 //cout << "multiple types, r=" << r
324 //<< " first=" << first << endl;
325 for (j = 0; j < len; j++) {
326 a = D.x[F + j];
327 distributions[nb_distributions *
328 nb_line_types + first + j] = a;
329 }
330 }
331 nb_distributions++;
332 }
333 if (f_v) {
334 if (nb_distributions == 0) {
335 cout << "tdo_data::solve_second_system_omit "
336 "system has no solution" << endl;
337 }
338 else {
339 cout << "tdo_data::solve_second_system_omit "
340 "system has " << nb_distributions
341 << " solutions" << endl;
342 }
343 }
344
345 FREE_int(eqns_replaced);
346 FREE_int(eqn_number);
347
348#if 0
349 for (i = 0; i < nb_multiple_types; i++) {
350 diophant D;
351 int nb_eqns_replaced;
352 int *eqns_replaced;
353
354 r = multiple_types[i];
355 f = types_first2[i];
356 l = types_len[r];
357 if (f_v) {
358 cout << r << " : " << setw(3) << classes_len[r]
359 << " : " << setw(3) << f << " : "
360 << setw(3) << l << endl;
361 }
362 D2->project(&D, f, l, nb_eqns_replaced,
363 eqns_replaced, verbose_level);
364 D.f_has_sum = TRUE;
365 D.sum = classes_len[r];
366 D.print();
367 D.solve_first(verbose_level);
368 FREE_int(eqns_replaced);
369 }
370#endif
371}
372
374 int f_use_mckay_solver, int f_once,
375 int *classes_len, int f_scale, int scaling,
376 int *&line_types, int &nb_line_types,
377 int *&distributions, int &nb_distributions,
378 int cnt_second_system, solution_file_data *Sol)
379{
380 int i;
381
382 if (Sol) {
383 for (i = 0; i < Sol->nb_solution_files; i++) {
384 if (cnt_second_system == Sol->system_no[i]) {
385 cout << "reading solutions from file "
386 << Sol->solution_file[i] << endl;
388 verbose_level, classes_len,
389 f_scale, scaling, line_types, nb_line_types,
390 distributions, nb_distributions,
391 Sol->solution_file[i]);
392 return;
393 }
394 }
395 }
396 solve_second_system(verbose_level,
397 f_use_mckay_solver, f_once, classes_len,
398 f_scale, scaling, line_types, nb_line_types,
399 distributions, nb_distributions);
400}
401
403 int *classes_len, int f_scale, int scaling,
404 int *&line_types, int &nb_line_types,
405 int *&distributions, int &nb_distributions,
406 std::string &solution_file_name)
407{
408 int f_v = (verbose_level >= 1);
409 int cnt, i, j, a, nb_sol, *the_solution;
410 int h, r, u, f, l, first, distributions_allocated;
411 int Nb_vars; //, Nb_eqns;
412
413 //Nb_eqns = D2->m;
414 Nb_vars = D2->n;
415 the_solution = NEW_int(Nb_vars);
416 {
417 ifstream ff(solution_file_name);
418
419 for (i = 0; TRUE; i++) {
420 if (ff.eof()) {
421 break;
422 }
423 ff >> a;
424 if (a == -1) {
425 break;
426 }
427 for (j = 1; j < Nb_vars; j++) {
428 ff >> a;
429 }
430 }
431 }
432 nb_sol = i;
433
434 if (f_v) {
435 cout << "the solution file " << solution_file_name
436 << " contains " << nb_sol << " solutions" << endl;
437 }
438 distributions_allocated = nb_sol;
439 nb_distributions = 0;
440 distributions = NEW_int(distributions_allocated * nb_line_types);
441 {
442 ifstream ff(solution_file_name);
443 for (cnt = 0; cnt < nb_sol; cnt++) {
444 for (j = 0; j < Nb_vars; j++) {
445 ff >> the_solution[j];
446 }
447
448 for (h = 0; h < nb_only_one_type; h++) {
449 r = only_one_type[h];
450 u = types_first[r];
451 //cout << "only one type, r=" << r << " u=" << u << endl;
452 distributions[nb_distributions * nb_line_types + u] =
453 classes_len[r];
454 }
455 for (i = 0; i < nb_multiple_types; i++) {
456 r = multiple_types[i];
457 f = types_first2[i];
458 first = types_first[r];
459 l = types_len[r];
460 //cout << "multiple types, r=" << r
461 //<< " first=" << first << endl;
462 for (j = 0; j < l; j++) {
463 a = the_solution[f + j];
464 if (f_scale) {
465 a *= scaling;
466 }
467 distributions[nb_distributions * nb_line_types
468 + first + j] = a;
469 }
470 }
471 nb_distributions++;
472
473 }
474
475 }
476 FREE_int(the_solution);
477 if (f_v) {
478 cout << "solve_second_system_from_file: found "
479 << nb_distributions << " distributions." << endl;
480 }
481}
482
483void tdo_data::solve_second_system(int verbose_level,
484 int f_use_mckay_solver, int f_once,
485 int *classes_len,
486 int f_scale, int scaling,
487 int *&line_types, int &nb_line_types,
488 int *&distributions, int &nb_distributions)
489{
490 int f_v = (verbose_level >= 1);
491 int f_vv = (verbose_level >= 2);
492 int f_vvv = (verbose_level >= 3);
493 int distributions_allocated, nb_sol, a;
494 int h, r, u, i, f, l, j, first, ret;
495 int Nb_vars, /*Nb_eqns,*/ nb_steps = 0;
496
497 if (f_v) {
498 cout << "tdo_data::solve_second_system" << endl;
499 cout << "f_use_mckay_solver=" << f_use_mckay_solver << endl;
500 cout << "f_once=" << f_once << endl;
501 }
502 //Nb_eqns = D2->m;
503 Nb_vars = D2->n;
504
505 distributions_allocated = 100;
506 nb_distributions = 0;
507 distributions = NEW_int(distributions_allocated * nb_line_types);
508
509
510 nb_sol = 0;
511
512 if (f_use_mckay_solver) {
513 ret = D2->solve_first_mckay_once_option/*betten*/(
514 f_once, 0/*verbose_level - 4*/);
515 }
516 else {
517 ret = D2->solve_first_betten(0/*verbose_level - 4*/);
518 }
519 if (ret) {
520
521 nb_steps += D2->nb_steps_betten;
522 while (TRUE) {
523 if (nb_distributions && (nb_distributions % 1000) == 0) {
524 cout << "solve_second_system: " << nb_distributions
525 << " distributions" << endl;
526 }
527 if (nb_distributions >= distributions_allocated) {
528 int new_nb_distributions = distributions_allocated + 100;
529 if (f_vv) {
530 cout << "reallocating to " << new_nb_distributions << endl;
531 }
532
533 int *new_distributions = NEW_int(
534 new_nb_distributions * nb_line_types);
535 for (i = 0; i < nb_distributions * nb_line_types; i++) {
536 new_distributions[i] = distributions[i];
537 }
538 FREE_int(distributions);
539 distributions = new_distributions;
540 distributions_allocated = new_nb_distributions;
541 }
542 if (f_vvv) {
543 cout << nb_sol << " : ";
544 for (i = 0; i < Nb_vars; i++) {
545 cout << " " << setw(2) << D2->x[i];
546 }
547 cout << endl;
548 }
549
550
551 for (h = 0; h < nb_only_one_type; h++) {
552 r = only_one_type[h];
553 u = types_first[r];
554 //cout << "only one type, r=" << r << " u=" << u << endl;
555 distributions[nb_distributions * nb_line_types + u] =
556 classes_len[r];
557 }
558 for (i = 0; i < nb_multiple_types; i++) {
559 r = multiple_types[i];
560 f = types_first2[i];
561 first = types_first[r];
562 l = types_len[r];
563 //cout << "multiple types, r=" << r
564 // << " first=" << first << endl;
565 for (j = 0; j < l; j++) {
566 a = D2->x[f + j];
567 if (f_scale) {
568 a *= scaling;
569 }
570 distributions[nb_distributions * nb_line_types
571 + first + j] = a;
572 }
573 }
574 nb_distributions++;
575
576 nb_sol++;
577 if (f_once) {
578 ret = FALSE;
579 }
580 else {
581 if (f_use_mckay_solver) {
582 ret = D2->solve_next_mckay(0/*verbose_level - 5*/);
583 }
584 else {
585 ret = D2->solve_next_betten(0/*verbose_level - 5*/);
586 }
587 }
588 if (!ret) {
589 break;
590 }
591 nb_steps += D2->nb_steps_betten;
592 }
593 }
594
595 nb_steps += D2->nb_steps_betten;
596 if (f_v) {
597 cout << "solve_second_system: found " << nb_distributions
598 << " distributions in " << nb_steps << " steps" << endl;
599 }
600}
601
602
603}}}
604
void solve_second_system_with_help(int verbose_level, int f_use_mckay_solver, int f_once, int *classes_len, int f_scale, int scaling, int *&line_types, int &nb_line_types, int *&distributions, int &nb_distributions, int cnt_second_system, solution_file_data *Sol)
Definition: tdo_data.cpp:373
void solve_second_system(int verbose_level, int f_use_mckay_solver, int f_once, int *classes_len, int f_scale, int scaling, int *&line_types, int &nb_line_types, int *&distributions, int &nb_distributions)
Definition: tdo_data.cpp:483
int solve_first_system(int verbose_level, int *&line_types, int &nb_line_types, int &line_types_allocated)
Definition: tdo_data.cpp:93
void solve_second_system_from_file(int verbose_level, int *classes_len, int f_scale, int scaling, int *&line_types, int &nb_line_types, int *&distributions, int &nb_distributions, std::string &solution_file_name)
Definition: tdo_data.cpp:402
void solve_second_system_omit(int verbose_level, int *classes_len, int *&line_types, int &nb_line_types, int *&distributions, int &nb_distributions, int omit)
Definition: tdo_data.cpp:150
diophantine systems of equations (i.e., linear systems over the integers)
Definition: solvers.h:209
int solve_all_mckay(long int &nb_backtrack_nodes, int maxresults, int verbose_level)
Definition: diophant.cpp:1435
int solve_first_mckay_once_option(int f_once, int verbose_level)
Definition: diophant.cpp:4551
void project(diophant *D, int first, int len, int *&eqn_number, int &nb_eqns_replaced, int *&eqns_replaced, int verbose_level)
Definition: diophant.cpp:3349
void write_xml(std::ostream &ost, const char *label)
Definition: diophant.cpp:3682
std::deque< std::vector< int > > _results
Definition: solvers.h:242
#define FREE_int(p)
Definition: foundations.h:640
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
the orbiter library for the classification of combinatorial objects