mathe 发表于 2010-1-14 12:40:58

看看稍微修改以后就可以求出s(7)
// shc.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <math.h>
#define L 40
#define N 7
#define K 5
unsigned n;
unsigned long long M;
unsigned long long R;
unsigned long long maxM;
int A;
long long count;
long long gc;

void solve()
{
    unsigned long long V=M*M+R;
    unsigned long long r=M%R;
    r=R-r;
    unsigned long long u=r;
    for(;u<=M;u+=R){
      if(V%u==0&&(u+M>=R*n)){
            int i;
            for(i=0;i<K;i++){
                printf("%d ",n);
            }
            printf("%lld %lld\n",(u+M)/R,(V/u+M)/R);
      }
    }
}

void output(int level, int overflow)
{
    if(level==K){
      int a3=A%4;
      int a1=A%4;
/*      if(A==1&&a1==1)
            return;
      if(A==1&&a3==0)
            return;
      if(A==0&&A==0){
            if((a1==1||a1==2)&&a3<2)
                return;
      }
*/      int c=(int)ceil(log10((double)(M)));
      if(c>=L)c=L-1;
      if(c<0)c=0;
      gc++;
      solve();
    }
    if(M>maxM)maxM=M;
    count++;
}

unsigned long long gcd(unsigned long long x,unsigned long long y)
{
    while(y!=0){
      unsigned long long r=x%y;
      x=y;
      y=r;
    }
    return x;
}

void search(int level)
{
    if(level>=K){
      output(level,0);
      return;
    }
    double ll=(double)M/R;
    double uu=ll*(N-level);
    if(uu>=4294967295.5||uu>=18446744073709551615.0/M){///overflow
      output(level,1);
      return;
    }
    unsigned li=(unsigned)ceil(ll);
    unsigned ui=(unsigned)uu;
    if(li<=n)li=n+1;
    unsigned i;
    for(i=li;i<=ui;i++){
      if(gcd(M,i)!=1)
            continue;
      n=i;
      M=M*i;
      R=R*i-M;
      A++;
      search(level+1);
      A--;
    }
}

