При отладке последней программы заметил, что под конец работы добавление нового проверяющего простого делителя к списку работающий делителей происходит чуть ли не раз в несколько десятков сегментов. Это знание не давало мне покоя, поэтому я стал разбираться что к чему.
Конкретно с этим вопросом, конечно, оказалось всё просто. Если взять, например, 4000-й простой делитель (для моего диапазона их всего 4792), то его значение
. А следующий за ним:
, расстояние равно 18. Поскольку простой делитель подключается в работу, когда его квадрат попадает в сегмент, то всё дело в расстоянии между квадратами. Его можно оценить как удвоенное значение делителя умножить на расстояние до него, то есть
. Эта величина как раз соответствует 26 эффективным размерам сегмента решета:
. В среднем же статистика расстояний в диапазоне номеров делителей от 3000 до 4000 такая:
Код:
2 134 13,40%
4 118 11,80%
6 208 20,80%
8 76 7,60%
10 98 9,80%
12 107 10,70%
14 40 4,00%
16 35 3,50%
18 60 6,00%
20 27 2,70%
22 32 3,20%
24 11 1,10%
26 11 1,10%
28 6 0,60%
30 17 1,70%
Others 20 2,00%
10.374
В процессе я осознал один интересный факт: для проверяющих простых делителей в диапазоне
(где
L — это верхняя граница искомых простых чисел) составные числа, эффективно вычёркиваемые этими делителями (то есть не вычёркиваемые делителями до
) являются произведениями двух простых чисел, одно из которых — проверяющий делитель
, а номер
m второго простого числа лежит на отрезке
, где
— это та самая функция распределения простых чисел. Имея таблицу этих чисел её, кстати, очень легко посчитать:
public static int findPi(int value) {
int result = Arrays.binarySearch(primesList, value);
if (0 <= result) {
return 1 + result;
} else {
return -1 - result;
}
}
Это знание предоставляет практическую возможность посчитать количество составных чисел, вычёркиваемых простым делителем
. Это число равно
. А просуммировав эти значения в диапазоне от
N до 4792 можно посчитать полное число составных чисел, вычёркиваемых простыми делителями начиная с
.
Однако всё познаётся в сравнении, просто числа ничего не дадут. Этот результат, очевидно, надо сравнивать с количеством обращений ко всем простым делителям от
N до 4792, которые производятся в цикле программы. При обработке каждого сегмента решета происходит одно обращение к работающим простым делителям. Делитель
начинает работать, когда его квадрат попадает в сегмент, то есть начиная с сегмента
. Номер же последнего сегмента:
. Для расчёта, разумеется, составил программу. Результаты получились такие:
(Оффтоп)
Код:
1300 10657 19588199 84106010
1325 10891 19172744 83129352
1350 11149 18766970 82155278
1375 11393 18370438 81183785
1400 11657 17982999 80215010
1425 11897 17605026 79249193
1450 12109 17234555 78285889
1475 12347 16871818 77325277
1500 12553 16516433 76367412
1525 12791 16167563 75412024
1550 13007 15825727 74459611
1575 13249 15490199 73509979
1600 13499 15161580 72563515
1625 13729 14839796 71620377
1650 13967 14523681 70680103
1675 14251 14214156 69743313
1700 14519 13911752 68810375
1725 14737 13614964 67880676
1750 14947 13323150 66953923
1775 15199 13036715 66030741
1800 15401 12755385 65110839
1825 15647 12478934 64194260
1850 15881 12207365 63281054
1875 16103 11940859 62371524
1900 16381 11679366 61465896
1925 16649 11422920 60564471
1950 16903 11171500 59667164
1975 17137 10924564 58773872
2000 17389 10682228 57884809
2025 17609 10443942 56999478
2050 17891 10210092 56118403
2075 18119 9980464 55241521
2100 18313 9754509 54368526
2125 18553 9532235 53499471
2150 18899 9314372 52635426
2175 19181 9101047 51777015
2200 19423 8891762 50923591
2225 19609 8685562 50073998
2250 19891 8483149 49229344
2275 20117 8284087 48389286
2300 20357 8088241 47553601
2325 20627 7895764 46722727
2350 20897 7706926 45897360
2375 21139 7521172 45076954
2400 21383 7338763 44261489
2425 21599 7159456 43451136
2450 21841 6983014 42645391
2475 22079 6809588 41844873
2500 22307 6638820 41049142
2525 22613 6471165 40259128
2550 22817 6306574 39474576
2575 23059 6144823 38695502
2600 23321 5985799 37921428
2625 23599 5829913 37153689
2650 23827 5676601 36391371
2675 24049 5525922 35634282
2700 24281 5377703 34882099
2725 24571 5232190 34136608
2750 24877 5089643 33398158
2775 25147 4949824 32666293
2800 25391 4812487 31940631
2825 25643 4677659 31221313
2850 25913 4545162 30508109
2875 26161 4415015 29801224
2900 26399 4287302 29100580
2925 26683 4162031 28406475
2950 26891 4039072 27718586
2975 27127 3918333 27036769
3000 27449 3800013 26362472
3025 27739 3684132 25696027
3050 27947 3570444 25035790
3075 28211 3458806 24382035
3100 28499 3349478 23736149
3125 28687 3242190 23096748
3150 28933 3136770 22463187
3175 29207 3033570 21837273
3200 29443 2932333 21218335
3225 29753 2833169 20606887
3250 30059 2736279 20004027
3275 30293 2641575 19408985
3300 30559 2548957 18821677
3325 30841 2458459 18242580
3350 31091 2369714 17670911
3375 31319 2282753 17106505
3400 31601 2197550 16549619
3425 31883 2114295 16001220
3450 32159 2033207 15462035
3475 32377 1953905 14930395
3500 32609 1876115 14405498
3525 32887 1800123 13888378
3550 33113 1725967 13379383
3575 33377 1653498 12878439
3600 33613 1582599 12385608
3625 33851 1513263 11899818
3650 34157 1445829 11422737
3675 34381 1380119 10954953
3700 34649 1315954 10495166
3725 34897 1253417 10043646
3750 35159 1192633 9601563
3775 35447 1133436 9168594
3800 35759 1075882 8744772
3825 36007 1020011 8331392
3850 36277 965702 7926616
3875 36551 913173 7531620
3900 36781 862124 7145349
3925 37013 812533 6767099
3950 37309 764549 6398110
3975 37547 718142 6038990
4000 37813 673209 5688135
4025 38119 630072 5348258
4050 38371 588567 5019038
4075 38677 548729 4700636
4100 38921 510327 4391478
4125 39181 473357 4092163
4150 39419 437736 3801957
4175 39719 403691 3522098
4200 39971 371045 3252402
4225 40231 339837 2992706
4250 40531 310148 2744584
4275 40829 281996 2507918
4300 41081 255214 2281497
4325 41333 229738 2064962
4350 41603 205651 1859001
4375 41851 182971 1662853
4400 42073 161699 1476770
4425 42331 141690 1300552
4450 42557 122849 1133606
4475 42793 105274 976807
4500 43051 89005 829984
4525 43399 74186 695341
4550 43661 60862 574062
4575 43969 48926 464536
4600 44201 38319 365933
4601 44203 37921 362206
4602 44207 37524 358483
4603 44221 37128 354767
4604 44249 36735 351074
4605 44257 36346 347429
4606 44263 35959 343798
4607 44267 35574 340177
4608 44269 35190 336563
4609 44273 34807 332952
4610 44279 34425 329348
4611 44281 34044 325754
4612 44293 33665 322163
4613 44351 33289 318593
4614 44357 32920 315122
4615 44371 32552 311661
4616 44381 32188 308224
4617 44383 31826 304804
4618 44389 31465 301387
4619 44417 31106 297981
4620 44449 30750 294622
4621 44453 30397 291318
4622 44483 30047 288021
4623 44491 29700 284775
4624 44497 29355 281543
4625 44501 29011 278321
4626 44507 28669 275106
4627 44519 28328 271901
4628 44531 27990 268717
4629 44533 27653 265553
4630 44537 27317 262393
4631 44543 26983 259240
4632 44549 26650 256097
4633 44563 26318 252964
4634 44579 25989 249855
4635 44587 25663 246774
4636 44617 25338 243706
4637 44621 25016 240690
4638 44623 24696 237681
4639 44633 24377 234675
4640 44641 24061 231686
4641 44647 23747 228711
4642 44651 23434 225746
4643 44657 23122 222788
4644 44683 22812 219841
4645 44687 22505 216938
4646 44699 22199 214042
4647 44701 21895 211167
4648 44711 21592 208295
4649 44729 21290 205440
4650 44741 20992 202616
4651 44753 20695 199813
4652 44771 20399 197031
4653 44773 20107 194280
4654 44777 19816 191532
4655 44789 19527 188791
4656 44797 19241 186071
4657 44809 18957 183364
4658 44819 18675 180678
4659 44839 18395 178009
4660 44843 18118 175375
4661 44851 17842 172748
4662 44867 17568 170134
4663 44879 17296 167548
4664 44887 17026 164983
4665 44893 16758 162432
4666 44909 16492 159891
4667 44917 16228 157378
4668 44927 15965 154878
4669 44939 15705 152396
4670 44953 15448 149934
4671 44959 15194 147497
4672 44963 14941 145070
4673 44971 14689 142650
4674 44983 14438 140244
4675 44987 14190 137858
4676 45007 13944 135479
4677 45013 13700 133135
4678 45053 13459 130801
4679 45061 13222 128537
4680 45077 12987 126287
4681 45083 12755 124064
4682 45119 12525 121852
4683 45121 12300 119702
4684 45127 12076 117556
4685 45131 11854 115420
4686 45137 11633 113291
4687 45139 11414 111172
4688 45161 11196 109057
4689 45179 10981 106980
4690 45181 10769 104934
4691 45191 10558 102892
4692 45197 10350 100867
4693 45233 10143 98853
4694 45247 9942 96901
4695 45259 9742 94974
4696 45263 9544 93067
4697 45281 9347 91167
4698 45289 9153 89299
4699 45293 8961 87445
4700 45307 8771 85598
4701 45317 8583 83775
4702 45319 8397 81970
4703 45329 8213 80168
4704 45337 8031 78383
4705 45341 7850 76612
4706 45343 7671 74848
4707 45361 7493 73088
4708 45377 7318 71359
4709 45389 7145 69658
4710 45403 6974 67978
4711 45413 6806 66323
4712 45427 6641 64685
4713 45433 6479 63071
4714 45439 6319 61468
4715 45481 6160 59875
4716 45491 6005 58356
4717 45497 5852 56854
4718 45503 5700 55363
4719 45523 5549 53882
4720 45533 5400 52436
4721 45541 5252 51008
4722 45553 5106 49594
4723 45557 4964 48201
4724 45569 4823 46815
4725 45587 4685 45450
4726 45589 4551 44117
4727 45599 4418 42787
4728 45613 4286 41475
4729 45631 4157 40187
4730 45641 4029 38931
4731 45659 3904 37692
4732 45667 3782 36485
4733 45673 3661 35292
4734 45677 3541 34109
4735 45691 3423 32933
4736 45697 3306 31782
4737 45707 3191 30642
4738 45737 3078 29519
4739 45751 2967 28449
4740 45757 2857 27404
4741 45763 2749 26369
4742 45767 2642 25345
4743 45779 2536 24328
4744 45817 2432 23332
4745 45821 2332 22403
4746 45823 2234 21481
4747 45827 2137 20562
4748 45833 2042 19650
4749 45841 1948 18749
4750 45853 1856 17862
4751 45863 1765 16996
4752 45869 1677 16148
4753 45887 1591 15310
4754 45893 1509 14504
4755 45943 1428 13709
4756 45949 1353 13002
4757 45953 1279 12306
4758 45959 1206 11617
4759 45971 1135 10938
4760 45979 1066 10281
4761 45989 998 9638
4762 46021 932 9012
4763 46027 871 8443
4764 46049 812 7885
4765 46051 757 7366
4766 46061 704 6850
4767 46073 652 6352
4768 46091 602 5875
4769 46093 554 5430
4770 46099 508 4989
4771 46103 464 4558
4772 46133 421 4134
4773 46141 382 3764
4774 46147 345 3408
4775 46153 309 3062
4776 46171 274 2727
4777 46181 241 2424
4778 46183 211 2139
4779 46187 182 1857
4780 46199 155 1582
4781 46219 130 1329
4782 46229 108 1111
4783 46237 88 911
4784 46261 71 725
4785 46271 57 582
4786 46273 44 457
4787 46279 33 335
4788 46301 23 224
4789 46307 16 152
4790 46309 10 91
4791 46327 5 33
4792 46337 1 8
В первом столбце находится номер простого числа, с которого начинается подсчёт, во втором — само простое число, в третьем — полное количество вычёркиваемых составных чисел и в четвёртом — количество обращений к простому числу, которое происходит в цикле программы. Если найти отношение данных в 4-ом столбце к данным в 3-ем, то узнаем среднее число обращений к простому делителю на одно вычёркивание составного числа. Получается такой интересный график:
Как видно, пока не так уж всё и плохо. Не больше десятка обращений (надо учитывать, что это интегральная картинка, фактически надо смотреть на самую первую точку). Каждое обращение к простому числу состоит из чтения из массива, сравнение с переменной, вычитания и записи в массив, если не было вычёркивания. Если вычёркивание было, то добавляются ещё одно сравнение, сложение и запись в массив решета. Я не знаю, как точно считать сложность этих действий, но получается 4-7 операций на обращение.
Всё это я вычислял применительно к идее реализации вычёркивания через очередь с приоритетом. Все простые делители, начиная с некоторого
, достаточно редко участвуют в вычёркивании. Поскольку вычёркиваемые составные числа являются произведением простого делителя
на другой делитель
, то каждое такие составное число, соответствующее делителю
для
начиная с
можно добавить в очередь с приоритетом и извлекать по одному при необходимости. Извлечённое составное число
, соответствующее делителю
, вычёркивается из решета, а вместо него в очередь добавляется число
и работа продолжается. При этом
, поскольку для меньших простых делителей второй множитель вычёркиваемого числа уже может быть составным.
Весь вопрос в том, можно ли достаточно эффективно организовать очередь на тысячу-другую элементов, чтобы добиться ускорения. Судя по графику выше, для текущего диапазона простых чисел, с которыми работает моя программа, этого сделать не получится. Возможно, для большего диапазона поиска в этом будет смысл.