Orbiter 2022
Combinatorial Objects
diophant.cpp
Go to the documentation of this file.
1// diophant.cpp
2//
3// Anton Betten
4// September 18, 2000
5//
6// moved to GALOIS: April 16, 2015
7
8#include "foundations.h"
9
10
11using namespace std;
12
13namespace orbiter {
14namespace layer1_foundations {
15namespace solvers {
16
17
18
19static void (*diophant_user_callback_solution_found)(int *sol,
20 int len, int nb_sol, void *data) = NULL;
21
22static void diophant_callback_solution_found(int *sol,
23 int len, int nb_sol, void *data);
24
25
27{
28 label[0] = 0;
29
30 m = 0;
31 n = 0;
33 sum = sum1 = 0;
34
35 //f_x_max = FALSE;
36
37 A = NULL;
38 G = NULL;
39 x_max = NULL;
40 x_min = NULL;
41 x = NULL;
42 RHS = NULL;
43 RHS_low = NULL;
44 RHS1 = NULL;
45 type = NULL;
46 eqn_label = NULL;
47
49 var_labels = NULL;
50
51 X = FALSE;
52 Y = FALSE;
53
54 // results
55 _maxresults = 0;
56 _resultanz = 0;
57 _cur_result = 0;
63 t0 = 0;
64
65 //null();
66}
67
68
70{
71 freeself();
72}
73
75{
76 //label[0] = 0;
77
78 m = 0;
79 n = 0;
81 sum = sum1 = 0;
82
83 //f_x_max = FALSE;
84
85 A = NULL;
86 G = NULL;
87 x_max = NULL;
88 x_min = NULL;
89 x = NULL;
90 RHS = NULL;
91 RHS_low = NULL;
92 RHS1 = NULL;
93 type = NULL;
94 eqn_label = NULL;
95
97 var_labels = NULL;
98
99 X = FALSE;
100 Y = FALSE;
101
102 // results
103 _maxresults = 0;
104 _resultanz = 0;
105 _cur_result = 0;
106 nb_steps_betten = 0;
109 max_time_in_sec = 0;
111 t0 = 0;
112}
113
115{
116 int verbose_level = 0;
117 int f_v = (verbose_level >= 1);
118 int i;
119
120 if (f_v) {
121 cout << "diophant::freeself" << endl;
122 }
123 if (A) {
124 FREE_int(A);
125 }
126 if (G) {
127 FREE_int(G);
128 }
129 if (x) {
130 FREE_int(x);
131 }
132 if (x_max) {
134 }
135 if (x_min) {
137 }
138 if (f_v) {
139 cout << "diophant::freeself before RHS" << endl;
140 }
141 if (RHS) {
142 FREE_int(RHS);
143 }
144 if (f_v) {
145 cout << "diophant::freeself before RHS_low" << endl;
146 }
147 if (RHS_low) {
149 }
150 if (f_v) {
151 cout << "diophant::freeself before RHS1" << endl;
152 }
153 if (RHS1) {
154 FREE_int(RHS1);
155 }
156 if (type) {
158 }
159 if (f_v) {
160 cout << "diophant::freeself before eqn_label" << endl;
161 }
162 if (eqn_label) {
163 for (i = 0; i < m; i++) {
164 if (eqn_label[i]) {
166 }
167 }
169 }
170 if (X) {
171 FREE_int(X);
172 }
173 if (Y) {
174 FREE_int(Y);
175 }
176 if (f_has_var_labels) {
178 }
179 null();
180 if (f_v) {
181 cout << "diophant::freeself done" << endl;
182 }
183}
184
185void diophant::open(int m, int n)
186{
187 int i;
188
189 A = NEW_int(m * n);
190 Int_vec_zero(A, m * n);
191 G = NEW_int(m * n);
192 Int_vec_zero(G, m * n);
193 x = NEW_int(n);
194 Int_vec_zero(x, n);
195 x_max = NEW_int(n);
197 x_min = NEW_int(n);
199 RHS = NEW_int(m);
201 RHS_low = NEW_int(m);
202 RHS1 = NEW_int(m);
205 X = NEW_int(n);
206 Y = NEW_int(m);
207
208 for (i = 0; i < n; i++) {
209 x_max[i] = 0;
210 }
211 label[0] = 0;
212 diophant::m = m;
213 diophant::n = n;
214 for (i = 0; i < m; i++) {
215 type[i] = t_EQ;
216 eqn_label[i] = NULL;
217 }
219 //f_x_max = FALSE;
222}
223
224void diophant::init_var_labels(long int *labels, int verbose_level)
225{
226 int f_v = (verbose_level >= 1);
227
228 if (f_v) {
229 cout << "diophant::init_var_labels" << endl;
230 }
234 if (f_v) {
235 cout << "diophant::init_var_labels done" << endl;
236 }
237
238}
240 diophant *D1, diophant *D2, int verbose_level)
241{
242 int f_v = (verbose_level >= 1);
243 int nb_rows, nb_cols;
244 int nb_r1, nb_r2;
245 int i, j;
246
247 if (f_v) {
248 cout << "diophant::join_problems" << endl;
249 }
250 if (D1->n != D2->n) {
251 cout << "D1->n != D2->n" << endl;
252 exit(1);
253 }
254 if (D1->sum != D2->sum) {
255 cout << "D1->sum != D2->sum" << endl;
256 exit(1);
257 }
258 if (!D1->f_has_sum) {
259 cout << "!D1->f_has_sum" << endl;
260 exit(1);
261 }
262 if (!D2->f_has_sum) {
263 cout << "!D2->f_has_sum" << endl;
264 exit(1);
265 }
266#if 0
267 if (D1->f_x_max != D2->f_x_max) {
268 cout << "D1->f_x_max != D2->f_x_max" << endl;
269 exit(1);
270 }
271#endif
272 nb_cols = D1->n;
273 nb_r1 = D1->m;
274 nb_r2 = D2->m;
275 nb_rows = nb_r1 + nb_r2;
276 open(nb_rows, nb_cols);
277 f_has_sum = TRUE;
278 sum = D1->sum;
279 //f_x_max = D1->f_x_max;
280#if 0
281 if (f_x_max) {
282 for (i = 0; i < nb_cols; i++) {
283 if (D1->x_max[i] != D2->x_max[i]) {
284 cout << "D1->x_max[i] != D2->x_max[i]" << endl;
285 exit(1);
286 }
287 x_max[i] = D1->x_max[i];
288 }
289 }
290#else
291 for (i = 0; i < nb_cols; i++) {
292 x_max[i] = MINIMUM(D1->x_max[i], D2->x_max[i]);
293 x_min[i] = MAXIMUM(D1->x_min[i], D2->x_min[i]);
294 }
295#endif
296 for (i = 0; i < nb_r1; i++) {
297 for (j = 0; j < nb_cols; j++) {
298 Aij(i, j) = D1->Aij(i, j);
299 }
300 type[i] = D1->type[i];
301 RHSi(i) = D1->RHSi(i);
302 RHS_low_i(i) = D1->RHS_low_i(i);
303 }
304 for (i = 0; i < nb_r2; i++) {
305 for (j = 0; j < nb_cols; j++) {
306 Aij(nb_r1 + i, j) = D2->Aij(i, j);
307 }
308 type[nb_r1 + i] = D2->type[i];
309 RHSi(nb_r1 + i) = D2->RHSi(i);
310 RHS_low_i(nb_r1 + i) = D2->RHS_low_i(nb_r1 + i);
311 }
312 if (f_v) {
313 cout << "diophant::join_problems done" << endl;
314 }
315}
316
318 int *weights, int nb_weights, int target_value,
319 int verbose_level)
320{
321 int f_v = (verbose_level >= 1);
322 int j;
323
324 if (f_v) {
325 cout << "diophant::init_partition_problem" << endl;
326 }
327 open(1, nb_weights);
328 for (j = 0; j < nb_weights; j++) {
329 x_max[j] = target_value / weights[j];
330 x_min[j] = 0;
331 }
332 //f_x_max = TRUE;
334 //sum = nb_to_select;
335 for (j = 0; j < nb_weights; j++) {
336 Aij(0, j) = weights[j];
337 }
338 RHSi(0) = target_value;
339 RHS_low_i(0) = 0; // not used
340 if (f_v) {
341 cout << "diophant::init_partition_problem" << endl;
342 }
343}
344
346 int *weights, int *bounds, int nb_weights, int target_value,
347 int verbose_level)
348{
349 int f_v = (verbose_level >= 1);
350 int j;
351
352 if (f_v) {
353 cout << "diophant::init_partition_problem_with_bounds" << endl;
354 }
355 open(1, nb_weights);
356 for (j = 0; j < nb_weights; j++) {
357 x_max[j] = bounds[j]; // target_value / weights[j];
358 x_min[j] = 0;
359 }
360 //f_x_max = TRUE;
362 //sum = nb_to_select;
363 for (j = 0; j < nb_weights; j++) {
364 Aij(0, j) = weights[j];
365 }
366 RHSi(0) = target_value;
367 RHS_low_i(0) = 0; // not used
368 if (f_v) {
369 cout << "diophant::init_partition_problem_with_bounds" << endl;
370 }
371}
372
373
374
376 int nb_rows, int nb_cols, int *Inc, int nb_to_select,
377 int *Rhs, int verbose_level)
378{
379 int f_v = (verbose_level >= 1);
380 int i, j;
381
382 if (f_v) {
383 cout << "diophant::init_problem_of_Steiner_type_with_RHS" << endl;
384 }
385 open(nb_rows, nb_cols);
386 for (j = 0; j < nb_cols; j++) {
387 x_max[j] = 1;
388 x_min[j] = 0;
389 }
390 //f_x_max = TRUE;
391 f_has_sum = TRUE;
392 sum = nb_to_select;
393 for (i = 0; i < nb_rows; i++) {
394 for (j = 0; j < nb_cols; j++) {
395 Aij(i, j) = Inc[i * nb_cols + j];
396 }
397 RHSi(i) = Rhs[i];
398 RHS_low_i(i) = 0; // not used
399 }
400 if (f_v) {
401 cout << "diophant::init_problem_of_Steiner_type_with_RHS done" << endl;
402 }
403}
404
406 int nb_rows, int nb_cols, int *Inc, int nb_to_select,
407 int verbose_level)
408{
409 int f_v = (verbose_level >= 1);
410 int i, j;
411
412 if (f_v) {
413 cout << "diophant::init_problem_of_Steiner_type" << endl;
414 }
415 open(nb_rows, nb_cols);
416 for (j = 0; j < nb_cols; j++) {
417 x_max[j] = 1;
418 x_min[j] = 0;
419 }
420 //f_x_max = TRUE;
421 f_has_sum = TRUE;
422 sum = nb_to_select;
423 for (i = 0; i < nb_rows; i++) {
424 for (j = 0; j < nb_cols; j++) {
425 Aij(i, j) = Inc[i * nb_cols + j];
426 }
427 RHSi(i) = 1;
428 RHS_low_i(i) = 0; // not used
429 }
430 if (f_v) {
431 cout << "diophant::init_problem_of_Steiner_type done" << endl;
432 }
433}
434
435void diophant::init_RHS(int RHS_value, int verbose_level)
436{
437 int f_v = (verbose_level >= 1);
438 int i;
439
440 if (f_v) {
441 cout << "diophant::init_RHS" << endl;
442 }
443 for (i = 0; i < m; i++) {
444 RHSi(i) = RHS_value;
445 }
446 if (f_v) {
447 cout << "diophant::init_RHS done" << endl;
448 }
449}
450
451void diophant::init_clique_finding_problem(int *Adj, int nb_pts,
452 int nb_to_select, int verbose_level)
453{
454 int f_v = (verbose_level >= 1);
455 int i, j, i1, i2;
456 int nb_zeros = 0, nb_ones = 0, total;
457
458 if (f_v) {
459 cout << "diophant::init_clique_finding_problem" << endl;
460 }
461 for (i = 0; i < nb_pts; i++) {
462 for (j = i + 1; j < nb_pts; j++) {
463 if (Adj[i * nb_pts + j]) {
464 nb_ones++;
465 }
466 else {
467 nb_zeros++;
468 }
469 }
470 }
471 total = nb_ones + nb_zeros;
472 if (f_v) {
473 cout << "nb_zeros=" << nb_zeros << endl;
474 cout << "nb_ones =" << nb_ones << endl;
475 total = nb_zeros + nb_ones;
476 cout << "edge density = " <<
477 (double)nb_ones / (double)total << endl;
478 }
479 open(nb_zeros, nb_pts);
480 for (j = 0; j < nb_pts; j++) {
481 x_max[j] = 1;
482 x_min[j] = 0;
483 }
484 //f_x_max = TRUE;
485 f_has_sum = TRUE;
486 sum = nb_to_select;
487 i = 0;
488 for (i1 = 0; i1 < nb_pts; i1++) {
489 for (i2 = i1 + 1; i2 < nb_pts; i2++) {
490 if (Adj[i1 * nb_pts + i2] == 0) {
491 Aij(i, i1) = 1;
492 Aij(i, i2) = 1;
493 type[i] = t_LE;
494 RHSi(i) = 1;
495 RHS_low_i(i) = 0; // not used
496 i++;
497 }
498 }
499 }
500 if (f_v) {
501 cout << "diophant::init_clique_finding_problem done" << endl;
502 }
503}
504
505
507{
508 int i;
509
510 for (i = 0; i < m * n; i++) {
511 A[i] = a;
512 }
513}
514
516{
517 int j;
518
519 for (j = 0; j < n; j++) {
520 x_min[j] = a;
521 }
522}
523
525{
526 int j;
527
528 for (j = 0; j < n; j++) {
529 x_max[j] = a;
530 }
531}
532
533int &diophant::Aij(int i, int j)
534{
535 if (i >= m) {
536 cout << "diophant::Aij i >= m" << endl;
537 cout << "i=" << i << endl;
538 cout << "m=" << m << endl;
539 exit(1);
540 }
541 if (j >= n) {
542 cout << "diophant::Aij j >= n" << endl;
543 cout << "j=" << j << endl;
544 cout << "n=" << n << endl;
545 exit(1);
546 }
547 return A[i * n + j];
548}
549
550int &diophant::Gij(int i, int j)
551{
552 if (i >= m) {
553 cout << "diophant::Gij i >= m" << endl;
554 cout << "i=" << i << endl;
555 cout << "m=" << m << endl;
556 exit(1);
557 }
558 if (j >= n) {
559 cout << "diophant::Gij j >= n" << endl;
560 cout << "j=" << j << endl;
561 cout << "n=" << n << endl;
562 exit(1);
563 }
564 return G[i * n + j];
565}
566
567int &diophant::RHSi(int i)
568{
569 if (i >= m) {
570 cout << "diophant::RHSi i >= m" << endl;
571 exit(1);
572 }
573 return RHS[i];
574}
575
577{
578 if (i >= m) {
579 cout << "diophant::RHS_low_i i >= m" << endl;
580 exit(1);
581 }
582 return RHS_low[i];
583}
584
585void diophant::init_eqn_label(int i, char *label)
586{
587 int l;
588
589 if (i >= m) {
590 cout << "diophant::init_eqn_label i >= m" << endl;
591 cout << "label: " << label << endl;
592 cout << "i=" << i << endl;
593 exit(1);
594 }
595 if (eqn_label[i]) {
597 eqn_label[i] = NULL;
598 }
599 l = strlen(label) + 1;
600 eqn_label[i] = NEW_char(l);
601 strcpy(eqn_label[i], label);
602}
603
605{
606 print2(FALSE);
607}
608
610{
611 int i, j, s, c;
612 for (i = 0; i < m; i++) {
613 s = 0;
614 for (j = 0; j < n; j++) {
615 c = Aij(i, j);
616 s += c;
617 cout << setw(1) << c;
618 }
619 if (type[i] == t_EQ) {
620 cout << " = " << RHS[i];
621 }
622 else if (type[i] == t_LE) {
623 cout << " <= " << RHS[i];
624 }
625 else if (type[i] == t_INT) {
626 cout << " in [" << RHS_low_i(i) << "," << RHS[i] << "]";
627 }
628 else if (type[i] == t_ZOR) {
629 cout << " ZOR " << RHS[i];
630 }
631 cout << " (rowsum=" << s << ")" << endl;
632 }
633 if (f_has_sum) {
634 cout << "sum = " << sum << endl;
635 }
636 else {
637 cout << "there is no restriction on the sum" << endl;
638 }
639}
640
641void diophant::print2(int f_with_gcd)
642{
643 int i, j;
644
645 cout << "diophant with m=" << m << " n=" << n << endl;
646 for (i = 0; i < m; i++) {
647 print_eqn(i, f_with_gcd);
648 }
649 //if (f_x_max) {
650 for (j = 0; j < n; j++) {
651 cout << x_min[j] << " \\le x_{" << j << "} \\le " << x_max[j] << ", ";
652 }
653 cout << endl;
654 //}
655 if (f_has_sum) {
656 cout << "sum = " << sum << endl;
657 }
658 else {
659 cout << "there is no condition on the sum of x_i" << endl;
660 }
661 //latex_it();
662}
663
665{
666 int i, j;
667
668 cout << "diophant with m=" << m << " n=" << n << endl;
669 for (i = 0; i < m; i++) {
671 }
672 //if (f_x_max) {
673 for (j = 0; j < n; j++) {
674 cout << x_min[j];
675 cout << x_max[j];
676 }
677 cout << endl;
678 //}
679 if (f_has_sum) {
680 cout << "sum = " << sum << endl;
681 }
682 else {
683 cout << "there is no condition on the sum of x_i" << endl;
684 }
685 //latex_it();
686}
687
689{
690 int i, j;
691
692 cout << "diophant with m=" << m << " n=" << n << endl;
693 for (i = 0; i < m; i++) {
695 }
696 //if (f_x_max) {
697 for (j = 0; j < n; j++) {
698 cout << x_min[j] << " \\le x_{" << j << "} \\le " << x_max[j] << ", ";
699 }
700 cout << endl;
701 //}
702 if (f_has_sum) {
703 cout << "sum = " << sum << endl;
704 }
705 else {
706 cout << "there is no condition on the sum of x_i" << endl;
707 }
708}
709
710
711void diophant::print_eqn(int i, int f_with_gcd)
712{
713 int j;
714
715 for (j = 0; j < n; j++) {
716 cout << setw(3) << Aij(i, j) << " ";
717 if (f_with_gcd) {
718 cout << "|" << setw(3) << Gij(i, j) << " ";
719 }
720 }
721 if (type[i] == t_EQ) {
722 cout << " = " << setw(3) << RHSi(i);
723 }
724 else if (type[i] == t_LE) {
725 cout << " <= " << setw(3) << RHSi(i);
726 }
727 else if (type[i] == t_INT) {
728 cout << " in [" << RHS_low_i(i) << ", " << setw(3) << RHSi(i) << "]";
729 }
730 else if (type[i] == t_ZOR) {
731 cout << " ZOR " << setw(3) << RHSi(i);
732 }
733 cout << " ";
734 if (eqn_label[i]) {
735 cout << eqn_label[i];
736 }
737 cout << endl;
738}
739
741{
742 int j;
743
744 for (j = 0; j < n; j++) {
745 if (Aij(i, j) == 0) {
746 continue;
747 }
748 if (Aij(i, j) == 1) {
749 cout << " + x_{" << j << "} ";
750 }
751 else {
752 cout << " + " << setw(3)
753 << Aij(i, j) << " * x_{" << j << "} ";
754 }
755 }
756 if (type[i] == t_EQ) {
757 cout << " = ";
758 }
759 else if (type[i] == t_LE) {
760 cout << " <= ";
761 }
762 else if (type[i] == t_INT) {
763 cout << " in [,]";
764 }
765 else if (type[i] == t_ZOR) {
766 cout << " ZOR ";
767 }
768 cout << setw(3) << RHSi(i) << " ";
769 if (eqn_label[i]) {
770 cout << eqn_label[i];
771 }
772 cout << endl;
773}
774
776{
777 int j;
778
779 for (j = 0; j < n; j++) {
780 cout << Aij(i, j);
781 }
782 if (type[i] == t_EQ) {
783 cout << " = " << setw(3) << RHSi(i);
784 }
785 else if (type[i] == t_LE) {
786 cout << " <= " << setw(3) << RHSi(i);
787 }
788 else if (type[i] == t_INT) {
789 cout << " in [" << RHS_low_i(i) << "," << setw(3) << RHSi(i) << "]";
790 }
791 else if (type[i] == t_ZOR) {
792 cout << " ZOR " << setw(3) << RHSi(i);
793 }
794 cout << " ";
795 if (eqn_label[i]) {
796 cout << eqn_label[i];
797 }
798 cout << endl;
799}
800
802{
803 int j;
804
805 for (j = 0; j < n; j++) {
806 cout << "x_{" << j << "} = " << x[j] << endl;
807 }
808}
809
810void diophant::print_x(int header)
811{
812 int j;
813
814 cout << setw(5) << header << " : ";
815 for (j = 0; j < n; j++) {
816 cout << setw(3) << x[j] << " ";
817 }
818 cout << endl;
819}
820
822{
823 int k;
824
825 for (k = 0; k < m; k++) {
826 if (RHS1[k] < 0) {
827 return FALSE;
828 }
829 }
830 return TRUE;
831}
832
833int diophant::solve_first(int verbose_level)
834{
835
836#if 0
837 if (FALSE/*n >= 50*/) {
838 return solve_first_wassermann(verbose_level);
839 }
840#endif
841
842 if (TRUE) {
843 return solve_first_betten(verbose_level);
844 }
845 else {
846 //cout << "diophant::solve_first
847 //solve_first_mckay is disabled" << endl;
848 return solve_first_mckay(FALSE, verbose_level);
849 }
850}
851
853{
854 return solve_next_betten(0);
855 //return solve_next_mckay();
856}
857
858#if 0
859int diophant::solve_first_wassermann(int verbose_level)
860{
861 solve_wassermann(verbose_level);
862 exit(1);
863}
864#endif
865
866int diophant::solve_first_mckay(int f_once, int verbose_level)
867{
868 int f_v = TRUE;//(verbose_level >= 1);
869 int j;
870 //int maxresults = 10000000;
871 int maxresults = INT_MAX;
872 vector<int> res;
873 long int nb_backtrack_nodes;
874 int nb_sol;
875
876 //verbose_level = 4;
877 if (f_v) {
878 cout << "diophant::solve_first_mckay "
879 "calling solve_mckay" << endl;
880 }
881 if (f_once) {
882 maxresults = 1;
883 }
884 solve_mckay("", maxresults, nb_backtrack_nodes, nb_sol, verbose_level - 2);
885 if (f_v) {
886 cout << "diophant::solve_first_mckay found " << _resultanz
887 << " solutions, using " << nb_backtrack_nodes
888 << " backtrack nodes" << endl;
889 }
890 _cur_result = 0;
891 if (_resultanz == 0) {
892 return FALSE;
893 }
894 res = _results.front();
895 for (j = 0; j < n; j++) {
896 x[j] = res[j];
897 }
898 _results.pop_front();
899 _cur_result++;
900 if (f_v) {
901 cout << "diophant::solve_first_mckay done" << endl;
902 }
903 return TRUE;
904}
905
906#if 0
907void diophant::draw_solutions(std::string &fname_base, int verbose_level)
908{
909 int f_v = (verbose_level >= 1);
910 int i, j;
911 vector<int> res;
912 int *solution;
913 int solution_sz;
914
915 if (f_v) {
916 cout << "diophant::draw_solutions" << endl;
917 }
918 solution = NEW_int(n);
919
920 for (i = 0; i < _resultanz; i++) {
921 res = _results.front();
922 solution_sz = 0;
923 for (j = 0; j < n; j++) {
924 if (res[j]) {
925 solution[solution_sz++] = j;
926 }
927 }
928
929 std::string fname_base2;
930
931 fname_base2.assign(fname_base);
932 char str[1000];
933
934 sprintf(str, "_sol_%d", i);
935 fname_base2.append(str);
936
937#if 0
938 int xmax_in = ONE_MILLION;
939 int ymax_in = ONE_MILLION;
940 int xmax_out = ONE_MILLION;
941 int ymax_out = ONE_MILLION;
942#endif
943
944 draw_partitioned(fname_base2,
945 //xmax_in, ymax_in, xmax_out, ymax_out,
946 TRUE /*f_solution*/, solution, solution_sz,
947 verbose_level);
948 _results.pop_front();
949 }
950
951 FREE_int(solution);
952 if (f_v) {
953 cout << "diophant::draw_solutions done" << endl;
954 }
955}
956#endif
957
958void diophant::write_solutions(std::string &fname, int verbose_level)
959{
960 int f_v = (verbose_level >= 1);
961 int i, j, h;
962 vector<int> res;
964
965 if (f_v) {
966 cout << "diophant::write_solutions" << endl;
967 }
968
969 {
970 ofstream fp(fname.c_str());
971
972 fp << _resultanz << " " << n << endl;
973 for (i = 0; i < _resultanz; i++) {
974 res = _results.front();
975 h = 0;
976 for (j = 0; j < n; j++) {
977 fp << res[j] << " ";
978 h += res[j];
979#if 0
980 if (res[j]) {
981 fp << j << " ";
982 h++;
983 }
984#endif
985 }
986 if (f_has_sum) {
987 if (h != sum) {
988 cout << "diophant::write_solutions h != sum" << endl;
989 cout << "nb_sol = " << _resultanz << endl;
990 cout << "sum = " << sum << endl;
991 cout << "h = " << h << endl;
992 cout << "res=" << endl;
993 for (j = 0; j < n; j++) {
994 cout << j << " : " << res[j] << endl;
995 }
996 exit(1);
997 }
998 }
999 fp << endl;
1000 _results.pop_front();
1001 }
1002 fp << "-1" << endl;
1003 }
1004 if (f_v) {
1005 cout << "diophant::write_solutions written file " << fname
1006 << " of size " << Fio.file_size(fname) << endl;
1007 }
1008}
1009
1010void diophant::read_solutions_from_file(std::string &fname_sol,
1011 int verbose_level)
1012{
1013 int f_v = (verbose_level >= 1);
1014 int i, j;
1015 vector<int> res;
1017
1018 if (f_v) {
1019 cout << "diophant::read_solutions_from_file" << endl;
1020 }
1021 if (f_v) {
1022 cout << "diophant::read_solutions_from_file reading file "
1023 << fname_sol << " of size " << Fio.file_size(fname_sol) << endl;
1024 }
1025 if (Fio.file_size(fname_sol) <= 0) {
1026 cout << "diophant::read_solutions_from_file file "
1027 << fname_sol << " does not exist" << endl;
1028 exit(1);
1029 }
1030
1031 {
1032 ifstream fp(fname_sol.c_str());
1033 int N, s, h;
1034
1035 fp >> N >> s;
1036
1037 sum = s;
1038 cout << "diophant::read_solutions_from_file reading " << N
1039 << " solutions of length " << sum << endl;
1040 _resultanz = 0;
1041 for (i = 0; i < N; i++) {
1042 res.resize(n);
1043 for (j = 0; j < n; j++) {
1044 res[j] = 0;
1045 }
1046 for (h = 0; h < n; h++) {
1047 fp >> res[h];
1048 }
1049 _results.push_back(res);
1050 _resultanz++;
1051 }
1052
1053 }
1054 if (f_v) {
1055 cout << "diophant::read_solutions_from_file read " << _resultanz
1056 << " solutions from file " << fname_sol << " of size "
1057 << Fio.file_size(fname_sol) << endl;
1058 }
1059}
1060
1061
1062void diophant::get_solutions(long int *&Sol, int &nb_sol, int verbose_level)
1063{
1064 int f_v = (verbose_level >= 1);
1065 int i, j, h;
1066 vector<int> res;
1067
1068 if (f_v) {
1069 cout << "diophant::get_solutions" << endl;
1070 cout << "nb_sol = " << _resultanz << endl;
1071 cout << "sum = " << sum << endl;
1072 }
1073 if (!f_has_sum) {
1074 cout << "diophant::get_solutions !f_has_sum" << endl;
1075 exit(1);
1076 }
1077 nb_sol = _resultanz;
1078 Sol = NEW_lint(nb_sol * sum);
1079 for (i = 0; i < _resultanz; i++) {
1080 res = _results.front();
1081 h = 0;
1082 for (j = 0; j < n; j++) {
1083 //x[j] = res[j];
1084 if (res[j]) {
1085 Sol[i * sum + h] = j;
1086 h++;
1087 }
1088 }
1089 if (h != sum) {
1090 cout << "diophant::get_solutions h != sum" << endl;
1091 exit(1);
1092 }
1093 _results.pop_front();
1094 }
1095 if (f_v) {
1096 cout << "diophant::get_solutions done" << endl;
1097 }
1098}
1099
1101 int &nb_sol, int verbose_level)
1102{
1103 int f_v = (verbose_level >= 1);
1104 int i, j;
1105 vector<int> res;
1106
1107 if (f_v) {
1108 cout << "diophant::get_solutions_full_length" << endl;
1109 cout << "nb_sol = " << _resultanz << endl;
1110 cout << "sum = " << sum << endl;
1111 }
1112#if 0
1113 if (!f_has_sum) {
1114 cout << "diophant::get_solutions_full_length !f_has_sum" << endl;
1115 exit(1);
1116 }
1117#endif
1118 nb_sol = _resultanz;
1119 Sol = NEW_int(nb_sol * n);
1120 for (i = 0; i < _resultanz; i++) {
1121 res = _results.front();
1122 for (j = 0; j < n; j++) {
1123 Sol[i * n + j] = res[j];
1124 }
1125 _results.pop_front();
1126 }
1127 if (f_v) {
1128 cout << "diophant::get_solutions_full_length done" << endl;
1129 }
1130}
1131
1132void diophant::test_solution_full_length(int *sol, int verbose_level)
1133{
1134 int f_v = (verbose_level >= 1);
1135 int i, j, s;
1136
1137 if (f_v) {
1138 cout << "diophant::test_solution_full_length" << endl;
1139 }
1140 s = 0;
1141 for (j = 0; j < n; j++) {
1142 s += sol[j];
1143 }
1144 cout << "diophant::test_solution_full_length s=" << s << endl;
1145 if (!f_has_sum) {
1146 cout << "diophant::get_solutions_full_length !f_has_sum" << endl;
1147 exit(1);
1148 }
1149 if (s != sum) {
1150 cout << "diophant::test_solution_full_length s != sum" << endl;
1151 exit(1);
1152 }
1153 for (i = 0; i < m; i++) {
1154 s = 0;
1155 for (j = 0; j < n; j++) {
1156 s += Aij(i, j) * sol[j];
1157 }
1158 cout << "diophant::test_solution_full_length condition " << i
1159 << " / " << m << ":" << endl;
1160 if (type[i] == t_EQ) {
1161 if (s != RHSi(i)) {
1162 cout << "diophant::test_solution_full_length condition "
1163 << i << " / " << m << ": s=" << s
1164 << " is not equal to " << RHSi(i) << endl;
1165 exit(1);
1166 }
1167 }
1168 else if (type[i] == t_LE) {
1169 if (s >= RHSi(i)) {
1170 cout << "diophant::test_solution_full_length condition "
1171 << i << " / " << m << ": s=" << s
1172 << " is larger than " << RHSi(i) << endl;
1173 exit(1);
1174 }
1175 }
1176 else if (type[i] == t_INT) {
1177 if (s >= RHSi(i)) {
1178 cout << "diophant::test_solution_full_length condition "
1179 << i << " / " << m << ": s=" << s
1180 << " is larger than " << RHSi(i) << endl;
1181 exit(1);
1182 }
1183 if (s < RHS_low_i(i)) {
1184 cout << "diophant::test_solution_full_length condition "
1185 << i << " / " << m << ": s=" << s
1186 << " is less than " << RHS_low_i(i) << endl;
1187 exit(1);
1188 }
1189 }
1190 else if (type[i] == t_ZOR) {
1191 if (s != 0 && s != RHSi(i)) {
1192 cout << "diophant::test_solution_full_length condition "
1193 << i << " / " << m << ": s=" << s
1194 << " is not equal to " << RHSi(i)
1195 << " or zero" << endl;
1196 exit(1);
1197 }
1198 }
1199 }
1200}
1201
1202int diophant::solve_all_DLX(int verbose_level)
1203{
1204 int f_v = (verbose_level >= 1);
1205
1206 if (f_v) {
1207 cout << "diophant::solve_all_DLX verbose_level="
1208 << verbose_level << endl;
1209 }
1210 //install_callback_solution_found(diophant_callback_solution_found, this);
1211
1212 int *Inc;
1213 int i, j;
1214 //int nb_sol, nb_backtrack;
1215
1216 Inc = NEW_int(m * n);
1217 for (i = 0; i < m; i++) {
1218 for (j = 0; j < n; j++) {
1219 Inc[i * n + j] = Aij(i, j);
1220 }
1221 }
1222
1223 _resultanz = 0;
1224
1226
1227 Descr.f_label_txt = TRUE;
1228 Descr.label_txt.assign(label);
1229 Descr.f_label_tex = TRUE;
1230 Descr.label_tex.assign(label);
1231
1232 Descr.f_data_matrix = TRUE;
1233 Descr.data_matrix = Inc;
1234 Descr.data_matrix_m = m;
1235 Descr.data_matrix_n = n;
1236
1237 dlx_solver Solver;
1238
1239 if (f_v) {
1240 cout << "diophant::solve_all_DLX before Solver.init" << endl;
1241 }
1242 Solver.init(&Descr, verbose_level);
1243 if (f_v) {
1244 cout << "diophant::solve_all_DLX after Solver.init" << endl;
1245 }
1246 Solver.install_callback_solution_found(diophant_callback_solution_found, this);
1247
1248
1249 if (f_v) {
1250 cout << "diophant::solve_all_DLX before Solver.Solve" << endl;
1251 }
1252 Solver.Solve(verbose_level);
1253 if (f_v) {
1254 cout << "diophant::solve_all_DLX after Solver.Solve" << endl;
1255 }
1256
1257
1258#if 0
1259 DlxTransposeAppendAndSolve(Inc, m, n, nb_sol, nb_backtrack,
1260 FALSE, "",
1261 verbose_level - 1);
1262
1263 nb_steps_betten = nb_backtrack;
1264#endif
1265
1267
1268
1269 FREE_int(Inc);
1270 if (f_v) {
1271 cout << "diophant::solve_all_DLX done found " << _resultanz
1272 << " solutions with " << nb_steps_betten
1273 << " backtrack steps" << endl;
1274 }
1275
1276 return _resultanz;
1277}
1278
1280 const char *fname_tree, int verbose_level)
1281{
1282 cout << "diophant::solve_all_DLX_with_RHS disabled" << endl;
1283#if 0
1284 int f_v = (verbose_level >= 1);
1285 int f_vv = (verbose_level >= 2);
1286
1287 if (f_v) {
1288 cout << "diophant::solve_all_DLX_with_RHS "
1289 "verbose_level=" << verbose_level << endl;
1290 }
1291 if (f_v) {
1292 cout << "diophant::solve_all_DLX_with_RHS "
1293 "m=" << m << " n=" << n << endl;
1294 }
1295 install_callback_solution_found(
1296 diophant_callback_solution_found,
1297 this);
1298
1299 int *Inc;
1300 int *my_RHS;
1301 int f_has_type;
1302 diophant_equation_type *my_type;
1303 int i, j;
1304 int nb_sol, nb_backtrack;
1305
1306 Inc = NEW_int(m * n);
1307 for (i = 0; i < m; i++) {
1308 for (j = 0; j < n; j++) {
1309 Inc[i * n + j] = Aij(i, j);
1310 }
1311 }
1312 if (f_vv) {
1313 cout << "diophant::solve_all_DLX_with_RHS "
1314 "the system:" << endl;
1315 Orbiter->Int_vec.matrix_print(Inc, m, n);
1316 }
1317 f_has_type = TRUE;
1318 my_RHS = NEW_int(m);
1320 for (i = 0; i < m; i++) {
1321 my_RHS[i] = RHS[i];
1322 my_type[i] = type[i];
1323 }
1324 if (f_vv) {
1325 cout << "diophant::solve_all_DLX_with_RHS RHS:" << endl;
1326 Orbiter->Int_vec.matrix_print(my_RHS, m, 1);
1327 //cout << diophant::solve_all_DLX_with_RHS type:" << endl;
1328 //int_matrix_print(my_type, m, 1);
1329 }
1330
1331 _resultanz = 0;
1332
1333 DlxTransposeAndSolveRHS(Inc, m, n,
1334 my_RHS, f_has_type, my_type,
1335 nb_sol, nb_backtrack,
1336 FALSE, "",
1337 f_write_tree, fname_tree,
1338 verbose_level - 1);
1339
1340 nb_steps_betten = nb_backtrack;
1341 FREE_int(Inc);
1342 FREE_int(my_RHS);
1343 FREE_OBJECTS(my_type);
1344 if (f_v) {
1345 cout << "diophant::solve_all_DLX_with_RHS done found "
1346 << _resultanz << " solutions with " << nb_backtrack
1347 << " backtrack steps" << endl;
1348 }
1349#endif
1350 return _resultanz;
1351}
1352
1354 int f_write_tree, const char *fname_tree,
1355 void (*user_callback_solution_found)(int *sol,
1356 int len, int nb_sol, void *data),
1357 int verbose_level)
1358{
1359 cout << "diophant::solve_all_DLX_with_RHS_and_callback disabled" << endl;
1360
1361#if 0
1362 int f_v = (verbose_level >= 1);
1363 int f_vv = (verbose_level >= 2);
1364
1365 if (f_v) {
1366 cout << "diophant::solve_all_DLX_with_RHS "
1367 "verbose_level=" << verbose_level << endl;
1368 }
1369 if (f_v) {
1370 cout << "diophant::solve_all_DLX_with_RHS "
1371 "m=" << m << " n=" << n << endl;
1372 }
1373 diophant_user_callback_solution_found = user_callback_solution_found;
1374
1375 install_callback_solution_found(
1376 diophant_callback_solution_found,
1377 this);
1378
1379 int *Inc;
1380 int *my_RHS;
1381 int f_has_type;
1382 diophant_equation_type *my_type;
1383 int i, j;
1384 int nb_sol, nb_backtrack;
1385
1386 Inc = NEW_int(m * n);
1387 for (i = 0; i < m; i++) {
1388 for (j = 0; j < n; j++) {
1389 Inc[i * n + j] = Aij(i, j);
1390 }
1391 }
1392 if (f_vv) {
1393 cout << "diophant::solve_all_DLX_with_RHS "
1394 "the system:" << endl;
1395 Orbiter->Int_vec.matrix_print(Inc, m, n);
1396 }
1397 f_has_type = TRUE;
1398 my_RHS = NEW_int(m);
1400 //my_f_le = NEW_int(m);
1401 for (i = 0; i < m; i++) {
1402 my_RHS[i] = RHS[i];
1403 my_type[i] = type[i];
1404 //my_f_le[i] = f_le[i];
1405 }
1406 if (f_vv) {
1407 cout << "diophant::solve_all_DLX_with_RHS RHS:" << endl;
1408 Orbiter->Int_vec.matrix_print(my_RHS, m, 1);
1409 //cout << diophant::solve_all_DLX_with_RHS type:" << endl;
1410 //int_matrix_print(my_type, m, 1);
1411 }
1412
1413 _resultanz = 0;
1414
1415 DlxTransposeAndSolveRHS(Inc, m, n,
1416 my_RHS, f_has_type, my_type,
1417 nb_sol, nb_backtrack,
1418 FALSE, "",
1419 f_write_tree, fname_tree,
1420 verbose_level - 1);
1421
1422 nb_steps_betten = nb_backtrack;
1423 FREE_int(Inc);
1424 FREE_int(my_RHS);
1425 FREE_OBJECTS(my_type);
1426 if (f_v) {
1427 cout << "diophant::solve_all_DLX_with_RHS done found "
1428 << _resultanz << " solutions with " << nb_backtrack
1429 << " backtrack steps" << endl;
1430 }
1431#endif
1432 return _resultanz;
1433}
1434
1435int diophant::solve_all_mckay(long int &nb_backtrack_nodes, int maxresults, int verbose_level)
1436{
1437 int f_v = (verbose_level >= 1);
1438 //int maxresults = 10000;
1439 //long int nb_backtrack_nodes;
1440 int nb_sol;
1441
1442 if (f_v) {
1443 cout << "diophant::solve_all_mckay before solve_mckay, "
1444 "verbose_level=" << verbose_level << endl;
1445 }
1446 solve_mckay(label.c_str(), maxresults,
1447 nb_backtrack_nodes, nb_sol,
1448 verbose_level - 2);
1449 if (f_v) {
1450 cout << "diophant::solve_all_mckay found " << _resultanz
1451 << " solutions in " << nb_backtrack_nodes
1452 << " backtrack nodes" << endl;
1453 }
1454 return _resultanz;
1455}
1456
1457int diophant::solve_once_mckay(int verbose_level)
1458{
1459 int f_v = (verbose_level >= 1);
1460 int maxresults = 1;
1461 long int nb_backtrack_nodes;
1462 int nb_sol;
1463
1464 solve_mckay(label.c_str(), maxresults,
1465 nb_backtrack_nodes, nb_sol, verbose_level - 2);
1466 if (f_v) {
1467 cout << "diophant::solve_once_mckay found " << _resultanz
1468 << " solutions in " << nb_backtrack_nodes
1469 << " backtrack nodes" << endl;
1470 }
1471 return _resultanz;
1472}
1473
1474
1475int diophant::solve_all_betten(int verbose_level)
1476{
1477 int f_v = (verbose_level >= 1);
1478 int j;
1479 vector<int> lo;
1480 //int maxresults = 10000000;
1481 _resultanz = 0;
1482 _cur_result = 0;
1483
1484 if (solve_first_betten(verbose_level - 2)) {
1485 lo.resize(n);
1486 for (j = 0; j < n; j++) {
1487 lo[j] = (int) x[j];
1488 }
1489 _results.push_back(lo);
1490 _resultanz++;
1491 while (solve_next_betten(verbose_level - 2)) {
1492 lo.resize(n);
1493 for (j = 0; j < n; j++) {
1494 lo[j] = (int) x[j];
1495 }
1496 _results.push_back(lo);
1497 _resultanz++;
1498 }
1499 }
1500 //solve_mckay(maxresults, verbose_level - 2);
1501 if (f_v) {
1502 cout << "diophant::solve_all_betten found " << _resultanz
1503 << " solutions in " << nb_steps_betten << " steps" << endl;
1504 }
1505 return _resultanz;
1506}
1507
1509 int f_max_sol, int max_sol,
1510 int f_max_time, int max_time_in_seconds)
1511{
1512 int f_v = (verbose_level >= 1);
1513 int j;
1514 vector<int> lo;
1516
1517
1518 //int maxresults = 10000000;
1519 _resultanz = 0;
1520 _cur_result = 0;
1521
1522 if (f_max_time) {
1524 diophant::max_time_in_sec = max_time_in_seconds;
1526 t0 = Os.os_ticks();
1527 max_time_in_ticks = max_time_in_seconds * Os.os_ticks_per_second();
1528 if (TRUE || f_v) {
1529 cout << "solve_all_betten_with_conditions maxtime "
1530 "max_time_in_sec=" << max_time_in_sec << endl;
1531 }
1532 }
1533 t0 = Os.os_ticks();
1534 if (solve_first_betten(verbose_level - 2)) {
1535 lo.resize(n);
1536 for (j = 0; j < n; j++) {
1537 lo[j] = (int) x[j];
1538 }
1539 _results.push_back(lo);
1540 _resultanz++;
1541 if (f_max_sol && _resultanz == max_sol) {
1542 return TRUE;
1543 }
1544 while (solve_next_betten(verbose_level - 2)) {
1545 lo.resize(n);
1546 for (j = 0; j < n; j++) {
1547 lo[j] = (int) x[j];
1548 }
1549 _results.push_back(lo);
1550 _resultanz++;
1551 if (f_max_sol && _resultanz == max_sol) {
1552 return TRUE;
1553 }
1554 }
1555 }
1557 return TRUE;
1558 }
1559 //solve_mckay(maxresults, verbose_level - 2);
1560 if (f_v) {
1561 cout << "diophant::solve_all_betten found " << _resultanz
1562 << " solutions in " << nb_steps_betten << " steps" << endl;
1563 }
1564 return FALSE;
1565}
1566
1567int diophant::solve_first_betten(int verbose_level)
1568{
1569 int i, j, g;
1570 int f_v = (verbose_level >= 1);
1571 int f_vv = (verbose_level >= 2);
1572 int k, total_max;
1575
1576 if (!f_has_sum) {
1577 cout << "diophant::solve_first_betten !f_has_sum" << endl;
1578 exit(1);
1579 }
1580 nb_steps_betten = 0;
1581 if (m <= 0) {
1582 if (f_v) {
1583 cout << "diophant::solve_first_betten(): m <= 0" << endl;
1584 }
1585 return TRUE;
1586 }
1587 if (n == 0) {
1588 //cout << "diophant::solve_first_betten(): n == 0" << endl;
1589 for (i = 0; i < m; i++) {
1590 if (type[i] == t_EQ) {
1591 if (RHS[i]) {
1592 if (f_v) {
1593 cout << "diophant::solve_first_betten no solution "
1594 "in equation " << i << " because n=0 and "
1595 "RHS=" << RHS[i] << " and not an inequality"
1596 << endl;
1597 }
1598 return FALSE;
1599 }
1600 }
1601 }
1602 return TRUE;
1603 }
1604 for (i = 0; i < m; i++) {
1605 RHS1[i] = RHS[i];
1606 }
1607 sum1 = sum;
1608 //if (f_x_max) {
1609 total_max = 0;
1610 for (k = 0; k < n; k++) {
1611 total_max += x_max[k];
1612 }
1613 if (total_max < sum) {
1614 if (f_v) {
1615 cout << "diophant::solve_first_betten() total_max "
1616 << total_max << " < sum = " << sum
1617 << ", no solution" << endl;
1618 }
1619 return FALSE;
1620 }
1621 //}
1622
1623 //
1624 // compute gcd:
1625 //
1626 for (i = 0; i < m; i++) {
1627 if (type[i] == t_EQ) {
1628 if (n >= 2) {
1629 j = n - 2;
1630 g = Aij(i, n - 1);
1631 Gij(i, j) = g;
1632 j--;
1633 for (; j >= 0; j--) {
1634 g = NT.gcd_lint(Aij(i, j + 1), g);
1635 Gij(i, j) = g;
1636 }
1637 }
1638 Gij(i, n - 1) = 0;
1639 // in the last step: RHS1 cong 0 mod 0 means: RHS1 == 0
1640 }
1641 else {
1642 for (j = 0; j < n; j++) {
1643 Gij(i, j) = 0;
1644 }
1645 }
1646 }
1647
1648 for (j = 0; j < n; j++) {
1649 x[j] = 0;
1650 }
1651 if (f_vv) {
1652 cout << "diophant::solve_first_betten: gcd computed:" << endl;
1653 print2(TRUE);
1654 }
1655
1656 j = 0;
1657 while (TRUE) {
1658 while (TRUE) {
1659 if (j >= n) {
1660 if (f_v) {
1661 cout << "diophant::solve_first_betten solution" << endl;
1663 }
1664 return TRUE;
1665 }
1667 if ((nb_steps_betten % 1000000) == 0) {
1668 cout << "diophant::solve_first_betten nb_steps_betten="
1669 << nb_steps_betten << " sol=" << _resultanz << " ";
1670 if (f_max_time) {
1671 int t1 = Os.os_ticks();
1672 int dt = t1 - t0;
1673 int t = dt / Os.os_ticks_per_second();
1674 cout << "time in seconds: " << t;
1675 }
1676 cout << endl;
1678 if (f_max_time) {
1679 int t1 = Os.os_ticks();
1680 int dt = t1 - t0;
1681 if (dt > max_time_in_ticks) {
1683 return FALSE;
1684 }
1685 }
1686 }
1687#if 0
1688 if (nb_steps_betten == 51859) {
1689 verbose_level = 4;
1690 f_v = (verbose_level >= 1);
1691 f_vv = (verbose_level >= 2);
1692 }
1693#endif
1694 if (f_vv) {
1695 cout << "diophant::solve_first_betten j=" << j
1696 << " sum1=" << sum1 << " x:" << endl;
1698 cout << endl;
1699 }
1700 if (!j_fst(j, verbose_level - 2)) {
1701 break;
1702 }
1703 j++;
1704 }
1705 while (TRUE) {
1706 if (j == 0) {
1707 if (f_v) {
1708 cout << "diophant::solve_first_betten "
1709 "no solution" << endl;
1710 }
1711 return FALSE;
1712 }
1713 j--;
1715 if ((nb_steps_betten % 1000000) == 0) {
1716 cout << "diophant::solve_first_betten nb_steps_betten="
1717 << nb_steps_betten << " sol=" << _resultanz << " ";
1718 if (f_max_time) {
1719 int t1 = Os.os_ticks();
1720 int dt = t1 - t0;
1721 int t = dt / Os.os_ticks_per_second();
1722 cout << "time in seconds: " << t;
1723 }
1724 cout << endl;
1726 if (f_max_time) {
1727 int t1 = Os.os_ticks();
1728 int dt = t1 - t0;
1729 if (dt > max_time_in_ticks) {
1731 return FALSE;
1732 }
1733 }
1734 }
1735#if 0
1736 if (nb_steps_betten == 51859) {
1737 verbose_level = 4;
1738 f_v = (verbose_level >= 1);
1739 f_vv = (verbose_level >= 2);
1740 }
1741#endif
1742 if (f_vv) {
1743 cout << "diophant::solve_first_betten j=" << j
1744 << " sum1=" << sum1 << " x:" << endl;
1746 cout << endl;
1747 }
1748 if (j_nxt(j, verbose_level - 2)) {
1749 break;
1750 }
1751 }
1752 j++;
1753 }
1754}
1755
1756int diophant::solve_next_mckay(int verbose_level)
1757{
1758 int j;
1759 if (_cur_result < _resultanz) {
1760 for (j = 0; j < n; j++) {
1761 x[j] = _results.front()[j];
1762 }
1763 _results.pop_front();
1764 _cur_result++;
1765 return TRUE;
1766 }
1767 else {
1768 return FALSE;
1769 }
1770}
1771
1772int diophant::solve_next_betten(int verbose_level)
1773{
1774 int j;
1776
1777 if (!f_has_sum) {
1778 cout << "diophant::solve_next_betten !f_has_sum" << endl;
1779 exit(1);
1780 }
1781 if (m == 0) {
1782 return FALSE;
1783 }
1784 if (n == 0) {
1785 return FALSE;
1786 }
1787 j = n - 1;
1788 while (TRUE) {
1789 while (TRUE) {
1791 if ((nb_steps_betten % 1000000) == 0) {
1792 cout << "diophant::solve_next_betten nb_steps_betten="
1793 << nb_steps_betten << " sol=" << _resultanz << " ";
1794 if (f_max_time) {
1795 int t1 = Os.os_ticks();
1796 int dt = t1 - t0;
1797 int t = dt / Os.os_ticks_per_second();
1798 cout << "time in seconds: " << t;
1799 }
1800 cout << endl;
1802 if (f_max_time) {
1803 int t1 = Os.os_ticks();
1804 int dt = t1 - t0;
1805 if (dt > max_time_in_ticks) {
1807 return FALSE;
1808 }
1809 }
1810 }
1811 if (j_nxt(j, verbose_level)) {
1812 break;
1813 }
1814 if (j == 0) {
1815 return FALSE;
1816 }
1817 j--;
1818 }
1819 while (TRUE) {
1820 if (j >= n - 1) {
1821 return TRUE;
1822 }
1823 j++;
1825 if ((nb_steps_betten % 1000000) == 0) {
1826 cout << "diophant::solve_next_betten nb_steps_betten="
1827 << nb_steps_betten << " sol=" << _resultanz << " ";
1828 if (f_max_time) {
1829 int t1 = Os.os_ticks();
1830 int dt = t1 - t0;
1831 int t = dt / Os.os_ticks_per_second();
1832 cout << "time in seconds: " << t;
1833 }
1834 cout << endl;
1835 if (f_max_time) {
1836 int t1 = Os.os_ticks();
1837 int dt = t1 - t0;
1838 if (dt > max_time_in_ticks) {
1840 return FALSE;
1841 }
1842 }
1843 }
1844 if (!j_fst(j, verbose_level)) {
1845 break;
1846 }
1847 }
1848 j--;
1849 }
1850}
1851
1852int diophant::j_fst(int j, int verbose_level)
1853// if return value is FALSE,
1854// x[j] is 0 and RHS1[i] unchanged;
1855// otherwise RHS1[i] := RHS1[i] - lf->x[j] * lf->a[i][j]
1856// and RHS1[i] divisible by g[i][j]
1857// (or RHS1 == 0 if g[j] == 0)
1858// for all 0 <= i < n.
1859{
1860 int f_v = (verbose_level >= 1);
1861 int f_vv = (verbose_level >= 2);
1862 int i, ii, g, a, b;
1863
1864 if (f_v) {
1865 cout << "j_fst node=" << nb_steps_betten << " j=" << j << endl;
1866 }
1867 // max value for x[j]:
1868 x[j] = sum1;
1869 //if (f_x_max) {
1870 // with restriction:
1871 x[j] = MINIMUM(x[j], x_max[j]);
1872 //}
1873 if (f_vv) {
1874 cout << "diophant::j_fst j=" << j << " trying x[j]=" << x[j] << endl;
1875 }
1876 for (i = 0; i < m; i++) {
1877 if (x[j] == 0) {
1878 break;
1879 }
1880 a = Aij(i, j);
1881 if (a == 0) {
1882 continue;
1883 }
1884 // x[j] = MINIMUM(x[j], (RHS1[i] / a));
1885 b = RHS1[i] / a;
1886 if (b < x[j]) {
1887 if (f_vv) {
1888 char *label;
1889
1890 if (eqn_label[i]) {
1891 label = eqn_label[i];
1892 }
1893 else {
1894 label = NEW_char(1);
1895 label[0] = 0;
1896 }
1897 cout << "diophant::j_fst j=" << j << " reducing x[j] "
1898 "from " << x[j] << " to " << b
1899 << " because of equation " << i << " = "
1900 << label << endl;
1901 cout << "RHS1[i]=" << RHS1[i] << endl;
1902 cout << "a=" << a << endl;
1903 }
1904 x[j] = b;
1905 }
1906 }
1907 if (f_vv) {
1908 cout << "diophant::j_fst j=" << j << " trying "
1909 "x[j]=" << x[j] << endl;
1910 }
1911
1912 sum1 -= x[j];
1913 for (i = 0; i < m; i++) {
1914 RHS1[i] -= x[j] * A[i * n + j];
1915 }
1916 for (i = 0; i < m; i++) {
1917 if (RHS1[i] < 0) {
1918 cout << "diophant::j_fst(): RHS1[i] < 0" << endl;
1919 exit(1);
1920 }
1921 }
1922 // RHS1[] non negative now
1923 if (f_vv) {
1924 cout << "diophant::j_fst: x[" << j << "] = " << x[j] << endl;
1925 }
1926
1927 if (j == n - 1) {
1928 // now have to check if the
1929 // current vector x[] is in fact a
1930 // solution;
1931 // this means:
1932 // a) if eqn i is an inequation:
1933 // no restriction
1934 // b) if eqn i is an equation:
1935 // RHS[i] must be 0
1936 //
1937 for (i = 0; i < m; i++) {
1938 if (type[i] == t_LE) {
1939 continue;
1940 }
1941 if (RHS1[i] != 0) {
1942 break; // no solution
1943 }
1944 }
1945 if (i < m || sum1 > 0) {
1946 // cout << "no solution !" << endl;
1947
1948 // not passed, go back */
1949 // NOTE: we CAN go back here
1950 // in any case; reason:
1951 // if we decrement x[n - 1]
1952 // than sum1 will be positive
1953 // and this cannot be a solution.
1954 for (ii = 0; ii < m; ii++) {
1955 RHS1[ii] += x[j] * A[ii * n + j];
1956 }
1957 sum1 += x[j];
1958 x[j] = 0;
1959 if (f_vv) {
1960 cout << "diophant::j_fst no solution b/c RHS[i] "
1961 "nonzero || sum1 > 0" << endl;
1962 cout << "i=" << i << endl;
1963 cout << "j=" << j << " = n - 1" << endl;
1964 cout << "n=" << n << endl;
1965 cout << "RHS1[i]=" << RHS1[i] << endl;
1966 cout << "sum1=" << sum1 << endl;
1967 cout << "m=" << m << endl;
1969 }
1970 return FALSE;
1971 }
1972 return TRUE;
1973 }
1974
1975 while (TRUE) {
1976 // check gcd restrictions:
1977 for (i = 0; i < m; i++) {
1978 if (type[i] == t_LE) {
1979 continue;
1980 // it is an inequality, hence no gcd condition
1981 }
1982 g = G[i * n + j];
1983 if (g == 0 && RHS1[i] != 0) {
1984 if (f_vv) {
1985 char *label;
1986
1987 if (eqn_label[i]) {
1988 label = eqn_label[i];
1989 }
1990 else {
1991 label = (char *) "";
1992 }
1993 cout << "diophant::j_fst g == 0 && RHS1[i] != 0 in "
1994 "eqn i=" << i << " = " << label << endl;
1995 cout << "g=" << g << endl;
1996 cout << "i=" << i << endl;
1997 cout << "j=" << j << " != n - 1" << endl;
1998 cout << "n=" << n << endl;
1999 cout << "RHS1[i]=" << RHS1[i] << endl;
2001 }
2002 break;
2003 }
2004 if (g == 0) {
2005 continue;
2006 }
2007 if (g == 1) {
2008 // no restriction
2009 continue;
2010 }
2011 if ((RHS1[i] % g) != 0) {
2012 if (f_vv) {
2013 char *label;
2014
2015 if (eqn_label[i]) {
2016 label = eqn_label[i];
2017 }
2018 else {
2019 label = (char *) "";
2020 }
2021 cout << "diophant::j_fst (RHS1[i] % g) != 0 in "
2022 "equation i=" << i << " = " << label << endl;
2023 cout << "g=" << g << endl;
2024 cout << "i=" << i << endl;
2025 cout << "j=" << j << " != n - 1" << endl;
2026 cout << "n=" << n << endl;
2027 cout << "RHS1[i]=" << RHS1[i] << endl;
2029 }
2030 break;
2031 }
2032 }
2033 if (i == m) { // OK
2034 break;
2035 }
2036
2037 if (f_vv) {
2038 cout << "gcd test failed !" << endl;
2039 }
2040 // was not OK
2041 if (x[j] == 0) {
2042 if (f_vv) {
2043 char *label;
2044
2045 if (eqn_label[i]) {
2046 label = eqn_label[i];
2047 }
2048 else {
2049 label = (char *) "";
2050 }
2051 cout << "diophant::j_fst no solution b/c gcd test "
2052 "failed in equation " << i << " = " << label << endl;
2053 cout << "j=" << j << endl;
2054 cout << "x[j]=" << x[j] << endl;
2055 cout << "RHS1[i]=" << RHS1[i] << endl;
2056 cout << "Gij(i,j)=" << Gij(i,j) << endl;
2058 }
2059 return FALSE;
2060 }
2061 x[j]--;
2062 sum1++;
2063 for (ii = 0; ii < m; ii++) {
2064 RHS1[ii] += A[ii * n + j];
2065 }
2066 if (f_vv) {
2067 cout << "diophant::j_fst() decrementing to: x[" << j
2068 << "] = " << x[j] << endl;
2069 }
2070 }
2071 return TRUE;
2072}
2073
2074int diophant::j_nxt(int j, int verbose_level)
2075{
2076 int f_v = (verbose_level >= 1);
2077 int f_vv = (verbose_level >= 2);
2078 int i, ii, g;
2079
2080 if (f_v) {
2081 cout << "j_nxt node=" << nb_steps_betten << " j=" << j << endl;
2082 }
2083 if (j == n - 1) {
2084 for (ii = 0; ii < m; ii++) {
2085 RHS1[ii] += x[j] * A[ii * n + j];
2086 }
2087 sum1 += x[j];
2088 x[j] = 0;
2089 if (f_vv) {
2090 cout << "diophant::j_nxt no solution b/c j == n - 1" << endl;
2091 cout << "j=" << j << endl;
2092 cout << "n=" << n << endl;
2094 }
2095 return FALSE;
2096 }
2097
2098 while (x[j] > 0) {
2099 x[j]--;
2100 if (f_vv) {
2101 cout << "diophant::j_nxt() decrementing to: x[" << j
2102 << "] = " << x[j] << endl;
2103 }
2104 sum1++;
2105 for (ii = 0; ii < m; ii++) {
2106 RHS1[ii] += A[ii * n + j];
2107 }
2108
2109 // check gcd restrictions:
2110 for (i = 0; i < m; i++) {
2111 if (type[i] == t_LE) {
2112 continue;
2113 // it is an inequality, hence no gcd condition
2114 }
2115 g = G[i * n + j];
2116 if (g == 0 && RHS1[i] != 0) {
2117 break;
2118 }
2119 if (g == 0) {
2120 continue;
2121 }
2122 if (g == 1) {
2123 // no restriction
2124 continue;
2125 }
2126 if ((RHS1[i] % g) != 0) {
2127 break;
2128 }
2129 }
2130 if (i == m) {
2131 // OK
2132 return TRUE;
2133 }
2134 if (f_vv) {
2135 char *label;
2136
2137 if (eqn_label[i]) {
2138 label = eqn_label[i];
2139 }
2140 else {
2141 label = (char *) "";
2142 }
2143 cout << "diophant::j_nxt() gcd restriction failed in "
2144 "eqn " << i << " = " << label << endl;
2145 }
2146 }
2147 if (f_vv) {
2148 cout << "diophant::j_nxt no solution b/c gcd test failed" << endl;
2149 cout << "j=" << j << endl;
2151 }
2152 return FALSE;
2153}
2154
2155void diophant::solve_mckay(const char *label, int maxresults,
2156 long int &nb_backtrack_nodes, int &nb_sol, int verbose_level)
2157{
2158 int f_v = (verbose_level >= 1);
2159
2160 if (f_v) {
2161 cout << "diophant::solve_mckay" << endl;
2162 }
2164 maxresults, nb_backtrack_nodes, 0 /* minrhs */, nb_sol,
2165 verbose_level);
2166 if (f_v) {
2167 cout << "diophant::solve_mckay done" << endl;
2168 }
2169}
2170
2172 const char *label,
2173 int maxresults, long int &nb_backtrack_nodes,
2174 int minrhs, int &nb_sol, int verbose_level)
2175{
2176 int f_v = (verbose_level >= 1);
2177 int i, j, nb;
2178 vector<int> minres, maxres, fanz;
2179 mckay::tMCKAY lgs;
2180 vector<mckay::equation> eqn;
2181 map<int, int>::iterator it;
2182 vector<int> minvarvalue;
2183 vector<int> maxvarvalue;
2184
2185 if (f_v) {
2186 cout << "diophant::solve_mckay_override_minrhs_in_inequalities "
2187 << label << ", a system "
2188 "of size " << m << " x " << n << endl;
2189 }
2190
2191 int nb_eqns;
2192
2193 if (f_has_sum) {
2194 nb_eqns= m + 1;
2195 }
2196 else {
2197 nb_eqns = m;
2198 }
2199
2200 lgs.Init(this, label, nb_eqns, n);
2201 minres.resize(nb_eqns);
2202 maxres.resize(nb_eqns);
2203 fanz.resize(m + 1);
2204 eqn.resize(m + 1);
2205
2206 for (i = 0; i < m; i++) {
2207 // the RHS:
2208 if (type[i] == t_EQ) {
2209 minres[i] = (int) RHS[i];
2210 maxres[i] = (int) RHS[i];
2211 }
2212 else if (type[i] == t_LE) {
2213 minres[i] = (int) minrhs;
2214 maxres[i] = (int) RHS[i];
2215 }
2216 else if (type[i] == t_INT) {
2217 minres[i] = (int) RHS_low[i];
2218 maxres[i] = (int) RHS[i];
2219 }
2220 else if (type[i] == t_ZOR) {
2221 minres[i] = (int) 0;
2222 maxres[i] = (int) RHS[i];
2223 }
2224 else {
2225 cout << "diophant::solve_mckay_override_minrhs_in_inequalities "
2226 "we cannot do this type of "
2227 "condition, equation " << i << endl;
2228 exit(1);
2229 }
2230
2231 // count the number of nonzero coefficients:
2232 nb = 0;
2233 for (j = 0; j < n; j++) {
2234 if (A[i * n + j]) {
2235 nb++;
2236 }
2237 }
2238
2239 // initialize coefficients:
2240 fanz[i] = nb;
2241 eqn[i].resize(nb);
2242 nb = 0;
2243 for (j = 0; j < n; j++) {
2244 if (A[i * n + j]) {
2245 eqn[i][nb].var = j;
2246 eqn[i][nb].coeff = (int) A[i * n + j];
2247 nb++;
2248 }
2249 }
2250 } // next i
2251
2252 if (f_has_sum) {
2253 // one more equation for \sum x_j = sum
2254 i = (int) m;
2255 fanz[i] = (int) n;
2256 eqn[i].resize(n);
2257 for (j = 0; j < n; j++) {
2258 eqn[i][j].var = j;
2259 eqn[i][j].coeff = 1;
2260 }
2261 minres[i] = (int) sum;
2262 maxres[i] = (int) sum;
2263 }
2264
2265 // now the bounds on the x_j
2266 minvarvalue.resize(n);
2267 maxvarvalue.resize(n);
2268
2269 if (f_v) {
2270 cout << "diophant::solve_mckay_override_minrhs_in_inequalities "
2271 "f_x_max=true" << endl;
2272 cout << "x_max=";
2273 Int_vec_print(cout, x_max, n);
2274 cout << endl;
2275 cout << "x_min=";
2276 Int_vec_print(cout, x_min, n);
2277 cout << endl;
2278 }
2279 for (j = 0; j < n; j++) {
2280 minvarvalue[j] = (int) x_min[j];
2281 maxvarvalue[j] = (int) x_max[j];
2282 }
2283
2284#if 0
2285 else {
2286 if (f_v) {
2287 cout << "diophant::solve_mckay_override_minrhs_in_inequalities "
2288 "f_x_max=false initializing with " << INT_MAX << endl;
2289 }
2290 for (j = 0; j < n; j++) {
2291 minvarvalue[j] = 0;
2292 maxvarvalue[j] = (int) INT_MAX;
2293 }
2294 }
2295#endif
2296
2297 // trying to restrict maxvarvalue[]:
2298 int b;
2299 for (i = 0; i < m; i++) {
2300 if (f_v) {
2301 cout << "trying to restrict using of equation " << i << endl;
2302 }
2303 for (j = 0; j < n; j++) {
2304 if (A[i * n + j]) {
2305
2306 b = RHS[i] / A[i * n + j];
2307
2308 if (b < maxvarvalue[j]) {
2309 if (f_v) {
2310 cout << "lowering maxvarvalue[" << j << "] from "
2311 << maxvarvalue[j] << " to " << b
2312 << " because of equation " << i << endl;
2313 }
2314 maxvarvalue[j] = b;
2315 }
2316 }
2317 }
2318 }
2319 if (f_v) {
2320 cout << "after restrictions:" << endl;
2321 print_dense();
2322 }
2323
2324 if (f_v) {
2325 cout << "diophant::solve_mckay_override_minrhs_in_inequalities "
2326 "maxvarvalue=" << endl;
2327 for (j = 0; j < n; j++) {
2328 cout << j << " : " << maxvarvalue[j] << endl;
2329 }
2330 }
2331 _resultanz = 0;
2332 _maxresults = (int) maxresults;
2333
2334 lgs.possolve(minvarvalue, maxvarvalue,
2335 eqn, minres, maxres, fanz,
2336 nb_eqns, n,
2337 verbose_level);
2338 nb_backtrack_nodes = lgs.nb_calls_to_solve;
2339 nb_sol = _resultanz;
2340 if (f_v) {
2341 cout << "diophant::solve_mckay_override_minrhs_in_inequalities "
2342 << label << " finished, "
2343 "number of solutions = " << _resultanz
2344 << " nb_backtrack_nodes=" << nb_backtrack_nodes << endl;
2345 }
2346}
2347
2349{
2350 latex_it(cout);
2351}
2352
2353void diophant::latex_it(ostream &ost)
2354{
2355 int i, j, a;
2356
2357 ost << "\\begin{array}{|*{" << n << "}{r}|r|l|}" << endl;
2358#if 0
2359 ost << "\\hline" << endl;
2360 //ost << " & ";
2361 for (j = 0; j < n; j++) {
2362 ost << setw(2) << (int)(j / 10) << " & ";
2363 }
2364 ost << " & & \\\\" << endl;
2365 ost << " & ";
2366 for (j = 0; j < n; j++) {
2367 ost << setw(2) << j % 10 << " & ";
2368 }
2369 ost << " & & \\\\" << endl;
2370 if (f_x_max) {
2371 //ost << " & ";
2372 for (j = 0; j < n; j++) {
2373 ost << setw(2) << (int)(x_max[j] / 10) << " & ";
2374 }
2375 ost << " & & \\\\" << endl;
2376 ost << " & ";
2377 for (j = 0; j < n; j++) {
2378 ost << setw(2) << x_max[j] % 10 << " & ";
2379 }
2380 ost << " & & \\\\" << endl;
2381 }
2382 ost << "\\hline" << endl;
2383#endif
2384 ost << "\\hline" << endl;
2385 for (i = 0; i < m; i++) {
2386 //ost << setw(2) << i << " & ";
2387 for (j = 0; j < n; j++) {
2388 a = Aij(i, j);
2389 ost << setw(2) << a << " & ";
2390 }
2391 if (type[i] == t_EQ) {
2392 ost << " = " << setw(2) << RHS[i] << " & ";
2393 }
2394 else if (type[i] == t_LE) {
2395 ost << " \\le " << setw(2) << RHS[i] << " & ";
2396 }
2397 else if (type[i] == t_INT) {
2398 ost << " \\in [" << setw(2) << RHS_low[i] << "," << setw(2) << RHS[i] << "] & ";
2399 }
2400 else if (type[i] == t_ZOR) {
2401 ost << " ZOR " << setw(2) << RHS[i] << " & ";
2402 }
2403 if (eqn_label[i]) {
2404 ost << eqn_label[i];
2405 }
2406 ost << "\\\\" << endl;
2407 }
2408 ost << "\\hline" << endl;
2409 //if (f_x_max) {
2410 ost << "\\multicolumn{" << n + 2 << "}{|c|}{" << endl;
2411 ost << "\\mbox{subject to:}" << endl;
2412 ost << "}\\\\" << endl;
2413 ost << "\\hline" << endl;
2414 ost << "\\multicolumn{" << n + 2 << "}{|l|}{" << endl;
2415 for (j = 0; j < n; j++) {
2416 ost << x_min[j] << " \\le x_{" << j + 1 << "} \\le " << x_max[j] << "\\," << endl;
2417 }
2418 if (f_has_sum) {
2419 ost << "\\sum_{i=1}^{" << n << "} x_i=" << sum << endl;
2420 }
2421 ost << "}\\\\" << endl;
2422 ost << "\\hline" << endl;
2423 //}
2424 ost << "\\end{array}" << endl;
2425}
2426
2428 int &f_no_solution, int verbose_level)
2429{
2430 int f_v = (verbose_level >= 1);
2431 int i, d, m1;
2432 int f_trivial;
2433
2434 if (f_v) {
2435 cout << "diophant::trivial_row_reductions" << endl;
2436 }
2437 m1 = m;
2438 f_no_solution = FALSE;
2439 for (i = m - 1; i >= 0; i--) {
2440 f_trivial = FALSE;
2442 if (type[i] == t_LE) {
2443 if (d <= RHS[i]) {
2444 f_trivial = FALSE; // this is only valid if x_max = 1
2445 }
2446 }
2447 else if (type[i] == t_INT) {
2448 if (d <= RHS[i]) {
2449 f_trivial = FALSE; // this is only valid if x_max = 1
2450 }
2451 }
2452 else if (type[i] == t_EQ) {
2453 if (RHS[i] > d) {
2454 f_no_solution = FALSE; // this is only valid if x_max = 1
2455 }
2456 }
2457 if (f_trivial) {
2458 delete_equation(i);
2459 }
2460 }
2461 if (f_v) {
2462 cout << "diophant::trivial_row_reductions done, eliminated "
2463 << m1 - m << " equations" << endl;
2464 }
2465}
2466
2468{
2469 int f_v = (verbose_level >= 1);
2470 int i, j, h, a, rhs;
2471 int *f_deleted;
2472 int *col_idx;
2473 int nb_deleted;
2474
2475 if (f_v) {
2476 cout << "diophant::trivial_column_reductions" << endl;
2477 }
2478 f_deleted = NEW_int(n);
2479 col_idx = NEW_int(n);
2480 Int_vec_zero(f_deleted, n);
2481 Int_vec_zero(col_idx, n);
2482 for (j = 0; j < n; j++) {
2483 col_idx[j] = -1;
2484 }
2485 for (i = 0; i < m; i++) {
2486 if (type[i] == t_EQ) {
2487 rhs = RHS[i];
2488 for (j = 0; j < n; j++) {
2489 a = Aij(i, j);
2490 if (a > rhs) {
2491 f_deleted[j] = TRUE;
2492 }
2493 }
2494 }
2495 }
2496 for (j = 0; j < n; j++) {
2497 cout << f_deleted[j];
2498 }
2499 cout << endl;
2500 nb_deleted = 0;
2501 h = 0;
2502 for (j = 0; j < n; j++) {
2503 if (f_deleted[j]) {
2504 nb_deleted++;
2505 }
2506 else {
2507 col_idx[j] = h;
2508 h++;
2509 }
2510 }
2511 if (f_v) {
2512 cout << "diophant::trivial_column_reductions nb_deleted = " << nb_deleted << endl;
2513 cout << "col_idx=";
2514 Int_vec_print(cout, col_idx, n);
2515 cout << endl;
2516 }
2517
2518
2519 diophant *D2;
2520
2521 D2 = NEW_OBJECT(diophant);
2522 D2->open(m, n - nb_deleted);
2523 D2->f_has_sum = f_has_sum;
2524 D2->sum = sum;
2525 //D2->f_x_max = f_x_max;
2526 D2->f_has_var_labels = TRUE;
2527 D2->var_labels = NEW_int(n - nb_deleted);
2528 for (i = 0; i < m; i++) {
2529 D2->type[i] = type[i];
2530 D2->RHS[i] = RHS[i];
2531 for (j = 0; j < n; j++) {
2532 if (f_deleted[j]) {
2533 }
2534 else {
2535 h = col_idx[j];
2536 D2->Aij(i, h) = Aij(i, j);
2537 }
2538 }
2539 }
2540 for (j = 0; j < n; j++) {
2541 if (f_deleted[j]) {
2542 }
2543 else {
2544 h = col_idx[j];
2545 D2->var_labels[h] = j;
2546 D2->x_max[h] = x_max[j];
2547 D2->x_min[h] = x_min[j];
2548 }
2549 }
2550 FREE_int(f_deleted);
2551 FREE_int(col_idx);
2552
2553 return D2;
2554
2555}
2556
2558{
2559 int j, d, a;
2560
2561 d = 0;
2562 for (j = 0; j < n; j++) {
2563 a = Aij(i, j);
2564 if (a) {
2565 d++;
2566 }
2567 }
2568 return d;
2569}
2570
2571void diophant::coefficient_values_in_row(int i, int &nb_values,
2572 int *&values, int *&multiplicities, int verbose_level)
2573{
2574 int f_v = (verbose_level >= 1);
2575 int a, j, k, idx;
2577
2578 if (f_v) {
2579 cout << "diophant::coefficient_values_in_row" << endl;
2580 }
2581 nb_values = 0;
2582 values = NEW_int(n);
2583 multiplicities = NEW_int(n);
2584 for (j = 0; j < n; j++) {
2585 a = Aij(i, j);
2586 if (a) {
2587 if (!Sorting.int_vec_search(values, nb_values, a, idx)) {
2588 for (k = nb_values; k > idx; k--) {
2589 values[k] = values[k - 1];
2590 multiplicities[k] = multiplicities[k - 1];
2591 }
2592 values[idx] = a;
2593 multiplicities[idx] = 1;
2594 nb_values++;
2595 }
2596 else {
2597 multiplicities[idx]++;
2598 }
2599 }
2600 }
2601
2602}
2603
2605{
2606 int i, d_max = 0, d;
2607
2608 for (i = 0; i < m; i++) {
2610 d_max = MAXIMUM(d, d_max);
2611 }
2612 return d_max;
2613}
2614
2616 int &nb_rows, int &nb_cols, int verbose_level)
2617{
2618 int f_v = (verbose_level >= 1);
2619 int i, j;
2620
2621 if (f_v) {
2622 cout << "diophant::get_coefficient_matrix" << endl;
2623 }
2624 nb_rows = m;
2625 nb_cols = n;
2626 M = NEW_int(m * n);
2627 for (i = 0; i < m; i++) {
2628 for (j = 0; j < n; j++) {
2629 M[i * n + j] = Aij(i, j);
2630 }
2631 }
2632 if (f_v) {
2633 cout << "diophant::get_coefficient_matrix done" << endl;
2634 }
2635}
2636
2637#if 0
2638void diophant::save_as_Levi_graph(std::string &fname, int verbose_level)
2639{
2640 int f_v = (verbose_level >= 1);
2641
2642 if (f_v) {
2643 cout << "diophant::save_as_Levi_graph" << endl;
2644 }
2645
2646 {
2647 colored_graph *CG;
2648 int *M;
2649 int nb_rows, nb_cols;
2650
2651 if (f_v) {
2652 cout << "diophant::save_as_Levi_graph before create_Levi_graph_"
2653 "from_coefficient_matrix" << endl;
2654 }
2655
2656 get_coefficient_matrix(M, nb_rows, nb_cols, verbose_level - 1);
2657
2658 CG = NEW_OBJECT(colored_graph);
2659
2660 CG->create_Levi_graph_from_incidence_matrix(
2661 M, nb_rows, nb_cols,
2662 FALSE /* f_point_labels */,
2663 NULL /* *point_labels */,
2664 verbose_level);
2665 if (f_v) {
2666 cout << "diophant::save_as_Levi_graph after create_Levi_graph_"
2667 "from_coefficient_matrix" << endl;
2668 }
2669 CG->save(fname, verbose_level);
2670 FREE_OBJECT(CG);
2671 }
2672
2673 if (f_v) {
2674 cout << "diophant::save_as_Levi_graph done" << endl;
2675 }
2676}
2677#endif
2678
2679#if 0
2680void diophant::save_in_compact_format(const char *fname, int verbose_level)
2681{
2682 int f_v = (verbose_level >= 1);
2683 int i, j, a, d;
2684 file_io Fio;
2685
2686 if (f_v) {
2687 cout << "diophant::save_in_compact_format" << endl;
2688 }
2689 for (i = 0; i < m; i++) {
2690 for (j = 0; j < n; j++) {
2691 a = Aij(i, j);
2692 if (a > 1) {
2693 cout << "diophant::save_in_compact_format coefficient "
2694 "matrix must be 0/1" << endl;
2695 exit(1);
2696 }
2697 }
2698 }
2699 {
2700 ofstream fp(fname);
2701
2702 fp << "% " << fname << endl;
2703 fp << m << " " << n << " " << f_has_sum << " " << sum << endl;
2704 for (i = 0; i < m; i++) {
2705 fp << i << " ";
2706 if (type[i] == t_EQ) {
2707 fp << "EQ" << " " << RHS[i];
2708 }
2709 else if (type[i] == t_LE) {
2710 fp << "LE" << " " << RHS[i];
2711 }
2712 else if (type[i] == t_INT) {
2713 fp << "INT" << " " << RHS_low[i] << " " << RHS[i];
2714 }
2715 else if (type[i] == t_ZOR) {
2716 fp << "ZOR" << " " << RHS[i];
2717 }
2718
2720
2721 fp << " " << d;
2722 for (j = 0; j < n; j++) {
2723 a = Aij(i, j);
2724 if (a) {
2725 fp << " " << j;
2726 }
2727 }
2728 fp << endl;
2729 }
2730 fp << "END" << endl;
2731 }
2732 if (f_v) {
2733 cout << "diophant::save_in_compact_format done, " << endl;
2734 cout << "written file " << fname << " of size "
2735 << Fio.file_size(fname) << endl;
2736 }
2737}
2738
2739void diophant::read_compact_format(const char *fname, int verbose_level)
2740{
2741 int f_v = (verbose_level >= 1);
2742 int m, n, s;
2743 int cnt, i, d, h, a;
2744 int f_has_sum1;
2745
2746 if (f_v) {
2747 cout << "diophant::read_compact_format" << endl;
2748 }
2749 string line;
2750 string EQ("EQ");
2751 string LE("LE");
2752 string INT("INT");
2753 string ZOR("ZOR");
2754 {
2755 ifstream myfile (fname);
2756 if (myfile.is_open()) {
2757 getline (myfile, line); // file name
2758 getline (myfile, line); // m n sum
2759
2760 i = line.find(" ");
2761
2762 string str = line.substr(0, i);
2763 string remainder = line.substr(i + 1);
2764
2765 //cout << "substring ='" << str << "'" << endl;
2766 m = atoi(str.c_str()); // stoi(str) is C++11
2767 //cout << "remainder ='" << remainder << "'" << endl;
2768 i = remainder.find(" ");
2769 str = remainder.substr(0, i);
2770 //cout << "substring ='" << str << "'" << endl;
2771 n = atoi(str.c_str());
2772 string remainder2 = remainder.substr(i + 1);
2773
2774 i = remainder2.find(" ");
2775 str = remainder2.substr(0, i);
2776 //cout << "substring ='" << str << "'" << endl;
2777 f_has_sum1 = atoi(str.c_str());
2778
2779 str = remainder2.substr(i + 1);
2780 s = atoi(str.c_str());
2781 //cout << "diophant::read_compact_format m=" << m << " n=" << n << " sum=" << s << endl;
2782
2783
2784 open(m, n);
2785 f_has_sum = f_has_sum1;
2786 sum = s;
2787
2788
2789 for (cnt = 0; cnt < m; cnt++) {
2790 getline (myfile, line);
2791 i = line.find(" ");
2792 remainder = line.substr(i + 1);
2793 line = remainder;
2794 //cout << "remainder = '" << remainder << "'" << endl;
2795 i = line.find(" ");
2796 str = line.substr(0, i);
2797 remainder = line.substr(i + 1);
2798 line = remainder;
2799 if (str.compare(EQ) == 0) {
2800 //cout << "equal" << endl;
2801 type[cnt] = t_EQ;
2802 }
2803 else if (str.compare(LE) == 0) {
2804 //cout << "less than or equal" << endl;
2805 type[cnt] = t_LE;
2806 }
2807 else if (str.compare(INT) == 0) {
2808 //cout << "interval" << endl;
2809 type[cnt] = t_INT;
2810 }
2811 else if (str.compare(ZOR) == 0) {
2812 //cout << "less than or equal" << endl;
2813 type[cnt] = t_ZOR;
2814 }
2815 else {
2816 cout << "cannot find EQ or LE or ZOR" << endl;
2817 exit(1);
2818 }
2819 //cout << "remainder = '" << line << "'" << endl;
2820 i = line.find(" ");
2821 str = line.substr(0, i);
2822 remainder = line.substr(i + 1);
2823 line = remainder;
2824 RHSi(cnt) = atoi(str.c_str());
2825 //cout << "rhs = " << RHS[cnt] << endl;
2826 //cout << "remainder = '" << line << "'" << endl;
2827
2828 if (type[cnt] == t_INT) {
2829 RHS_low_i(cnt) = RHSi(cnt);
2830 i = line.find(" ");
2831 str = line.substr(0, i);
2832 remainder = line.substr(i + 1);
2833 line = remainder;
2834 RHSi(cnt) = atoi(str.c_str());
2835 }
2836
2837 i = line.find(" ");
2838 str = line.substr(0, i);
2839 d = atoi(str.c_str());
2840 remainder = line.substr(i + 1);
2841 line = remainder;
2842
2843 //cout << "d = " << d << endl;
2844 for (h = 0; h < d; h++) {
2845 i = line.find(" ");
2846 str = line.substr(0, i);
2847 a = atoi(str.c_str());
2848 remainder = line.substr(i + 1);
2849 line = remainder;
2850 Aij(cnt, a) = 1;
2851 }
2852
2853
2854 } // next cnt
2855 //cout << "read " << cnt << " lines" << endl;
2856
2857#if 0
2858 while ( getline (myfile, line) ) {
2859 cout << line << '\n';
2860
2861 }
2862#endif
2863 myfile.close();
2864 }
2865 else {
2866 cout << "Cannot open file " << fname << endl;
2867 exit(1);
2868 }
2869
2870 if (f_v) {
2871 cout << "diophant::read_compact_format read system with " << m
2872 << " rows and " << n << " columns and f_has_sum = " << f_has_sum
2873 << " and sum " << sum << endl;
2874 }
2875 }
2876}
2877#endif
2878
2879void diophant::save_in_general_format(std::string &fname, int verbose_level)
2880// ToDo this does not save the values of x_min[] and x_max[]
2881{
2882 int f_v = (verbose_level >= 1);
2883 int i, j, a, d, h, val;
2886
2887 if (f_v) {
2888 cout << "diophant::save_in_general_format" << endl;
2889 }
2890
2891#if 0
2892 for (i = 0; i < m; i++) {
2893 for (j = 0; j < n; j++) {
2894 a = Aij(i, j);
2895 if (a > 1) {
2896 cout << "diophant::save_in_general_format coefficient "
2897 "matrix must be 0/1" << endl;
2898 exit(1);
2899 }
2900 }
2901 }
2902#endif
2903
2904 std::string fname_coeff;
2905 std::string fname_RHS;
2906 std::string fname_x_bounds;
2907
2908 fname_coeff.assign(fname);
2909 fname_RHS.assign(fname);
2910 fname_x_bounds.assign(fname);
2911 //strcpy(fname_coeff, fname);
2912 //strcpy(fname_RHS, fname);
2913 //strcpy(fname_x_bounds, fname);
2914
2915 ST.replace_extension_with(fname_coeff, "_coeff_matrix.csv");
2916 ST.replace_extension_with(fname_RHS, "_RHS.csv");
2917 ST.replace_extension_with(fname_x_bounds, "_x_bounds.csv");
2918
2919 Fio.int_matrix_write_csv(fname_coeff, A, m, n);
2920 if (f_v) {
2921 cout << "diophant::save_in_general_format written file " << fname_coeff << " of size "
2922 << Fio.file_size(fname_coeff) << endl;
2923 }
2924
2925 int *RHS_coded;
2926 RHS_coded = NEW_int(m * 3);
2927 for (i = 0; i < m; i++) {
2928 RHS_coded[3 * i + 0] = RHS_low[i];
2929 RHS_coded[3 * i + 1] = RHS[i];
2930 if (type[i] == t_EQ) {
2931 RHS_coded[3 * i + 0] = RHS[i];
2932 RHS_coded[3 * i + 2] = 1;
2933 }
2934 else if (type[i] == t_LE) {
2935 RHS_coded[3 * i + 2] = 2;
2936 }
2937 else if (type[i] == t_INT) {
2938 RHS_coded[3 * i + 2] = 3;
2939 }
2940 else if (type[i] == t_ZOR) {
2941 RHS_coded[3 * i + 2] = 4;
2942 }
2943 else {
2944 cout << "type[i] is not recognized" << endl;
2945 exit(1);
2946 }
2947 }
2948 Fio.int_matrix_write_csv(fname_RHS, RHS_coded, m, 3);
2949 if (f_v) {
2950 cout << "diophant::save_in_general_format written file " << fname_RHS << " of size "
2951 << Fio.file_size(fname_RHS) << endl;
2952 }
2953 FREE_int(RHS_coded);
2954
2955 int *X_bounds;
2956 X_bounds = NEW_int(n * 2);
2957 for (j = 0; j < n; j++) {
2958 X_bounds[2 * j + 0] = x_min[j];
2959 X_bounds[2 * j + 1] = x_max[j];
2960 }
2961
2962 Fio.int_matrix_write_csv(fname_x_bounds, X_bounds, n, 2);
2963 FREE_int(X_bounds);
2964 if (f_v) {
2965 cout << "diophant::save_in_general_format written file " << fname_x_bounds << " of size "
2966 << Fio.file_size(fname_x_bounds) << endl;
2967 }
2968
2969 {
2970 ofstream fp(fname);
2971
2972 fp << "% diophantine system in general format " << fname << endl;
2973 fp << m << " " << n << " " << f_has_sum << " " << sum << " "
2974 << f_has_var_labels << endl;
2975 if (f_has_var_labels) {
2976 for (j = 0; j < n; j++) {
2977 fp << var_labels[j] << " ";
2978 }
2979 fp << endl;
2980 }
2981 for (i = 0; i < m; i++) {
2982 fp << i << " ";
2983 if (type[i] == t_EQ) {
2984 fp << "EQ" << " " << RHS[i];
2985 }
2986 else if (type[i] == t_LE) {
2987 fp << "LE" << " " << RHS[i];
2988 }
2989 else if (type[i] == t_INT) {
2990 fp << "INT" << " " << RHS_low[i] << " " << RHS[i];
2991 }
2992 else if (type[i] == t_ZOR) {
2993 fp << "ZOR" << " " << RHS[i];
2994 }
2995
2996
2997 int nb_values;
2998 int *values, *multiplicities;
2999 int d1;
3000
3001
3002 coefficient_values_in_row(i, nb_values,
3003 values, multiplicities, 0 /*verbose_level*/);
3004
3005
3006 //d = count_non_zero_coefficients_in_row(i);
3007
3008 fp << " " << nb_values;
3009 for (h = 0; h < nb_values; h++) {
3010 val = values[h];
3011 d = multiplicities[h];
3012 fp << " " << val;
3013 fp << " " << d;
3014 d1 = 0;
3015 for (j = 0; j < n; j++) {
3016 a = Aij(i, j);
3017 if (a == val) {
3018 fp << " " << j;
3019 d1++;
3020 }
3021 }
3022 if (d1 != d) {
3023 cout << "d1 != d" << endl;
3024 cout << "i=" << i << endl;
3025 cout << "val=" << val << endl;
3026 cout << "d=" << d << endl;
3027 cout << "d1=" << d1 << endl;
3028 exit(1);
3029 }
3030 }
3031 fp << endl;
3032
3033 FREE_int(values);
3034 FREE_int(multiplicities);
3035
3036 }
3037 for (j = 0; j < n; j++) {
3038 fp << x_min[j] << " " << x_max[j] << endl;
3039 }
3040 fp << "END" << endl;
3041 }
3042 if (f_v) {
3043 cout << "diophant::save_in_general_format done, " << endl;
3044 cout << "written file " << fname << " of size "
3045 << Fio.file_size(fname) << endl;
3046 }
3047}
3048
3049void diophant::read_general_format(std::string &fname, int verbose_level)
3050{
3051 int f_v = (verbose_level >= 1);
3052 int f_vv = FALSE; //(verbose_level >= 1);
3053 int m, n, s;
3054 int cnt, i, j, d, h, a, nb_types, t, val;
3055 int f_has_sum1;
3056 int f_has_var_labels_save = FALSE;
3057
3058 if (f_v) {
3059 cout << "diophant::read_general_format" << endl;
3060 }
3061 string line;
3062 string EQ("EQ");
3063 string LE("LE");
3064 string INT("INT");
3065 string ZOR("ZOR");
3066 {
3067 ifstream myfile (fname);
3068 if (myfile.is_open()) {
3069 if (f_vv) {
3070 cout << "diophant::read_general_format" << endl;
3071 }
3072 getline (myfile, line); // file name
3073
3074
3075 //cout << "diophant::read_general_format parsing '" << line << "'" << endl;
3076 getline (myfile, line); // m n sum
3077
3078 i = line.find(" ");
3079
3080 string str = line.substr(0, i);
3081 string remainder = line.substr(i + 1);
3082
3083 //cout << "substring ='" << str << "'" << endl;
3084 m = atoi(str.c_str()); // stoi(str) is C++11
3085 //cout << "remainder ='" << remainder << "'" << endl;
3086 i = remainder.find(" ");
3087 str = remainder.substr(0, i);
3088 //cout << "substring ='" << str << "'" << endl;
3089 n = atoi(str.c_str());
3090 string remainder2 = remainder.substr(i + 1);
3091
3092 i = remainder2.find(" ");
3093 str = remainder2.substr(0, i);
3094 //cout << "substring ='" << str << "'" << endl;
3095 f_has_sum1 = atoi(str.c_str());
3096
3097 string remainder3 = remainder2.substr(i + 1);
3098 i = remainder3.find(" ");
3099 str = remainder3.substr(0, i);
3100 s = atoi(str.c_str());
3101 string remainder4 = remainder3.substr(i + 1);
3102 f_has_var_labels_save = atoi(remainder4.c_str());
3103
3104
3105 //cout << "diophant::read_general_format "
3106 // "m=" << m << " n=" << n << " remainder3=" << remainder3 << endl;
3107
3108 //str = remainder3.substr(i + 1);
3109 if (f_vv) {
3110 cout << "diophant::read_general_format "
3111 "m=" << m << " n=" << n << " sum=" << s
3112 << " f_has_var_labels=" << f_has_var_labels_save << endl;
3113 }
3114
3115 open(m, n);
3116 f_has_var_labels = f_has_var_labels_save;
3117 f_has_sum = f_has_sum1;
3118 sum = s;
3119
3120 if (f_has_var_labels) {
3121
3122 if (f_vv) {
3123 cout << "reading var labels" << endl;
3124 }
3125 var_labels = NEW_int(n);
3126 getline (myfile, line);
3127 for (j = 0; j < n; j++) {
3128
3129 // read the value:
3130 i = line.find(" ");
3131 str = line.substr(0, i);
3132 var_labels[j] = atoi(str.c_str());
3133 remainder = line.substr(i + 1);
3134 line = remainder;
3135 }
3136 }
3137 else {
3138 if (f_vv) {
3139 cout << "not reading var labels" << endl;
3140 }
3141 }
3142
3143 for (cnt = 0; cnt < m; cnt++) {
3144 if (f_v) {
3145 cout << "reading equation " << cnt << " / " << m << ":" << endl;
3146 }
3147 getline (myfile, line);
3148 i = line.find(" ");
3149 remainder = line.substr(i + 1);
3150 line = remainder;
3151 if (f_v) {
3152 cout << "remainder = '" << remainder << "'" << endl;
3153 }
3154 i = line.find(" ");
3155 str = line.substr(0, i);
3156 remainder = line.substr(i + 1);
3157 line = remainder;
3158 if (str.compare(EQ) == 0) {
3159 //cout << "equal" << endl;
3160 type[cnt] = t_EQ;
3161 }
3162 else if (str.compare(LE) == 0) {
3163 //cout << "less than or equal" << endl;
3164 type[cnt] = t_LE;
3165 }
3166 else if (str.compare(INT) == 0) {
3167 //cout << "less than or equal" << endl;
3168 type[cnt] = t_INT;
3169 }
3170 else if (str.compare(ZOR) == 0) {
3171 //cout << "less than or equal" << endl;
3172 type[cnt] = t_ZOR;
3173 }
3174 else {
3175 cout << "cannot find EQ or LE or ZOR" << endl;
3176 exit(1);
3177 }
3178 //cout << "remainder = '" << line << "'" << endl;
3179
3180 // read the RHS:
3181
3182 i = line.find(" ");
3183 str = line.substr(0, i);
3184 remainder = line.substr(i + 1);
3185 line = remainder;
3186 RHSi(cnt) = atoi(str.c_str());
3187 //cout << "rhs = " << RHS[cnt] << endl;
3188 //cout << "remainder = '" << line << "'" << endl;
3189 if (type[cnt] == t_INT) {
3190 RHS_low_i(cnt) = RHSi(cnt);
3191 i = line.find(" ");
3192 str = line.substr(0, i);
3193 remainder = line.substr(i + 1);
3194 line = remainder;
3195 RHSi(cnt) = atoi(str.c_str());
3196 //cout << "rhs_low = " << RHS_low[cnt] << endl;
3197 //cout << "rhs = " << RHS[cnt] << endl;
3198 //cout << "remainder = '" << line << "'" << endl;
3199 }
3200
3201 // read nb_types:
3202 i = line.find(" ");
3203 str = line.substr(0, i);
3204 nb_types = atoi(str.c_str());
3205 remainder = line.substr(i + 1);
3206 line = remainder;
3207
3208 for (t = 0; t < nb_types; t++) {
3209
3210 // read the value:
3211 i = line.find(" ");
3212 str = line.substr(0, i);
3213 val = atoi(str.c_str());
3214 remainder = line.substr(i + 1);
3215 line = remainder;
3216
3217 // read the multiplicity:
3218 i = line.find(" ");
3219 str = line.substr(0, i);
3220 d = atoi(str.c_str());
3221 remainder = line.substr(i + 1);
3222 line = remainder;
3223
3224 // read the coefficients:
3225
3226 //cout << "d = " << d << endl;
3227 for (h = 0; h < d; h++) {
3228 i = line.find(" ");
3229 str = line.substr(0, i);
3230 a = atoi(str.c_str());
3231 remainder = line.substr(i + 1);
3232 line = remainder;
3233 Aij(cnt, a) = val;
3234
3235 }
3236 }
3237
3238
3239 } // next cnt
3240 //cout << "read " << cnt << " lines" << endl;
3241
3242#if 0
3243 while ( getline (myfile, line) ) {
3244 cout << line << '\n';
3245
3246 }
3247#endif
3248 x_min = NEW_int(n);
3249 x_max = NEW_int(n);
3250 for (j = 0; j < n; j++) {
3251 getline (myfile, line);
3252
3253 // read the value:
3254 i = line.find(" ");
3255 str = line.substr(0, i);
3256 x_min[j] = atoi(str.c_str());
3257 remainder = line.substr(i + 1);
3258 line = remainder;
3259 x_max[j] = atoi(remainder.c_str());
3260 }
3261
3262 myfile.close();
3263 }
3264 else {
3265 cout << "Cannot open file " << fname << endl;
3266 exit(1);
3267 }
3268
3269 if (f_v) {
3270 cout << "diophant::read_general_format read system with " << m
3271 << " rows and " << n << " columns and f_has_sum=" << f_has_sum
3272 << " sum " << sum << endl;
3273 }
3274 }
3275}
3276
3278{
3279 int *eqn_number;
3280 eliminate_zero_rows(eqn_number, verbose_level);
3281 FREE_int(eqn_number);
3282}
3283
3284void diophant::eliminate_zero_rows(int *&eqn_number, int verbose_level)
3285{
3286 int f_v = (verbose_level >= 1);
3287 int i, j, mm;
3288 int f_delete = FALSE;
3289
3290 eqn_number = NEW_int(m);
3291 mm = 0;
3292 for (i = 0; i < m; i++) {
3293 for (j = 0; j < n; j++) {
3294 if (Aij(i, j)) {
3295 break;
3296 }
3297 }
3298 if (j < n) {
3299 f_delete = FALSE;
3300 }
3301 else {
3302 f_delete = TRUE;
3303 }
3304 if (f_delete && type[i] == t_EQ && RHS[i]) {
3305 f_delete = FALSE;
3306 }
3307 if (!f_delete) {
3308 eqn_number[mm] = i;
3309 if (i != mm) {
3310 for (j = 0; j < n; j++) {
3311 Aij(mm, j) = Aij(i, j);
3312 }
3313 RHS[mm] = RHS[i];
3314 RHS_low[mm] = RHS_low[i];
3315 type[mm] = type[i];
3316 eqn_label[mm] = eqn_label[i];
3317 }
3318 mm++;
3319 }
3320 else {
3321 if (eqn_label[i]) {
3322 FREE_char(eqn_label[i]);
3323 eqn_label[i] = NULL;
3324 }
3325 }
3326 }
3327 if (f_v) {
3328 cout << "eliminate_zero_rows: eliminated " << m - mm
3329 << " zero rows" << endl;
3330 }
3331 m = mm;
3332}
3333
3334int diophant::is_zero_outside(int first, int len, int i)
3335{
3336 int j;
3337
3338 for (j = 0; j < n; j++) {
3339 if (j >= first && j < first + len) {
3340 continue;
3341 }
3342 if (Aij(i, j)) {
3343 return FALSE;
3344 }
3345 }
3346 return TRUE;
3347}
3348
3349void diophant::project(diophant *D, int first, int len,
3350 int *&eqn_number, int &nb_eqns_replaced, int *&eqns_replaced,
3351 int verbose_level)
3352{
3353 int i, j, f_zo;
3354
3355 D->open(m, len);
3356 nb_eqns_replaced = 0;
3357 eqns_replaced = NEW_int(m);
3358 for (i = 0; i < m; i++) {
3359 f_zo = is_zero_outside(first, len, i);
3360 if (f_zo) {
3361 eqns_replaced[nb_eqns_replaced++] = i;
3362 }
3363 for (j = 0; j < len; j++) {
3364 D->Aij(i, j) = Aij(i, first + j);
3365 }
3366 D->RHS_low[i] = RHS_low[i];
3367 D->RHS[i] = RHS[i];
3368 D->type[i] = type[i];
3369 if (!f_zo) {
3370 D->type[i] = t_LE;
3371 }
3372 if (eqn_label[i]) {
3373 D->init_eqn_label(i, eqn_label[i]);
3374 }
3375 }
3376 //D->f_x_max = f_x_max;
3377 //if (f_x_max) {
3378 for (j = 0; j < len; j++) {
3379 D->x_max[j] = x_max[first + j];
3380 D->x_min[j] = x_min[first + j];
3381 }
3382 //}
3383 D->f_has_sum = f_has_sum;
3384 D->sum = sum;
3385 D->eliminate_zero_rows(eqn_number, 0);
3386}
3387
3389 int f_solve_case, int solve_case_idx, int verbose_level)
3390{
3391 int f_v = (verbose_level >= 1);
3392
3393 if (f_v) {
3394 cout << "diophant::split_by_equation" << endl;
3395 }
3396 diophant *D;
3397 long int nb_backtrack_nodes;
3398 int max_results = INT_MAX;
3399 int N, a;
3400
3401 D = NEW_OBJECT(diophant);
3403 project_to_single_equation(D, eqn_idx, verbose_level);
3404 if (f_v) {
3405 cout << "equation " << eqn_idx << " has " << a << " nonzero coefficients:" << endl;
3406 D->print_dense();
3407 }
3408 D->solve_all_mckay(nb_backtrack_nodes, max_results, 0 /* verbose_level */);
3409 N = D->_resultanz;
3410 if (f_v) {
3411 cout << "equation " << eqn_idx << " has " << N << " solutions." << endl;
3412 D->print_dense();
3413 }
3414
3415 int j;
3416 int *Sol;
3417 int nb_sol;
3418
3419 D->get_solutions_full_length(Sol, nb_sol, verbose_level);
3420
3421 if (f_solve_case) {
3422 if (f_v) {
3423 cout << "Solution " << solve_case_idx << " is ";
3424 for (j = 0; j < n; j++) {
3425 if (Sol[solve_case_idx * n + j] == 0) {
3426 continue;
3427 }
3428 cout << j << ", ";
3429 }
3430 cout << endl;
3431 }
3432 cout << "Solution " << solve_case_idx << " is ";
3433 for (j = 0; j < n; j++) {
3434 if (D->x_min[j] != D->x_max[j]) {
3435 cout << "x_" << j << " = " << Sol[solve_case_idx * n + j] << ", ";
3436 }
3437 }
3438 cout << endl;
3439
3440 for (j = 0; j < n; j++) {
3441 if (D->x_min[j] != D->x_max[j]) {
3442 x_min[j] = x_max[j] = Sol[solve_case_idx * n + j];
3443 }
3444 }
3445 cout << "solving case " << solve_case_idx << endl;
3446 solve_all_mckay(nb_backtrack_nodes, INT_MAX, 0 /*verbose_level */);
3447 cout << "solved case " << solve_case_idx << " with " << _resultanz << " solutions" << endl;
3448
3449 }
3450 FREE_int(Sol);
3451
3452 FREE_OBJECT(D);
3453
3454}
3455
3456void diophant::split_by_two_equations(int eqn1_idx, int eqn2_idx,
3457 int f_solve_case, int solve_case_idx_r, int solve_case_idx_m,
3458 int verbose_level)
3459{
3460 int f_v = (verbose_level >= 1);
3461
3462 if (f_v) {
3463 cout << "diophant::split_by_two_equations" << endl;
3464 }
3465 diophant *D;
3466 long int nb_backtrack_nodes;
3467 int max_results = INT_MAX;
3468 int N;
3469
3470 D = NEW_OBJECT(diophant);
3471 project_to_two_equations(D, eqn1_idx, eqn2_idx, verbose_level);
3472 if (f_v) {
3473 cout << "equations (" << eqn1_idx << ", " << eqn2_idx << "):" << endl;
3474 D->print_dense();
3475 }
3476 D->solve_all_mckay(nb_backtrack_nodes, max_results, 0 /* verbose_level */);
3477 N = D->_resultanz;
3478 if (f_v) {
3479 cout << "equations (" << eqn1_idx << ", " << eqn2_idx << ") have " << N << " solutions." << endl;
3480 D->print_dense();
3481 }
3482
3483 int j;
3484 int *Sol;
3485 int nb_sol;
3486 int idx;
3487
3488 D->get_solutions_full_length(Sol, nb_sol, verbose_level);
3489
3490 if (f_solve_case) {
3491 for (idx = 0; idx < nb_sol; idx++) {
3492 if ((idx % solve_case_idx_m) != solve_case_idx_r) {
3493 continue;
3494 }
3495 if (f_v) {
3496 cout << "Solution " << idx << " is ";
3497 for (j = 0; j < n; j++) {
3498 if (Sol[idx * n + j] == 0) {
3499 continue;
3500 }
3501 cout << j << ", ";
3502 }
3503 cout << endl;
3504 }
3505 cout << "Solution " << idx << " is ";
3506 for (j = 0; j < n; j++) {
3507 if (D->x_min[j] != D->x_max[j]) {
3508 cout << "x_" << j << " = " << Sol[idx * n + j] << ", ";
3509 }
3510 }
3511 cout << endl;
3512
3513 for (j = 0; j < n; j++) {
3514 if (D->x_min[j] != D->x_max[j]) {
3515 x_min[j] = x_max[j] = Sol[idx * n + j];
3516 }
3517 }
3518 cout << "solving case " << idx << endl;
3519 solve_all_mckay(nb_backtrack_nodes, max_results, 0 /*verbose_level */);
3520 cout << "solved case " << idx << " with " << _resultanz << " solutions" << endl;
3521 }
3522 }
3523 FREE_int(Sol);
3524
3525 FREE_OBJECT(D);
3526
3527}
3528
3530 int max_number_of_coefficients,
3531 int verbose_level)
3532{
3533 int f_v = (verbose_level >= 1);
3534
3535 if (f_v) {
3536 cout << "diophant::project_to_single_equation_and_solve" << endl;
3537 cout << "max_number_of_coefficients = " << max_number_of_coefficients << endl;
3538 }
3539 diophant *D;
3540 long int *nb_sol_in_eqn;
3541 long int nb_backtrack_nodes;
3542 int max_results = 10000;
3543 int *eqn_idx;
3544 int i, h, a;
3545
3546 nb_sol_in_eqn = NEW_lint(m);
3547 eqn_idx = NEW_int(m);
3548 h = 0;
3549 for (i = 0; i < m; i++) {
3551 if (f_v) {
3552 cout << "equation " << i << " has " << a << " nonzero coefficients" << endl;
3553 }
3554 if (a < max_number_of_coefficients) {
3555 D = NEW_OBJECT(diophant);
3556 project_to_single_equation(D, i, verbose_level);
3557 if (f_v) {
3558 cout << "equation " << i << " has " << a << " nonzero coefficients:" << endl;
3559 D->print_dense();
3560 }
3561 D->solve_all_mckay(nb_backtrack_nodes, max_results, 0 /* verbose_level */);
3562 eqn_idx[h] = i;
3563 nb_sol_in_eqn[h] = D->_resultanz;
3564 h++;
3565 FREE_OBJECT(D);
3566 }
3567 else {
3568 if (f_v) {
3569 cout << "ignoring equation " << i << endl;
3570 }
3571 }
3572 }
3573
3574 cout << "number of solutions of individual equations:" << endl;
3575 for (i = 0; i < h; i++) {
3576 cout << setw(3) << eqn_idx[i] << " : " << setw(4) << nb_sol_in_eqn[i] << endl;
3577 }
3578
3580
3581 C.init_lint(nb_sol_in_eqn, h, FALSE, 0);
3582 cout << "number of solutions of individual equations classified:" << endl;
3583 C.print(TRUE);
3584
3585 FREE_int(eqn_idx);
3586 FREE_lint(nb_sol_in_eqn);
3587
3588 if (f_v) {
3589 cout << "diophant::project_to_single_equation_and_solve done" << endl;
3590 }
3591}
3592
3594 int verbose_level)
3595{
3596 int f_v = (verbose_level >= 1);
3597 int j;
3598
3599 if (f_v) {
3600 cout << "diophant::project_to_single_equation" << endl;
3601 }
3602
3603 D->open(1, n);
3604
3605 for (j = 0; j < n; j++) {
3606 D->Aij(0, j) = Aij(eqn_idx, j);
3607 }
3608 D->RHS[0] = RHS[eqn_idx];
3609 D->RHS_low[0] = RHS_low[eqn_idx];
3610 D->type[0] = type[eqn_idx];
3611
3612 for (j = 0; j < n; j++) {
3613 D->x_max[j] = x_max[j];
3614 D->x_min[j] = x_min[j];
3615
3616 if (D->Aij(0, j) == 0) {
3617 D->x_max[j] = 0;
3618 }
3619 }
3620
3621 D->f_has_sum = FALSE;
3622 D->sum = 0;
3623
3624 if (f_v) {
3625 cout << "diophant::project_to_single_equation done" << endl;
3626 }
3627}
3628
3629void diophant::project_to_two_equations(diophant *D, int eqn1_idx, int eqn2_idx,
3630 int verbose_level)
3631{
3632 int f_v = (verbose_level >= 1);
3633 int j;
3634
3635 if (f_v) {
3636 cout << "diophant::project_to_two_equations" << endl;
3637 }
3638
3639 D->open(2, n);
3640
3641 for (j = 0; j < n; j++) {
3642 D->Aij(0, j) = Aij(eqn1_idx, j);
3643 D->Aij(1, j) = Aij(eqn2_idx, j);
3644 }
3645 D->RHS[0] = RHS[eqn1_idx];
3646 D->RHS[1] = RHS[eqn2_idx];
3647 D->RHS_low[0] = RHS_low[eqn1_idx];
3648 D->RHS_low[1] = RHS_low[eqn2_idx];
3649 D->type[0] = type[eqn1_idx];
3650 D->type[1] = type[eqn2_idx];
3651
3652 for (j = 0; j < n; j++) {
3653 D->x_max[j] = x_max[j];
3654 D->x_min[j] = x_min[j];
3655
3656 if (D->Aij(0, j) == 0 && D->Aij(1, j) == 0) {
3657 D->x_max[j] = 0;
3658 }
3659 }
3660
3661 D->f_has_sum = FALSE;
3662 D->sum = 0;
3663
3664 if (f_v) {
3665 cout << "diophant::project_to_two_equations done" << endl;
3666 }
3667}
3668
3670{
3671 int i, j, a;
3672
3673 for (i = 0; i < m; i++) {
3674 a = 0;
3675 for (j = 0; j < n; j++) {
3676 a += Aij(i, j) * x[j];
3677 }
3678 RHS1[i] = a;
3679 }
3680}
3681
3682void diophant::write_xml(ostream &ost, const char *label)
3683{
3684 int i, j;
3685 char *lbl;
3686
3687 ost << "<DIOPHANT label=\"" << label << "\" num_eqns=" << m
3688 << " num_vars=" << n << " f_has_sum=" << f_has_sum
3689 << " sum=" << sum << " >" << endl;
3690 for (i = 0; i < m; i++) {
3691 for (j = 0;j < n; j++) {
3692 ost << setw(4) << Aij(i, j) << " ";
3693 }
3694 if (eqn_label[i]) {
3695 lbl = eqn_label[i];
3696 }
3697 else {
3698 lbl = (char *) "";
3699 }
3700 if (type[i] == t_EQ) {
3701 ost << setw(2) << 0 << " " << setw(4) << RHS[i];
3702 }
3703 else if (type[i] == t_LE) {
3704 ost << setw(2) << 1 << " " << setw(4) << RHS[i];
3705 }
3706 else if (type[i] == t_INT) {
3707 ost << setw(2) << 2 << " " << setw(4) << RHS_low_i(i) << " " << setw(4) << RHS[i];
3708 }
3709 else if (type[i] == t_ZOR) {
3710 ost << setw(2) << 3 << " " << setw(4) << RHS[i];
3711 }
3712 ost << " \"" << lbl << "\"" << endl;
3713 }
3714 for (j = 0; j < n; j++) {
3715 ost << setw(4) << x_min[j] << " " << setw(4) << x_max[j] << endl;
3716 }
3717 ost << "</DIOPHANT>" << endl;
3718
3719}
3720
3721
3722void diophant::read_xml(ifstream &f, char *label, int verbose_level)
3723{
3724#ifdef SYSTEMUNIX
3725 int f_v = (verbose_level >= 1);
3726 string str, mapkey, mapval;
3727 bool brk;
3728 int eqpos, l, M = 0, N = 0, F_has_sum = 0, Sum = 0, i, j, a;
3729 char tmp[1000], c;
3731
3732
3733 if (f_v) {
3734 cout << "diophant::read_xml" << endl;
3735 }
3736 label[0] = 0;
3737 f.ignore(INT_MAX, '<');
3738 f >> str;
3739 brk = false;
3740 if (str != "DIOPHANT") {
3741 cout << "not a DIOPHANT object: str=" << str << endl;
3742 exit(1);
3743 }
3744 while (!brk) {
3745 f >> str;
3746 if (str.substr(str.size() - 1, 1) == ">") {
3747 str = str.substr(0, str.size() - 1);
3748 brk = true;
3749 }
3750 eqpos = (int) str.find("=");
3751 if (eqpos > 0) {
3752 mapkey = str.substr(0, eqpos);
3753 mapval = str.substr(eqpos + 1, str.size() - eqpos - 1);
3754 if (mapkey == "label") {
3755 l = (int) mapval.size();
3756 for (i = 1; i < l; i++) {
3757 label[i - 1] = mapval[i];
3758 }
3759 label[l - 2] = 0;
3760 }
3761 else if (mapkey == "num_eqns") {
3762 M = ST.str2int(mapval);
3763 if (f_v) {
3764 cout << "diophant::read_xml num_eqns = " << M << endl;
3765 }
3766 }
3767 else if (mapkey == "num_vars") {
3768 N = ST.str2int(mapval);
3769 if (f_v) {
3770 cout << "diophant::read_xml num_vars = " << N << endl;
3771 }
3772 }
3773 else if (mapkey == "f_has_sum") {
3774 F_has_sum = ST.str2int(mapval);
3775 if (f_v) {
3776 cout << "diophant::read_xml F_has_sum = " << F_has_sum << endl;
3777 }
3778 }
3779 else if (mapkey == "sum") {
3780 Sum = ST.str2int(mapval);
3781 if (f_v) {
3782 cout << "diophant::read_xml Sum = " << Sum << endl;
3783 }
3784 }
3785 }
3786 brk = brk || f.eof();
3787 }
3788 if (f_v) {
3789 cout << "diophant::read_xml M=" << M << " N=" << N << endl;
3790 }
3791 open(M, N);
3792 f_has_sum = F_has_sum;
3793 sum = Sum;
3794 for (i = 0; i < m; i++) {
3795 for (j = 0; j < n; j++) {
3796 f >> a;
3797 Aij(i, j) = a;
3798 }
3799 int t;
3800 f >> t;
3801 if (t == 0) {
3802 type[i] = t_EQ;
3803 }
3804 else if (t == 1) {
3805 type[i] = t_LE;
3806 }
3807 else if (t == 2) {
3808 type[i] = t_INT;
3809 }
3810 else if (t == 3) {
3811 type[i] = t_ZOR;
3812 }
3813 f >> RHS[i];
3814 if (type[i] == t_INT) {
3815 RHS_low[i] = RHS[i];
3816 f >> RHS[i];
3817 }
3818
3819 //f.ignore(INT_MAX, '\"');
3820 while (TRUE) {
3821 f >> c;
3822 if (c == '\"') {
3823 break;
3824 }
3825 }
3826 l = 0;
3827 while (TRUE) {
3828 f >> c;
3829 if (c == '\"') {
3830 break;
3831 }
3832 tmp[l] = c;
3833 l++;
3834 }
3835 tmp[l] = 0;
3836 eqn_label[i] = NEW_char(l + 1);
3837 for (j = 0; j < l; j++) {
3838 eqn_label[i][j] = tmp[j];
3839 }
3840 eqn_label[i][l] = 0;
3841 }
3842 if (f_v) {
3843 cout << "diophant::read_xml reading x_max[]" << endl;
3844 }
3845 for (j = 0; j < n; j++) {
3846 f >> x_min[j] >> x_max[j];
3847 if (f_v) {
3848 cout << "diophant::read_xml reading x_max[" << j << "]="
3849 << x_max[j] << endl;
3850 }
3851 }
3852 if (f_v) {
3853 cout << "diophant::read_xml read the following file:" << endl;
3854 write_xml(cout, label);
3855 }
3856#endif
3857#ifdef SYSTEMWINDOWS
3858 cout << "diophant::read_xml has a problem under windows"<< endl;
3859 exit(1);
3860#endif
3861}
3862
3864{
3865 int *AA, *R_low, *R, *R1, *Y1;
3867 char **L;
3868 int m1 = m + 1;
3869 int i, j;
3870
3871 AA = NEW_int(m1 * n);
3872 R_low = NEW_int(m1);
3873 R = NEW_int(m1);
3874 R1 = NEW_int(m1);
3876 L = NEW_pchar(m1);
3877 Y1 = NEW_int(m1);
3878
3879 for (i = 0; i < m; i++) {
3880
3881 for (j = 0; j < n; j++) {
3882 AA[i * n + j] = Aij(i, j);
3883 }
3884 R_low[i] = RHS_low[i];
3885 R[i] = RHS[i];
3886 R1[i] = RHS1[i];
3887 type1[i] = type[i];
3888 L[i] = eqn_label[i];
3889 }
3890
3891 FREE_int(A);
3893 FREE_int(RHS);
3894 FREE_int(RHS1);
3897 FREE_int(Y);
3898
3899 A = AA;
3900 RHS_low = R_low;
3901 RHS = R;
3902 RHS1 = R1;
3903 type = type1;
3904 eqn_label = L;
3905 Y = Y1;
3906
3907 Int_vec_zero(A + m * n, n);
3908 RHS_low[m] = 0;
3909 RHS[m] = 0;
3910 RHS1[m] = 0;
3911 type[m] = t_EQ;
3912 eqn_label[m] = NULL;
3913
3914 m++;
3915
3916}
3917
3919{
3920 int i, j;
3921
3922 if (eqn_label[I]) {
3923 FREE_char(eqn_label[I]);
3924 eqn_label[I] = NULL;
3925 }
3926 for (i = I; i < m - 1; i++) {
3927 eqn_label[i] = eqn_label[i + 1];
3928 eqn_label[i + 1] = NULL;
3929 type[i] = type[i + 1];
3930 RHS_low[i] = RHS_low[i + 1];
3931 RHS[i] = RHS[i + 1];
3932 for (j = 0; j < n; j++) {
3933 Aij(i, j) = Aij(i + 1, j);
3934 }
3935 }
3936 m--;
3937}
3938
3940{
3941 int i, j, a;
3943
3944 {
3945 ofstream f(fname);
3946 f << "Maximize" << endl;
3947 f << " ";
3948 for (j = 0; j < n; j++) {
3949 f << " + 0 x" << j;
3950 }
3951 f << endl;
3952 f << " Subject to" << endl;
3953 for (i = 0; i < m; i++) {
3954 f << " ";
3955 for (j = 0; j < n; j++) {
3956 a = Aij(i, j);
3957 if (a == 0) {
3958 continue;
3959 }
3960 f << " + " << a << " x"<< j;
3961 }
3962 f << " = " << RHSi(i) << endl;
3963 }
3964 f << "Binary" << endl;
3965 for (i = 0; i < n; i++) {
3966 f << "x" << i << endl;
3967 }
3968 f << "End" << endl;
3969 }
3970 cout << "Written file " << fname << " of size "
3971 << Fio.file_size(fname) << endl;
3972}
3973
3974void diophant::draw_as_bitmap(std::string &fname,
3975 int f_box_width, int box_width, int bit_depth, int verbose_level)
3976{
3977 int f_v = (verbose_level >= 1);
3978
3979 if (f_v) {
3980 cout << "diophant::draw_as_bitmap" << endl;
3981 }
3982
3983 int *M;
3984 int m1 = m + 1;
3985 int n1 = n + 1;
3986 int i, j, a;
3987
3988 M = NEW_int(m1 * n1);
3989 for (i = 0; i < m1; i++) {
3990 for (j = 0; j < n1; j++) {
3991 if (i == m) {
3992 if (j == n) {
3993 a = 0;
3994 }
3995 else {
3996 a = x_max[j];
3997 }
3998 }
3999 else {
4000 if (j == n) {
4001 a = RHS[i];
4002 }
4003 else {
4004 a = Aij(i, j);
4005 }
4006 }
4007 M[i * n1 + j] = a;
4008 }
4009 }
4010
4011
4013 graphics::draw_bitmap_control Draw_bitmap_control;
4014
4015 Draw_bitmap_control.M = M;
4016 Draw_bitmap_control.m = m1;
4017 Draw_bitmap_control.n = n1;
4018 Draw_bitmap_control.f_box_width = f_box_width;
4019 Draw_bitmap_control.box_width = box_width;
4020 Draw_bitmap_control.bit_depth = bit_depth;
4021 Draw_bitmap_control.f_invert_colors = FALSE;
4022
4023
4024 GO.draw_bitmap(&Draw_bitmap_control, verbose_level);
4025
4026#if 0
4027 draw_bitmap(fname, M, m1, n1,
4028 FALSE /* f_partition */, 0 /* part_width*/,
4029 0, NULL, 0, NULL, //int nb_row_parts, int *Row_part, int nb_col_parts, int *Col_part,
4030 f_box_width, box_width,
4031 FALSE /* f_invert_colors */, bit_depth,
4032 verbose_level);
4033#endif
4034
4035 FREE_int(M);
4036
4037 if (f_v) {
4038 cout << "diophant::draw_as_bitmap done" << endl;
4039 }
4040
4041}
4042
4044 std::string &fname_base,
4046 int verbose_level)
4047{
4048 int f_dots = FALSE;
4049 int f_partition = FALSE;
4050 int f_bitmatrix = FALSE;
4051 int f_row_grid = FALSE;
4052 int f_col_grid = FALSE;
4054
4055
4056 Graph.draw_bitmatrix(
4057 fname_base,
4058 Draw_options,
4059 f_dots,
4060 f_partition, 0, NULL, 0, NULL,
4061 f_row_grid, f_col_grid,
4062 f_bitmatrix, NULL, A,
4063 m, n,
4064 FALSE, NULL,
4065 verbose_level);
4066}
4067
4069 std::string &fname_base,
4071 int f_solution, int *solution, int solution_sz,
4072 int verbose_level)
4073{
4074 int f_v = (verbose_level >= 1);
4075 int f_dots = FALSE;
4076 int f_bitmatrix = FALSE;
4077 int i, ii, j, jj;
4080
4081
4082 if (f_v) {
4083 cout << "diophant::draw_partitioned" << endl;
4084 }
4085
4086 int *T;
4087 int *A2;
4088 int a;
4089
4090 T = NEW_int(m);
4091 A2 = NEW_int(m * n);
4092 Int_vec_zero(A2, m * n);
4093
4094 for (i = 0; i < m; i++) {
4095 if (type[i] == t_EQ) {
4096 T[i] = -RHS[i];
4097 }
4098 else if (type[i] == t_LE) {
4099 T[i] = 2;
4100 }
4101 else if (type[i] == t_INT) {
4102 T[i] = 3;
4103 }
4104 else if (type[i] == t_ZOR) {
4105 T[i] = 4;
4106 }
4107 }
4108
4110
4111 C.init(T, m, FALSE, 0);
4112 if (f_v) {
4113 cout << "diophant::draw_partitioned we found " << C.nb_types
4114 << " classes according to type[]" << endl;
4115 }
4116
4117 int *part;
4118 int *part_col;
4119 int *col_perm;
4120 int size_complement;
4121 int col_part_size;
4122
4123 part = NEW_int(C.nb_types + 1);
4124 for (i = 0; i < C.nb_types; i++) {
4125 part[i] = C.type_first[i];
4126 }
4127 part[C.nb_types] = m;
4128
4129 col_perm = NEW_int(n);
4130
4131
4132
4133
4134 if (f_solution) {
4135 part_col = NEW_int(3);
4136 part_col[0] = 0;
4137 part_col[1] = n - solution_sz;
4138 part_col[2] = n;
4139
4140 Int_vec_copy(solution, col_perm + n - solution_sz, solution_sz);
4141 Combi.set_complement(solution, solution_sz, col_perm, size_complement, n);
4142
4143 if (size_complement != n - solution_sz) {
4144 cout << "diophant::draw_partitioned size_complement "
4145 "!= n - solution_sz" << endl;
4146 exit(1);
4147 }
4148 col_part_size = 2;
4149 }
4150 else {
4151 part_col = NEW_int(2);
4152 part_col[0] = 0;
4153 part_col[1] = n;
4154 for (j = 0; j < n; j++) {
4155 col_perm[j] = j;
4156 }
4157 col_part_size = 1;
4158 }
4159
4160#if 0
4161 if (f_v) {
4162 cout << "row_perm:";
4163 int_vec_print(cout, C.sorting_perm_inv, m);
4164 cout << endl;
4165 }
4166 if (f_v) {
4167 cout << "col_perm:";
4168 int_vec_print(cout, col_perm, n);
4169 cout << endl;
4170 }
4171#endif
4172
4173
4174 for (i = 0; i < m; i++) {
4175 ii = C.sorting_perm_inv[i];
4176 //cout << "i=" << i << " ii=" << ii << endl;
4177 for (j = 0; j < n; j++) {
4178 jj = col_perm[j];
4179 a = Aij(ii, jj);
4180 A2[i * n + j] = a;
4181 }
4182 }
4183 if (FALSE) {
4184 cout << "diophant::draw_partitioned A2=" << endl;
4185 Int_matrix_print(A2, m, n);
4186 }
4187
4188 int f_row_grid = FALSE;
4189 int f_col_grid = FALSE;
4190
4191
4192 Graph.draw_bitmatrix(
4193 fname_base,
4194 Draw_options,
4195 f_dots,
4196 TRUE /* f_partition */, C.nb_types, part, col_part_size, part_col,
4197 f_row_grid, f_col_grid,
4198 f_bitmatrix, NULL,
4199 A2, m, n,
4200 FALSE, NULL, verbose_level - 1);
4201
4202
4203 FREE_int(T);
4204 FREE_int(A2);
4205 FREE_int(part);
4206 FREE_int(part_col);
4207 FREE_int(col_perm);
4208 if (f_v) {
4209 cout << "diophant::draw_partitioned done" << endl;
4210 }
4211}
4212
4213int diophant::test_solution(int *sol, int len, int verbose_level)
4214{
4215 int f_v = (verbose_level >= 1);
4216 int i, j, b, c, ret;
4217
4218 if (f_v) {
4219 cout << "diophant::test_solution" << endl;
4220 }
4221 if (FALSE) {
4222 Int_vec_print(cout, sol, len);
4223 cout << endl;
4225
4226 get_columns(sol, len, S, 0 /* verbose_level */);
4227 S->print_table();
4228
4229 FREE_OBJECT(S);
4230 }
4231 Int_vec_zero(Y, m);
4232 Int_vec_zero(X, n);
4233 for (j = 0; j < len; j++) {
4234 X[sol[j]] = 1;
4235 }
4236 for (i = 0; i < m; i++) {
4237 b = 0;
4238 for (j = 0; j < n; j++) {
4239 c = Aij(i, j) * X[j];
4240 b += c;
4241 }
4242 Y[i] = b;
4243 }
4244 if (FALSE) {
4245 cout << "Y=";
4246 Int_vec_print_fully(cout, Y, m);
4247 cout << endl;
4248 }
4249 ret = TRUE;
4250 for (i = 0; i < m; i++) {
4251 if (type[i] == t_EQ) {
4252 if (Y[i] != RHS[i]) {
4253 cout << "diophant::test_solution t_EQ and Y[i] != RHS[i]" << endl;
4254 ret = FALSE;
4255 break;
4256 }
4257 }
4258 else if (type[i] == t_LE) {
4259 if (Y[i] > RHS[i]) {
4260 cout << "diophant::test_solution t_LE and Y[i] > RHS[i]" << endl;
4261 ret = FALSE;
4262 break;
4263 }
4264
4265 }
4266 else if (type[i] == t_INT) {
4267 if (Y[i] > RHS[i]) {
4268 cout << "diophant::test_solution t_INT and Y[i] > RHS[i]" << endl;
4269 ret = FALSE;
4270 break;
4271 }
4272 if (Y[i] < RHS_low[i]) {
4273 cout << "diophant::test_solution t_INT and Y[i] < RHS_low[i]" << endl;
4274 ret = FALSE;
4275 break;
4276 }
4277
4278 }
4279 else if (type[i] == t_ZOR) {
4280 if (Y[i] != 0 && Y[i] != RHS[i]) {
4281 ret = FALSE;
4282 break;
4283 }
4284 }
4285 else {
4286 cout << "diophant::test_solution unknown type" << endl;
4287 exit(1);
4288 }
4289 }
4290
4291
4292
4293 if (f_v) {
4294 cout << "diophant::test_solution done" << endl;
4295 }
4296 return ret;
4297}
4298
4299
4300void diophant::get_columns(int *col, int nb_col,
4301 data_structures::set_of_sets *&S, int verbose_level)
4302{
4303 int f_v = (verbose_level >= 1);
4304 int i, j, h, d;
4305
4306 if (f_v) {
4307 cout << "diophant::get_columns" << endl;
4308 }
4310
4311 S->init_simple(m, nb_col, 0 /* verbose_level */);
4312 for (h = 0; h < nb_col; h++) {
4313 j = col[h];
4314 d = 0;
4315 for (i = 0; i < m; i++) {
4316 if (Aij(i, j)) {
4317 d++;
4318 }
4319 }
4320 S->Sets[h] = NEW_lint(d);
4321 S->Set_size[h] = d;
4322 d = 0;
4323 for (i = 0; i < m; i++) {
4324 if (Aij(i, j)) {
4325 S->Sets[h][d] = i;
4326 d++;
4327 }
4328 }
4329 }
4330}
4331
4332void diophant::test_solution_file(std::string &solution_file,
4333 int verbose_level)
4334{
4335 int f_v = (verbose_level >= 1);
4336 int f_vv = (verbose_level >= 2);
4337 int *Sol;
4338 int nb_sol, sol_length;
4339 int i;
4341
4342 if (f_v) {
4343 cout << "diophant::test_solution_file" << endl;
4344 }
4345 Fio.int_matrix_read_text(solution_file, Sol, nb_sol, sol_length);
4346
4347 for (i = 0; i < nb_sol; i++) {
4348 if (f_vv) {
4349 cout << "diophant::test_solution_file testing solution "
4350 << i << " / " << nb_sol << ":" << endl;
4351 }
4352 if (!test_solution(Sol + i * sol_length, sol_length, verbose_level)) {
4353 cout << "solution " << i << " / " << nb_sol << " is bad" << endl;
4354 }
4355 else {
4356 cout << "solution " << i << " / " << nb_sol << " is OK" << endl;
4357 }
4358 cout << "Y=";
4359 Int_vec_print(cout, Y, m);
4360 cout << endl;
4361
4363
4364 C.init(Y, m, FALSE, 0);
4365 cout << "classification: ";
4366 C.print_naked(FALSE);
4367 cout << endl;
4368 }
4369 if (f_v) {
4370 cout << "diophant::test_solution_file done" << endl;
4371 }
4372}
4373
4374void diophant::analyze(int verbose_level)
4375{
4376 int f_v = (verbose_level >= 1);
4377 int i, h, val, d;
4378
4379 if (f_v) {
4380 cout << "diophant::analyze" << endl;
4381 }
4382
4383 for (i = 0; i < m; i++) {
4384
4385
4386 int nb_values;
4387 int *values, *multiplicities;
4388
4389
4390 coefficient_values_in_row(i, nb_values,
4391 values, multiplicities, 0 /*verbose_level*/);
4392
4393
4394 cout << "row " << i << ": ";
4395 for (h = 0; h < nb_values; h++) {
4396 val = values[h];
4397 d = multiplicities[h];
4398 cout << val << "^" << d;
4399 if (h < nb_values - 1) {
4400 cout << ", ";
4401 }
4402 }
4403 cout << endl;
4404
4405 FREE_int(values);
4406 FREE_int(multiplicities);
4407
4408 }
4409
4410 if (f_v) {
4411 cout << "diophant::analyze done" << endl;
4412 }
4413}
4414
4416{
4417 int i;
4418
4419 for (i = 0; i < m; i++) {
4420 if (type[i] != t_EQ || type[i] != t_EQ) {
4421 return FALSE;
4422 }
4423 if (RHSi(i) != 1) {
4424 return FALSE;
4425 }
4426 }
4427 return TRUE;
4428}
4429
4431 int verbose_level)
4432{
4433 int f_v = (verbose_level >= 1);
4434 int j1, j2, L, k, i;
4436
4437 if (f_v) {
4438 cout << "diophant::make_clique_graph_adjacency_matrix" << endl;
4439 }
4440#if 0
4441 if (!is_of_Steiner_type()) {
4442 cout << "diophant::make_clique_graph_adjacency_matrix "
4443 "the system is not of Steiner type" << endl;
4444 exit(1);
4445 }
4446#endif
4447 L = (n * (n - 1)) >> 1;
4448#if 0
4449 //length = (L + 7) >> 3;
4450 Adj = bitvector_allocate(L);
4451 for (i = 0; i < L; i++) {
4452 bitvector_m_ii(Adj, i, 1);
4453 }
4454#else
4455 Adj->allocate(L);
4456#endif
4457 for (i = 0; i < m; i++) {
4458 for (j1 = 0; j1 < n; j1++) {
4459 if (Aij(i, j1) == 0) {
4460 continue;
4461 }
4462 for (j2 = j1 + 1; j2 < n; j2++) {
4463 if (Aij(i, j2) == 0) {
4464 continue;
4465 }
4466 // now: j1 and j2 do not go together
4467 k = Combi.ij2k(j1, j2, n);
4468 Adj->m_i(k, 0);
4469 }
4470 }
4471 }
4472 if (f_v) {
4473 cout << "diophant::make_clique_graph_adjacency_matrix done" << endl;
4474 }
4475}
4476
4477
4479{
4480 int f_v = (verbose_level >= 1);
4482
4483 if (f_v) {
4484 cout << "diophant::make_clique_graph" << endl;
4485 }
4486 make_clique_graph_adjacency_matrix(Adj, verbose_level - 1);
4487
4488
4490
4491 string label, label_tex;
4492
4493 label.assign("clique_graph");
4494 label_tex.assign("clique\\_graph");
4495
4496 CG->init_no_colors(n, Adj, TRUE, label, label_tex, verbose_level - 1);
4497
4498
4499 if (f_v) {
4500 cout << "diophant::make_clique_graph" << endl;
4501 }
4502}
4503
4505 std::string &clique_graph_fname, int verbose_level)
4506{
4507 int f_v = (verbose_level >= 1);
4508
4509 if (f_v) {
4510 cout << "diophant::make_clique_graph_and_save" << endl;
4511 }
4512
4514
4515 make_clique_graph(CG, verbose_level - 1);
4516 CG->save(clique_graph_fname, verbose_level - 1);
4517
4518 FREE_OBJECT(CG);
4519 if (f_v) {
4520 cout << "diophant::make_clique_graph_and_save done" << endl;
4521 }
4522}
4523
4524
4526{
4527 vector<int> last;
4528 vector<int> cur;
4529 int l, i, j;
4530
4531 l = _results.size();
4532 last = _results.at(l - 1);
4533 for (i = 0; i < l - 1; i++) {
4534 cur = _results.at(i);
4535 for (j = 0; j < n; j++) {
4536 if (cur[j] != last[j]) {
4537 break;
4538 }
4539 }
4540 if (j == n) {
4541 cout << "The last solution " << l - 1
4542 << " is the same as solution " << i << endl;
4543 exit(1);
4544 }
4545 }
4546}
4547
4548
4549
4550
4552 int f_once, int verbose_level)
4553{
4554 int f_v = TRUE;//(verbose_level >= 1);
4555 int j;
4556 int maxresults = 10000000;
4557 vector<int> res;
4558 long int nb_backtrack_nodes;
4559 int nb_sol;
4560
4561 //verbose_level = 4;
4562 if (f_v) {
4563 cout << "diophant::solve_first_mckay calling solve_mckay" << endl;
4564 }
4565 if (f_once) {
4566 maxresults = 1;
4567 }
4568
4569 solve_mckay("",
4570 maxresults, nb_backtrack_nodes, nb_sol,
4571 verbose_level - 2);
4572
4573 if (f_v) {
4574 cout << "diophant::solve_first_mckay found " << _resultanz
4575 << " solutions, using " << nb_backtrack_nodes
4576 << " backtrack nodes" << endl;
4577 }
4578 _cur_result = 0;
4579 if (_resultanz == 0) {
4580 return FALSE;
4581 }
4582 res = _results.front();
4583 for (j = 0; j < n; j++) {
4584 x[j] = res[j];
4585 }
4586 _results.pop_front();
4587 _cur_result++;
4588 if (f_v) {
4589 cout << "diophant::solve_first_mckay done" << endl;
4590 }
4591 return TRUE;
4592}
4593
4594
4595
4596// #############################################################################
4597// callbacks and globals
4598// #############################################################################
4599
4600
4601static void diophant_callback_solution_found(int *sol, int len,
4602 int nb_sol, void *data)
4603{
4604 int f_v = FALSE;
4605 diophant *D = (diophant *) data;
4606 vector<int> lo;
4607 int i, j;
4608
4609 if ((nb_sol % 1000) == 0) {
4610 f_v = TRUE;
4611 }
4612 if (f_v) {
4613 cout << "diophant_callback_solution_found recording solution "
4614 << nb_sol << " len = " << len << " : ";
4615 Int_vec_print(cout, sol, len);
4616 cout << endl;
4617 cout << "D->_resultanz=" << D->_resultanz << endl;
4618
4619 for (i = 0; i < len; i++) {
4620 cout << 0 /*DLX_Cur_col[i]*/ << "/" << sol[i];
4621 if (i < len - 1) {
4622 cout << ", ";
4623 }
4624 }
4625 cout << endl;
4626 }
4627
4628 if (!D->test_solution(sol, len, 0 /* verbose_level */)) {
4629 cout << "diophant_callback_solution_found the solution "
4630 "is not a solution" << endl;
4631 exit(1);
4632 //return;
4633 }
4634 else {
4635 if (f_v) {
4636 cout << "diophant_callback_solution_found D->test_solution "
4637 "returns TRUE" << endl;
4638 }
4639 }
4640
4641
4642 lo.resize(D->n);
4643 for (j = 0; j < D->n; j++) {
4644 lo[j] = 0;
4645 }
4646 for (j = 0; j < len; j++) {
4647 lo[sol[j]] = 1;
4648 }
4649 D->_results.push_back(lo);
4650 D->_resultanz++;
4651
4652 if (diophant_user_callback_solution_found) {
4653 (*diophant_user_callback_solution_found)(sol, len, nb_sol, data);
4654 }
4655 //D->test_if_the_last_solution_is_unique();
4656}
4657
4658
4659}}}
4660
4661
4662
void set_complement(int *subset, int subset_size, int *complement, int &size_complement, int universal_set_size)
compact storage of 0/1-data as bitvectors
void init_simple(int underlying_set_size, int nb_sets, int verbose_level)
Definition: set_of_sets.cpp:67
a collection of functions related to sorted vectors
int int_vec_search(int *v, int len, int a, int &idx)
Definition: sorting.cpp:1094
functions related to strings and character arrays
void replace_extension_with(char *p, const char *new_ext)
a statistical analysis of data consisting of single integers
void init(int *data, int data_length, int f_second, int verbose_level)
Definition: tally.cpp:72
void init_lint(long int *data, int data_length, int f_second, int verbose_level)
Definition: tally.cpp:123
void init_no_colors(int nb_points, data_structures::bitvector *Bitvec, int f_ownership_of_bitvec, std::string &label, std::string &label_tex, int verbose_level)
void save(std::string &fname, int verbose_level)
void draw_bitmatrix(std::string &fname_base, graphics::layered_graph_draw_options *Draw_options, int f_dots, int f_partition, int nb_row_parts, int *row_part_first, int nb_col_parts, int *col_part_first, int f_row_grid, int f_col_grid, int f_bitmatrix, data_structures::bitmatrix *Bitmatrix, int *M, int m, int n, int f_has_labels, int *labels, int verbose_level)
a catch-all class for things related to 2D graphics
Definition: graphics.h:411
void draw_bitmap(draw_bitmap_control *C, int verbose_level)
options for drawing an object of type layered_graph
Definition: graphics.h:457
void int_matrix_write_csv(std::string &fname, int *M, int m, int n)
Definition: file_io.cpp:1300
void int_matrix_read_text(std::string &fname, int *&M, int &m, int &n)
Definition: file_io.cpp:1751
diophantine systems of equations (i.e., linear systems over the integers)
Definition: solvers.h:209
void make_clique_graph_adjacency_matrix(data_structures::bitvector *&Adj, int verbose_level)
Definition: diophant.cpp:4430
void get_solutions(long int *&Sol, int &nb_sol, int verbose_level)
Definition: diophant.cpp:1062
void trivial_row_reductions(int &f_no_solution, int verbose_level)
Definition: diophant.cpp:2427
void make_clique_graph(graph_theory::colored_graph *&CG, int verbose_level)
Definition: diophant.cpp:4478
void init_problem_of_Steiner_type_with_RHS(int nb_rows, int nb_cols, int *Inc, int nb_to_select, int *Rhs, int verbose_level)
Definition: diophant.cpp:375
int solve_all_DLX_with_RHS_and_callback(int f_write_tree, const char *fname_tree, void(*user_callback_solution_found)(int *sol, int len, int nb_sol, void *data), int verbose_level)
Definition: diophant.cpp:1353
void read_xml(std::ifstream &f, char *label, int verbose_level)
Definition: diophant.cpp:3722
void init_RHS(int RHS_value, int verbose_level)
Definition: diophant.cpp:435
void coefficient_values_in_row(int i, int &nb_values, int *&values, int *&multiplicities, int verbose_level)
Definition: diophant.cpp:2571
void project_to_two_equations(diophant *D, int eqn1_idx, int eqn2_idx, int verbose_level)
Definition: diophant.cpp:3629
int solve_first_mckay(int f_once, int verbose_level)
Definition: diophant.cpp:866
int test_solution(int *sol, int len, int verbose_level)
Definition: diophant.cpp:4213
int is_zero_outside(int first, int len, int i)
Definition: diophant.cpp:3334
void project_to_single_equation(diophant *D, int eqn_idx, int verbose_level)
Definition: diophant.cpp:3593
void print_eqn(int i, int f_with_gcd)
Definition: diophant.cpp:711
int solve_all_betten_with_conditions(int verbose_level, int f_max_sol, int max_sol, int f_max_time, int max_time_in_seconds)
Definition: diophant.cpp:1508
int j_fst(int j, int verbose_level)
Definition: diophant.cpp:1852
void draw_partitioned(std::string &fname_base, graphics::layered_graph_draw_options *Draw_options, int f_solution, int *solution, int solution_sz, int verbose_level)
Definition: diophant.cpp:4068
void read_solutions_from_file(std::string &fname_sol, int verbose_level)
Definition: diophant.cpp:1010
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 init_clique_finding_problem(int *Adj, int nb_pts, int nb_to_select, int verbose_level)
Definition: diophant.cpp:451
void solve_mckay(const char *label, int maxresults, long int &nb_backtrack_nodes, int &nb_sol, int verbose_level)
Definition: diophant.cpp:2155
int solve_all_DLX_with_RHS(int f_write_tree, const char *fname_tree, int verbose_level)
Definition: diophant.cpp:1279
void init_problem_of_Steiner_type(int nb_rows, int nb_cols, int *Inc, int nb_to_select, int verbose_level)
Definition: diophant.cpp:405
void write_solutions(std::string &fname, int verbose_level)
Definition: diophant.cpp:958
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 get_solutions_full_length(int *&Sol, int &nb_sol, int verbose_level)
Definition: diophant.cpp:1100
void make_clique_graph_and_save(std::string &clique_graph_fname, int verbose_level)
Definition: diophant.cpp:4504
void draw_as_bitmap(std::string &fname, int f_box_width, int box_width, int bit_depth, int verbose_level)
Definition: diophant.cpp:3974
void write_xml(std::ostream &ost, const char *label)
Definition: diophant.cpp:3682
void init_partition_problem_with_bounds(int *weights, int *bounds, int nb_weights, int target_value, int verbose_level)
Definition: diophant.cpp:345
void split_by_two_equations(int eqn1_idx, int eqn2_idx, int f_solve_case, int solve_case_idx_r, int solve_case_idx_m, int verbose_level)
Definition: diophant.cpp:3456
void project_to_single_equation_and_solve(int max_number_of_coefficients, int verbose_level)
Definition: diophant.cpp:3529
int j_nxt(int j, int verbose_level)
Definition: diophant.cpp:2074
void solve_mckay_override_minrhs_in_inequalities(const char *label, int maxresults, long int &nb_backtrack_nodes, int minrhs, int &nb_sol, int verbose_level)
Definition: diophant.cpp:2171
void eliminate_zero_rows_quick(int verbose_level)
Definition: diophant.cpp:3277
void get_coefficient_matrix(int *&M, int &nb_rows, int &nb_cols, int verbose_level)
Definition: diophant.cpp:2615
void eliminate_zero_rows(int *&eqn_number, int verbose_level)
Definition: diophant.cpp:3284
void join_problems(diophant *D1, diophant *D2, int verbose_level)
Definition: diophant.cpp:239
void draw_it(std::string &fname_base, graphics::layered_graph_draw_options *Draw_options, int verbose_level)
Definition: diophant.cpp:4043
void test_solution_full_length(int *sol, int verbose_level)
Definition: diophant.cpp:1132
std::deque< std::vector< int > > _results
Definition: solvers.h:242
void init_partition_problem(int *weights, int nb_weights, int target_value, int verbose_level)
Definition: diophant.cpp:317
void read_general_format(std::string &fname, int verbose_level)
Definition: diophant.cpp:3049
void get_columns(int *col, int nb_col, data_structures::set_of_sets *&S, int verbose_level)
Definition: diophant.cpp:4300
void write_gurobi_binary_variables(const char *fname)
Definition: diophant.cpp:3939
void test_solution_file(std::string &solution_file, int verbose_level)
Definition: diophant.cpp:4332
void split_by_equation(int eqn_idx, int f_solve_case, int solve_case_idx, int verbose_level)
Definition: diophant.cpp:3388
diophant * trivial_column_reductions(int verbose_level)
Definition: diophant.cpp:2467
void init_var_labels(long int *labels, int verbose_level)
Definition: diophant.cpp:224
void save_in_general_format(std::string &fname, int verbose_level)
Definition: diophant.cpp:2879
description of a problem instance for dancing links solver
Definition: solvers.h:406
An implementation of Donald Knuth's dancing links algorithm to solve exact cover problems.
Definition: solvers.h:449
void init(dlx_problem_description *Descr, int verbose_level)
Definition: dlx_solver.cpp:98
void install_callback_solution_found(void(*callback_solution_found)(int *solution, int len, int nb_sol, void *data), void *callback_solution_found_data)
Definition: dlx_solver.cpp:154
solves diophantine systems according to McKay
Definition: solvers.h:616
void possolve(std::vector< int > &lo, std::vector< int > &hi, std::vector< equation > &eqn, std::vector< int > &lorhs, std::vector< int > &hirhs, std::vector< int > &neqn, int numeqn, int numvar, int verbose_level)
Definition: mckay.cpp:66
void Init(diophant *lgs, const char *label, int aEqnAnz, int aVarAnz)
Definition: mckay.cpp:41
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define NEW_pchar(n)
Definition: foundations.h:635
#define FREE_pchar(p)
Definition: foundations.h:648
#define MINIMUM(x, y)
Definition: foundations.h:216
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define Int_vec_print_fully(A, B, C)
Definition: foundations.h:687
#define ONE_MILLION
Definition: foundations.h:226
#define NEW_char(n)
Definition: foundations.h:632
#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 Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Lint_vec_copy_to_int(A, B, C)
Definition: foundations.h:723
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_char(p)
Definition: foundations.h:646
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define MAXIMUM(x, y)
Definition: foundations.h:217
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects