|
Вы последовательность множеств остатков, как я понял, по некоторым паттернам (правилам перехода к новым комбинациям) строите. Думаю, что угадать паттерн легче, чем угадывание больших степеней в представлении (это то, что использовал я). Вам стоит попробовать жадный алгоритм рандома, если какой-то паттерн за некоторое не очень большое время не даёт результат, сбрасывать его и запускать с новым. Хотя, я не очень вникал, возможно, что правила перехода Вы руками задаёте, а рандом по начальным данным. Да-да, в эту сторону я ходил: с некоторой долей случайности выбираются паттерны при каждом переходе, и сброс, если поиск слишком затянулся. Подробнее: 0. Делаем сколько-то независимых попыток, пока не надоест; я обычно двухсот не дожидался. В каждой попытке: 1. Начинаем с упорядоченной по возрастанию последовательности остатков  , добавляем к ней еще два числа  , где  2. При каждом переходе для каждого  вычисляем четыре (или меньше) разности  и вставляем их обратно в упорядоченную последовательность; проверяя отсутствие полных дубликатов и "запрещенных" комбинаций с коэффициентом по модулю большим единицы при какой-нибудь степени пятерки; при этом, для каждого перехода в рамках попытки, четыре числа  выбираются псевдослучайно из диапазонов  3. Повторяем предыдущий шаг в цикле  раз; если решение еще не найдено, а размер последовательности не увеличился или превысил  членов - сброс попытки. Если найдено - успех, стоп. Константы подобраны эмпирически, исходя из физиологии моего нотика и ряда шаманских предположений о пространстве решений задачи. Код (все константы забиты в строках 42, 47, 57, 81):
- f52isnice(a,b)={return(bitand(real(a),imag(b))==0 && bitand(real(b),imag(a))==0)};
-
- f52diff(a,b)={my([L1,R1]=[real(a),imag(a)],[L2,R2]=[real(b),imag(b)],G);
- G=bitxor(bitand(L1,L2),bitand(R1,R2));
- return(bitxor(G,bitor(L1,R2))+I*bitxor(G,bitor(L2,R1)))
- };
-
- f52dec(s,n)={my(
- L=binary(real(s)),
- R=binary(imag(s)),
- L1=select(x->x,L,1),
- R1=select(x->x,R,1),
- L2=vector(#L1,i,#L-L1[i]),
- R2=vector(#R1,i,#R-R1[i]),
- r=(sum(i=1,#L2,5^L2[i])-sum(i=1,#R2,5^R2[i]))/(2^n-1);
- );
- return([L2;R2;r]);
- };
-
- f52nb(n)={
- \\try to find a multiple of N=2^n-1 as a sum of b[i]*5^i, i=0,1,...,n-1, b[i]=-1,0,1
- t0=getabstime();
- N=2^n-1;
- a=vector(n,i,lift(Mod(5^(i-1),N)));
- k=floor(vecsum(a)/N); print(k); if(k<2,k=2);
- a=vector(n+1,i,if(i<n+1,a[i],N)); \\dunno a nice way for concating two vectors
- a=vector(n+2,i,if(i<n+2,a[i],k*N));
-
- s=vector(n,i,2^(i-1));
- s=vector(n+2,i,if(i<n+1,s[i],0));
-
- \\pack b[i] into bits of a complex number: 5+2i => [101, 10] => 5^2+5^0-5^1
- aind=vecsort(a,,1);
- a0=vecextract(a,aind);
- s0=vecextract(s,aind);
- \\print(a);
- \\print(s);
-
- \\DD=7; \\max search depth
- \\DD=#combo;
-
- for(gcnt=1,10000,
- print([gcnt,getabstime()-t0,#a]);
- a=a0;
- s=s0;
-
- for(ecnt=1,max(30,k+45),\\basically while(1)
- wa=#a;
- anew=a;
- snew=s;
- wanew=wa;
- waold=wa;
-
- \\DDgen=random([1,127]);
- \\DDgen=binary(DDgen);
- \\combo=select(x->x,DDgen,1);
- combo=vecsort([random([1,3]),random([1,6]),random([1,9]),random([1,12])],,8);
- DD=#combo;
-
- \\main job
- for(dcnt=1,DD,
- dep=combo[dcnt];
- da=vector(wa-dep,i,if(f52isnice(s[i+dep],s[i]),a[i+dep]-a[i],-1));
- ds=vector(wa-dep,i,if(f52isnice(s[i+dep],s[i]),f52diff(s[i+dep],s[i]),-1));
- wda=#da;
-
- anew=vector(wanew+wda,i,if(i<=wanew,anew[i],da[i-wanew]));
- snew=vector(wanew+wda,i,if(i<=wanew,snew[i],ds[i-wanew]));
- wanew=#anew;
- ); \\end for dep
-
- g=matconcat([anew,snew]~);
- aind=vecsort(g,,9); \\remove full duplicates
- a=vecextract(anew,aind);
- s=vecextract(snew,aind);
- if(a[1]==-1,wa=#a;a=a[2..wa];s=s[2..wa]); \\remove one last bad combo s
- \\print(["===>",ecnt,#a,combo]);
-
- if(a[1]==0,print(getabstime()-t0," ms");return(f52dec(s[1],n))); \\success
-
- if(#a>1900000 || #a==waold, break());
-
- ); \\end for ecnt
- ); \\end for gcnt
- print(getabstime()-t0," ms");
- return([]); \\failure
- };
Код по-прежнему не экономен к памяти (для размера последовательности  при переходе я пложу несколько объектов размера  , чтобы иметь возможность пользоваться быстрыми операциями с векторами).
|
|