void search0()
{
    int i;
    for(i=0;i<4;i++)A=0;
    for(i=2;i<=7;i++){
      n=i;
      R=i-1;
      M=i;
      A++;
      search(1);
      A--;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    search0();
    int i;
        return 0;
}

mathe 发表于 2010-1-14 13:46:24

根据45#,我们有340万个平均22位最多28位的整数需要分解因子.
我不知道分解这么大的整数平均需要多长时间.假设分解每一个数需要1秒钟,那么也只需要一个CPU大概1000小时,从计算量上看,是完全可行的.
而如果直接采用试除法,由于已经知道因子的特殊形式,平均每个大概需要试除数百万次,也就是大概需要$10^14$次128比特整数的除法运算,从计算量上看,可能比因子分解算法慢数倍,但是从计算量上也是可行的.而且对于这个方法,我们只要提供一个128比特整数比较有效的加减乘除代码就可以了.
谁先提供一个效率比较高的128比特整数的加减乘除运算代码看看,我们只需要修改52#中的solve程序采用128比特计算,然后修改N为8,K为6就可以了.可以先部分运行一下代码测试一下大概的速度

mathe 发表于 2010-1-14 14:23:50

快速乘法有了:
x86上128位二进制乘法最快速算法征解
除法有没有好的?

mathe 发表于 2010-1-14 14:25:46

看了一下solve的代码,只需要128位除64位的除法运算,那么应该直接用汇编指令就可以了.
谁将上面的solve函数改写一下?汇编我长时间不用,已经非常不熟练了

gxqcn 发表于 2010-1-14 14:46:17

除法要快速,一般是针对除数是固定值时,预先算好一些算法值以加速运算。
对于128位除64位的除法,用一般的试商法即可;
如果在64位系统下,只要将高地位分别移进 RDX:RAX,而后 DIV 除数 即可。

mathe 发表于 2010-1-14 19:41:36

存在一些很大的M/R,所以还是要用对V因子分解的方法
然后对V每个小于sqrt(V)的因子d,如果(d+M)是R倍数,就可以构着一个解.
这个还是谁用Mathematica来做比较好.如果能够运行两个月左右估计就能解决这个问题了

数学星空 发表于 2010-1-14 19:45:40

呵,这个还是谁用Mathematica来做比较好.如果能够运行两个月左右估计就能解决这个问题了
这个难题可能对wayne来说不是问题,可惜我的mathematica编程不行.....

数学星空 发表于 2010-1-14 20:34:40

请教mathe:
51#楼的程序文件格式为.cpp吧?
在visualstudio 2008中运行怎么不成功呢?
见下图:

gxqcn 发表于 2010-1-14 20:52:55

看图示似乎是编译未通过,尚未生成 exe 文件。

你可以用向导产生一个工程(目的:生成stdafx.h及staafx.cpp),
然后再将 mathe 的代码粘贴进来进行编译。

mathe 发表于 2010-1-15 09:59:35

试着用LiLDA求解,发现代码有bug,做因子分解时经常崩溃掉,而且稍微添加一点代码,崩溃的地方都不同,不知道什么原因
#include <time.h>
#include <LiDIA/rational_factorization.h>
#include <iostream.h>
using namespace LiDIA;
using namespace std;
#include <math.h>
#define L 40
#define N 8
#define K 6
unsigned long n;
bigint M;
bigint R;
bigint maxM;
int A;
long long c;
long long gc;
int start_time;

#define MAX_INDEX 20
int iindex;
void solve()
{
        bigint V,MM,RR,uu;
        MM=M;
        RR=R;
        V=MM*MM+RR;
        rational_factorization f;
        f.assign(V);
        f.factor();
        if(!f.is_prime_factorization()){
                printf("cannot factor %lld solution\n",c);
        }else{
                if(f.no_of_comp()>=MAX_INDEX){
                        printf("too much compondents for %lld solution\n",c);
                }else{
                        int i;
                        for(i=0;i<f.no_of_comp();i++){
                                iindex=0;
                        }
                        do{
                                bigint v=1;
                                for(i=0;i<f.no_of_comp();i++){
                                        int j;
                                        for(j=0;j<iindex;j++){
                                                v*=f.base(i);
                                        }
                                }
                                if((v+MM)%RR==0){///solution found
                                        for(i=0;i<K;i++){
                                                cout<<"n"<<i+1<<"="<<n<<";";
                                        }
                                        cout<<"n"<<K+1<<'='<<(v+MM)/RR<<";n"<<K+2<<"="<<(V/v+MM)/RR<<";\n";
                                }
                                for(i=f.no_of_comp()-1;i>=0;i--){
                                        if(iindex==f.exponent(i)){
                                                iindex=0;
                                                continue;
                                        }else{
                                                iindex++;
                                                break;
                                        }
                                }
                                if(i<0)break;
                        }while(1);
                }
        }
        fflush(stdout);
}

void output(int level, int overflow)
{
    if(level==K){
      solve();
    }
    if(M>maxM)maxM=M;
    c++;
    fprintf(stderr,"processed %lld by %ds\n",c,time(NULL)-start_time);
}

void search(int level)
{
    if(level>=K){
      output(level,0);
      return;
    }
    double ll=(double)dbl(M)/dbl(R);
    double uu=ll*(N-level);
    if(uu>=4294967295.5){///overflow
      output(level,1);
      return;
    }
    unsigned long li=(unsigned long)ceil(ll);
    unsigned long ui=(unsigned long)uu;
    if(li<=n)li=n+1;
    unsigned long i;
    for(i=li;i<=ui;i++){
      if(gcd(M,i)!=1)
            continue;
      n=i;
      M=M*i;
      R=R*i-M;
      A++;
      search(level+1);
      A--;
    }
}

void search0()
{
    int i;
    for(i=0;i<4;i++)A=0;
    for(i=2;i<=7;i++){
      n=i;
      R=i-1;
      M=i;
      A++;
      search(1);
      A--;
    }
}

int main()
{
        start_time=time(NULL);
    search0();
    int i;
        return 0;
}

页: 1 2 3 4 5 [6] 7 8 9 10 11
查看完整版本: 关于单位分数的一些难题