Orbiter 2022
Combinatorial Objects
search_blocking_set.cpp
Go to the documentation of this file.
1// search_blocking_set.cpp
2//
3// Anton Betten
4// started in INC_CAN: July 14, 2010
5// moved to TOP_LEVEL: Nov 2, 2010
6// added active_set: Nov 3, 2010
7//
8//
9//
10
11#include "orbiter.h"
12
13using namespace std;
14
15namespace orbiter {
16namespace layer5_applications {
17namespace apps_geometry {
18
19
20
22{
23 Inc = NULL;
24 A = NULL;
25 Control = NULL;
26 Poset = NULL;
27 gen = NULL;
28
29
30 Line_intersections = NULL;
31 blocking_set = NULL;
33 sz = NULL;
34
35 active_set = NULL;
36 sz_active_set = NULL;
37
38
39 nb_solutions = 0;
43
46 search_cur = NULL;
47 search_candidates = NULL;
48 save_sz = NULL;
49}
50
52{
53 freeself();
54}
55
57{
58}
59
61{
62 int i;
63
66 }
67 if (Control) {
69 }
70 if (Poset) {
72 }
73 if (gen) {
75 }
76 if (blocking_set) {
78 }
79 if (sz) {
80 FREE_int(sz);
81 }
82 if (active_set) {
84 }
85 if (sz_active_set) {
87 }
89 for (i = 0; i < max_search_depth; i++) {
90 if (search_candidates[i]) {
92 search_candidates[i] = NULL;
93 }
94 }
96 }
99 }
100 if (search_cur) {
102 }
103 if (save_sz) {
104 for (i = 0; i < max_search_depth; i++) {
105 if (save_sz[i]) {
106 FREE_int(save_sz[i]);
107 save_sz[i] = NULL;
108 }
109 }
111 }
112 null();
113}
114
117 actions::action *A, int verbose_level)
118{
119 int f_v = (verbose_level >= 1);
120 int j;
121
122 if (f_v) {
123 cout << "search_blocking_set::init" << endl;
124 }
127
129 for (j = 0; j < Inc->nb_cols; j++) {
131 }
132
134 sz = NEW_int(Inc->nb_cols);
135
139}
140
141void search_blocking_set::find_partial_blocking_sets(int depth, int verbose_level)
142{
143 int f_v = (verbose_level >= 1);
144 int t0;
146
147 t0 = Os.os_ticks();
148
149
150 if (f_v) {
151 cout << "search_blocking_set::find_partial_blocking_sets" << endl;
152 }
153
154
155
156 //sprintf(gen->fname_base, "blocking_set");
157
158
159
160 if (f_v) {
161 cout << "find_blocking_sets calling gen->init" << endl;
162 }
163
165 cout << "find_partial_blocking_sets !A->f_has_strong_generators" << endl;
166 exit(1);
167 }
171
174 A->Strong_gens,
175 verbose_level);
176
178
180 Inc->nb_rows, verbose_level);
181
182#if 0
183 // ToDo
184 gen->init_check_func(
185 callback_check_partial_blocking_set,
186 this /* candidate_check_data */);
187#endif
188
189 //gen->init_incremental_check_func(
190 //check_mindist_incremental,
191 //this /* candidate_check_data */);
192
193 //gen->f_its_OK_to_not_have_an_early_test_func = TRUE;
194
195#if 0
196 gen->f_print_function = TRUE;
197 gen->print_function = print_set;
198 gen->print_function_data = this;
199#endif
200
201 int schreier_depth = Inc->nb_rows;
202 int f_use_invariant_subset_if_available = TRUE;
203 int f_debug = FALSE;
204
205
206 if (f_v) {
207 cout << "find_partial_blocking_sets: calling generator_main" << endl;
208 }
209 gen->main(t0,
210 schreier_depth,
211 f_use_invariant_subset_if_available,
212 f_debug,
213 verbose_level - 1);
214
215 if (f_v) {
216 cout << "find_partial_blocking_sets: done with generator_main" << endl;
217 }
218}
219
220int search_blocking_set::test_level(int depth, int verbose_level)
221{
222 int f_v = (verbose_level >= 1);
223 int f_OK;
224 int nb_orbits, f, h;
225
226 if (f_v) {
227 cout << "search_blocking_set::test_level: testing all partial "
228 "blocking sets at level " << depth << endl;
229 }
230 f = gen->first_node_at_level(depth);
231 nb_orbits = gen->nb_orbits_at_level(depth);
232 if (f_v) {
233 cout << "search_blocking_set::test_level: we found " << nb_orbits
234 << " orbits on partial blocking sets "
235 "of size " << depth << endl;
236 }
237 f_OK = FALSE;
238 for (h = 0; h < nb_orbits; h++) {
239 gen->get_node(f + h)->store_set_to(gen, depth - 1, blocking_set);
240
241 if (f_v) {
242 cout << "testing set " << h << " / " << nb_orbits << " : ";
243 Lint_vec_print(cout, blocking_set, depth);
244 cout << endl;
245 }
246
247 blocking_set_len = depth;
248
249 f_OK = test_blocking_set(depth, blocking_set, verbose_level);
250
251 if (f_OK) {
252 if (f_v) {
253 cout << "found blocking set" << endl;
254 }
255 break;
256 }
257 else {
258 if (f_v) {
259 cout << endl;
260 }
261 }
262 }
263 if (f_OK) {
264 return TRUE;
265 }
266 return FALSE;
267}
268
269int search_blocking_set::test_blocking_set(int len, long int *S, int verbose_level)
270// computes all Line_intersections[] sets based on the set S[len],
271// uses Inc->lines_on_point[]
272// tests if Line_intersections[j] is greater than zero
273// but less than Inc->nb_points_on_line[j] for all j
274{
275 int f_OK = TRUE;
276 int f_v = (verbose_level >= 1);
277 int i, j, h, a;
278
279 if (f_v) {
280 cout << "search_blocking_set::test_blocking_set "
281 "checking set of points ";
282 Lint_vec_print(cout, S, len);
283 cout << endl;
284 }
285
286 for (j = 0; j < Inc->nb_cols; j++) {
287 Line_intersections[j].k = 0;
288 }
289 for (h = 0; h < len; h++) {
290 i = S[h];
291 for (a = 0; a < Inc->nb_lines_on_point[i]; a++) {
292 j = Inc->lines_on_point[i * Inc->max_r + a];
294 }
295 }
296 for (j = 0; j < Inc->nb_cols; j++) {
297 sz[j] = Line_intersections[j].k;
298 }
299
300 if (f_v) {
302
303 C.init(sz, Inc->nb_cols, FALSE, 0);
304
305 cout << "the line type is:";
306 C.print(FALSE /*f_backwards*/);
307 }
308
309 for (j = 0; j < Inc->nb_cols; j++) {
310 a = Line_intersections[j].k;
311 if (a == 0) {
312 f_OK = FALSE;
313 if (f_v) {
314 cout << "not OK, line " << j << " is disjoint" << endl;
315 }
316 break;
317 }
318 if (a >= Inc->nb_points_on_line[j]) {
319 f_OK = FALSE;
320 if (f_v) {
321 cout << "not OK, line " << j
322 << " is completely contained" << endl;
323 }
324 goto done;
325 }
326 }
327 for (h = 0; h < len; h++) {
328 i = S[h];
329 for (a = 0; a < Inc->nb_lines_on_point[i]; a++) {
330 j = Inc->lines_on_point[i * Inc->max_r + a];
331 if (Line_intersections[j].k == 1) {
332 break;
333 }
334 }
335 if (a == Inc->nb_lines_on_point[i]) {
336 f_OK = FALSE;
337 if (f_v) {
338 cout << "not OK, point S[" << h << "]=" << i
339 << " is not on a 1-line" << endl;
340 }
341 goto done;
342 }
343 }
344done:
345 return f_OK;
346}
347
349 int len, long int *S, int verbose_level)
350{
351 int f_OK = TRUE;
352 int f_v = (verbose_level >= 1);
353 int i, j, h, a;
354
355 if (f_v) {
356 cout << "search_blocking_set::test_blocking_set_upper_bound_only "
357 "set of points ";
358 Lint_vec_print(cout, S, len);
359 cout << endl;
360 }
361
362 for (j = 0; j < Inc->nb_cols; j++) {
363 Line_intersections[j].k = 0;
364 }
365 for (h = 0; h < len; h++) {
366 i = S[h];
367 //cout << "adding line pencil of point " << i << " of size "
368 //<< Inc->nb_lines_on_point[i] << endl;
369 for (a = 0; a < Inc->nb_lines_on_point[i]; a++) {
370 j = Inc->lines_on_point[i * Inc->max_r + a];
371 //cout << "adding point " << i << " to line " << j << endl;
373 }
374 }
375 for (j = 0; j < Inc->nb_cols; j++) {
376 sz[j] = Line_intersections[j].k;
377 }
378
379 if (f_v) {
381
382 C.init(sz, Inc->nb_cols, FALSE, 0);
383
384 cout << "the line type is:";
385 C.print(FALSE /*f_backwards*/);
386 }
387
388 for (j = 0; j < Inc->nb_cols; j++) {
389 a = Line_intersections[j].k;
390 if (a >= Inc->nb_points_on_line[j]) {
391 f_OK = FALSE;
392 if (f_v) {
393 cout << "not OK, line " << j
394 << " is completely contained" << endl;
395 }
396 goto done;
397 }
398 }
399 for (h = 0; h < len; h++) {
400 i = S[h];
401 for (a = 0; a < Inc->nb_lines_on_point[i]; a++) {
402 j = Inc->lines_on_point[i * Inc->max_r + a];
403 if (Line_intersections[j].k == 1) {
404 break;
405 }
406 }
407 if (a == Inc->nb_lines_on_point[i]) {
408 f_OK = FALSE;
409 if (f_v) {
410 cout << "not OK, point S[" << h << "]=" << i
411 << " is not on a 1-line" << endl;
412 }
413 goto done;
414 }
415 }
416done:
417 return f_OK;
418}
419
420
422 int level, int f_all, int verbose_level)
423{
424 int f_v = (verbose_level >= 1);
425 int f, nb_orbits, h, u, i, a, b, j;
426
427 if (f_v) {
428 cout << "search_blocking_set::search_for_blocking_set: "
429 "input_no=" << input_no << " testing all partial "
430 "blocking sets at level " << level << endl;
431 cout << "f_all=" << f_all << endl;
432 }
433
434 max_search_depth = Inc->nb_rows - level;
439 for (i = 0; i < max_search_depth; i++) {
441 save_sz[i] = NEW_int(Inc->nb_cols);
442 }
443
444
445 nb_solutions = 0;
446
447 if (f_all) {
449 }
450 else {
452 }
453
454 f = gen->first_node_at_level(level);
455 nb_orbits = gen->nb_orbits_at_level(level);
456 if (f_v) {
457 cout << "search_blocking_set::search_for_blocking_set: "
458 "we found " << nb_orbits << " orbits on partial "
459 "blocking sets of size" << level << endl;
460 }
461 for (h = 0; h < nb_orbits; h++) {
462 gen->get_node(f + h)->store_set_to(gen, level - 1, blocking_set);
463
464 if (f_v) {
465 cout << "input_no " << input_no << " level " << level
466 << " testing set " << h << " / " << nb_orbits << " : ";
467 Lint_vec_print(cout, blocking_set, level);
468 cout << endl;
469 }
470
471 blocking_set_len = level;
472
473 if (level) {
474 b = blocking_set[level - 1];
475 }
476 else {
477 b = -1;
478 }
479 for (i = b + 1; i < Inc->nb_rows; i++) {
481 }
483 if (f_v) {
484 cout << "sz_active_set[0]=" << sz_active_set[0] << endl;
485 }
486
487 for (j = 0; j < Inc->nb_cols; j++) {
488 Line_intersections[j].k = 0;
489 }
490 for (u = 0; u < level; u++) {
491 i = blocking_set[u];
492 //cout << "adding line pencil of point " << i << " of size "
493 //<< Inc->nb_lines_on_point[i] << endl;
494 for (a = 0; a < Inc->nb_lines_on_point[i]; a++) {
495 j = Inc->lines_on_point[i * Inc->max_r + a];
496 //cout << "adding point " << i << " to line " << j << endl;
498 }
499 }
500
501
503 level, 0, verbose_level - 4);
504
505 if (f_v) {
506 cout << "input_no " << input_no << " level " << level
507 << " testing set " << h << " / " << nb_orbits << " : ";
508 cout << " done" << endl;
509 }
510
511
513 break;
514 }
515 }
516
517
518 if (f_v) {
519 cout << "search_blocking_set::search_for_blocking_set done, "
520 "we found " << nb_solutions << " solutions" << endl;
521 }
522}
523
525 int input_no, int starter_level, int level,
526 int verbose_level)
527{
528 int f_v = (verbose_level >= 1);
529 int j;
530 int t0_first, t0_len, t, line_idx, i, a, b;
531
532 if (f_v) {
533 cout << "search_blocking_set::recursive_search_for_blocking_set "
534 "input_no = " << input_no << " level = " << level
535 << " sz_active_set = " << active_set->k << endl;
536 Lint_vec_print(cout, blocking_set, starter_level + level);
537 cout << endl;
538 }
540 if (starter_level + level > blocking_set_size_desired) {
541 if (f_v) {
542 cout << "we backtrack since we reached the "
543 "desired size" << endl;
544 }
545 return TRUE;
546 }
547 }
548
549 for (j = 0; j < Inc->nb_cols; j++) {
550 sz[j] = Line_intersections[j].k;
551 }
553
554 C.init(sz, Inc->nb_cols, FALSE, 0);
555
556 if (f_v) {
557 cout << "the current line type is:";
558 C.print(FALSE /*f_backwards*/);
559 }
560 for (j = 0; j < Inc->nb_cols; j++) {
561 if (sz[j] == Inc->nb_points_on_line[j]) {
562 // backtrack, since one line is contained in the blocking set
563 if (f_v) {
564 cout << "we backtrack since line " << j
565 << " is contained in the blocking set" << endl;
566 }
567 return TRUE;
568 }
569 }
570
571 t0_first = C.type_first[0];
572 t0_len = C.type_len[0];
573 t = C.data_sorted[t0_first];
574 if (t) {
575 cout << "found blocking set of size "
576 << starter_level + level << " : ";
577 Lint_vec_print(cout, blocking_set, starter_level + level);
578 cout << " line type = ";
579 C.print(FALSE /*f_backwards*/);
580 cout << " : solution no " << nb_solutions + 1;
581 cout << " : ";
582 for (i = 0; i < level; i++) {
583 cout << i << ":" << search_cur[i] << "/"
584 << search_nb_candidates[i] << " ";
585 }
586 cout << endl;
587
588
589 vector<int> sol;
590
591 sol.resize(starter_level + level);
592 for (j = 0; j < starter_level + level; j++) {
593 sol[j] = (int) blocking_set[j];
594 }
595 solutions.push_back(sol);
596
597 nb_solutions++;
598
599 if (f_find_only_one) {
600 return FALSE;
601 }
602 else {
603 return TRUE;
604 }
605 }
606 else {
607 if (f_v) {
608 cout << "there are " << t0_len << " 0-lines" << endl;
609 }
610 }
611 line_idx = C.sorting_perm_inv[t0_first];
612 if (f_v) {
613 cout << "line_idx=" << line_idx << endl;
614 }
615 if (Line_intersections[line_idx].k != 0) {
616 cout << "Line_intersections[line_idx].k != 0" << endl;
617 exit(1);
618 }
619 j = 0;
620 for (i = 0; i < Inc->nb_points_on_line[line_idx]; i++) {
621 a = Inc->points_on_line[line_idx * Inc->max_k + i];
622 if (active_set->is_contained(a)) {
623 search_candidates[level][j++] = a;
624 }
625 }
626 search_nb_candidates[level] = j;
627
628 for (search_cur[level] = 0;
629 search_cur[level] < search_nb_candidates[level];
630 search_cur[level]++) {
631
632
634
635
636 a = search_candidates[level][search_cur[level]];
637
638 blocking_set[starter_level + level] = a;
639
640 for (b = 0; b < Inc->nb_lines_on_point[a]; b++) {
641 j = Inc->lines_on_point[a * Inc->max_r + b];
642 //cout << "adding point " << i << " to line " << j << endl;
644 }
645
647 sz_active_set[level + 1] = active_set->k;
648
650 starter_level, level + 1, verbose_level)) {
651 return FALSE;
652 }
653 else {
654 active_set->k = sz_active_set[level + 1];
655 }
656
657
659
660 }
661 return TRUE;
662}
663
665{
666 int j;
667
668 for (j = 0; j < Inc->nb_cols; j++) {
669 save_sz[level][j] = Line_intersections[j].k;
670 }
671}
672
674{
675 int j;
676
677 for (j = 0; j < Inc->nb_cols; j++) {
678 Line_intersections[j].k = save_sz[level][j];
679 }
680}
681
682
683#if 0
684int callback_check_partial_blocking_set(int len, int *S,
685 void *data, int verbose_level)
686{
688 int f_OK = TRUE;
689 int f_v = (verbose_level >= 1);
690
691 if (f_v) {
692 cout << "check_partial_blocking_set: checking set of points ";
693 print_set(cout, len, S);
694 cout << endl;
695 }
696
697 if (len && S[len - 1] >= SBS->Inc->nb_rows) {
698 return FALSE;
699 }
700
701 //cout << "before SBS->test_blocking_set_upper_bound_only" << endl;
702 f_OK = SBS->test_blocking_set_upper_bound_only(len, S, verbose_level);
703
704
705
706 if (f_OK) {
707 if (f_v) {
708 cout << "OK" << endl;
709 }
710 return TRUE;
711 }
712 else {
713 return FALSE;
714 }
715}
716#endif
717
718}}}
719
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
interface for various incidence geometries
Definition: geometry.h:1099
a permutation group in a fixed action.
Definition: actions.h:99
groups::strong_generators * Strong_gens
Definition: actions.h:130
to control the behavior of the poset classification algorithm
void initialize_and_allocate_root_node(poset_classification_control *PC_control, poset_with_group_action *Poset, int depth, int verbose_level)
int main(int t0, int schreier_depth, int f_use_invariant_subset_if_available, int f_debug, int verbose_level)
void store_set_to(poset_classification *gen, int i, long int *to)
void init_subset_lattice(actions::action *A, actions::action *A2, groups::strong_generators *Strong_gens, int verbose_level)
classification of blocking sets in projective planes
Definition: tl_geometry.h:798
int recursive_search_for_blocking_set(int input_no, int starter_level, int level, int verbose_level)
poset_classification::poset_classification * gen
Definition: tl_geometry.h:804
int test_blocking_set_upper_bound_only(int len, long int *S, int verbose_level)
int test_blocking_set(int len, long int *S, int verbose_level)
void init(geometry::incidence_structure *Inc, actions::action *A, int verbose_level)
void search_for_blocking_set(int input_no, int level, int f_all, int verbose_level)
poset_classification::poset_classification_control * Control
Definition: tl_geometry.h:802
poset_classification::poset_with_group_action * Poset
Definition: tl_geometry.h:803
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define FREE_int(p)
Definition: foundations.h:640
#define NEW_pint(n)
Definition: foundations.h:627
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
#define FREE_pint(p)
Definition: foundations.h:641
the orbiter library for the classification of combinatorial objects