treewalk.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <chrono>
  4. #include <cmath>
  5. #include <cpuid.h>
  6. #include <fstream>
  7. #include "treewalk.hpp"
  8. using namespace std;
  9. using namespace std::chrono;
  10. fstream file;
  11. void treat(const monoid& m){
  12. // output(m,file);
  13. //return;
  14. // int w=m.e*m.left-m.conductor;
  15. int q=ceil(float(m.conductor)/float(m.min));
  16. unsigned int rho=q*m.min-m.conductor;
  17. if(m.wilf<=rho){
  18. if((m.wilf<0) or (m.wilf<=rho and m.e>2 and m.left_primitive>1 and q>=4)){
  19. output(m,file);
  20. }
  21. }
  22. }
  23. //static const int mcut=ceil(float(3*(MAX_GENUS+2))/5);
  24. bool cut(const monoid& m){
  25. if(3*m.left_primitive>=m.min) return true;
  26. return false;
  27. }
  28. #define STACK_SIZE (MAX_GENUS*(MAX_GENUS+1))/2
  29. void walk(int m,int k)
  30. {
  31. monoid data[STACK_SIZE], *stack[STACK_SIZE], *current,temp,temp2;
  32. size_t stack_size=0;
  33. for (ind_t i=0; i<STACK_SIZE; i++) stack[i] = &(data[i]);
  34. init_ordinary(data[0],m);
  35. for(int i=0;i<k;++i){
  36. auto it = generator_iter<CHILDREN>(data[i]);
  37. it.move_next();
  38. ind_t pos=0;
  39. if(i==0){
  40. it.move_next();
  41. pos=1;
  42. }
  43. remove_generator(data[i+1],data[i],it.get_gen(),pos);
  44. }
  45. //Root @ data[k]
  46. temp=data[k];
  47. cout<<"Root : ";
  48. print_monoid_gen(temp);
  49. auto it = generator_iter<CHILDREN>(temp);
  50. it.move_next();
  51. ind_t pos=0;
  52. if(k==0){
  53. it.move_next();
  54. ++pos;
  55. }
  56. while (it.move_next()){
  57. remove_generator(*stack[stack_size], temp, it.get_gen(),pos++);
  58. cout<<"Pop "<<it.get_gen()<<" : ";
  59. print_monoid_gen(*stack[stack_size]);
  60. treat(*stack[stack_size]);
  61. ++stack_size;
  62. }
  63. while (stack_size != 0)
  64. {
  65. current = stack[--stack_size];
  66. /*if(current->conductor>=35){
  67. cout<<"Pop ";
  68. print_monoid_gen(*current);
  69. }*/
  70. if(not cut(*current))
  71. {
  72. if (current->genus < MAX_GENUS - 1)
  73. {
  74. auto it = generator_iter<CHILDREN>(*current);
  75. ind_t pos=0;
  76. while (it.move_next())
  77. {
  78. swap(stack[stack_size],stack[stack_size+1]);
  79. //Current is tored @ stack_size+1
  80. remove_generator(*stack[stack_size], *current, it.get_gen(),pos++);
  81. treat(*stack[stack_size]);
  82. ++stack_size;
  83. }
  84. }
  85. else
  86. {
  87. auto it = generator_iter<CHILDREN>(*current);
  88. ind_t pos=0;
  89. while (it.move_next())
  90. {
  91. remove_generator(temp2, *current, it.get_gen(),pos++);
  92. temp2.conductor=0;
  93. treat(temp2);
  94. }
  95. }
  96. }
  97. }
  98. }
  99. int main(int argc, char **argv)
  100. {
  101. if(argc!=4){
  102. cerr<<"Usage : "<<argv[0]<<" [m] [k] filename with k in [0,MAX_GENUS-m]"<<endl;
  103. exit(-1);
  104. }
  105. int m=atoi(argv[1]);
  106. int k=atoi(argv[2]);
  107. char* filename_base=argv[3];
  108. if(k<0 or k>=MAX_GENUS-m){
  109. cerr<<"k must be in [0,MAX_GENUS-m]"<<endl;
  110. exit(-2);
  111. }
  112. unsigned int ax, bx, cx, dx;
  113. if (!__get_cpuid(0x00000001, &ax, &bx, &cx, &dx))
  114. {
  115. cerr << "Unable to determine the processor type !" << endl;
  116. return EXIT_FAILURE;
  117. }
  118. if (!(cx & bit_SSSE3))
  119. {
  120. cerr << "This programm require sse3 instructions set !" << endl;
  121. return EXIT_FAILURE;
  122. }
  123. if (!(cx & bit_POPCNT))
  124. {
  125. cerr << "This programm require popcount instruction !" << endl;
  126. return EXIT_FAILURE;
  127. }
  128. cout << "Testing Wilf's conjecture for numerical semigroups of genus <= "
  129. << MAX_GENUS << " for m="<<m<<" and k="<<k<<"."<<endl;
  130. /*cerr << "Testing Wilf's conjecture for numerical semigroups of genus <= "
  131. << MAX_GENUS << " for m="<<m<<" and k="<<k<<"."<<endl;*/
  132. auto begin = high_resolution_clock::now();
  133. string filename=string(filename_base)+"_wilf_"+to_string(m)+"_"+to_string(k);
  134. file.open(filename.c_str(),ios::out|ios::trunc);
  135. walk(m,k);
  136. auto end = high_resolution_clock::now();
  137. duration<double> ticks = end-begin;
  138. cout << " Computation time = " << std::setprecision(4) << ticks.count() << " s." << endl;
  139. file.close();
  140. return EXIT_SUCCESS;
  141. }