博文
Miller-Rabin算法(转)(2007-3-22 23:42:00)
一.费马小定里
if n is prime and (a,n) equals one ,then a^(n-1) = 1 (mod n)
费马小定理只是个必要条件,符合费马小定理而非素数的数叫做Carmichael.
前3个Carmichael数是561,1105,1729。
Carmichael数是非常少的。
在1~100000000范围内的整数中,只有255个Carmichael数。
为此又有二次探测定理,以确保该数为素数:
二.二次探测定理
二次探测定理 如果p是一个素数,0<x<p,则方程x^2≡1(mod p)的解为x=1,p-1
根据以上两个定理,如到Miller-Rabin算法的一般步骤:
0、先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数
1、随机取一个b,2<=b
2、计算v=b^m mod n
3、如果v==1,通过测试,返回
4、令i=1
5、如果v=n-1,通过测试,返回
6、如果i==j,非素数,结束
7、v=v^2 mod n,i=i+1
8、循环到5
说明:
Miller-Rabin是随机算法
得到的结果的正确率为 75%,所以应该多次调用该函数,使正确概率提高为
1-(1/4)^p
//功能实现
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <functional>
typedef __int64 lltype;
const int MAX_COUNT = 6;//测试次数
lltype allFactor[65], nFactor;//质因分解结果(刚返回的时候是无序的)
void fFindFactor(const lltype &num);//主函数(num > 1)
lltype pollard_rho(const lltype &c, const lltype &num);
bool miller_rabin(const lltype &n, int count);//miller-rabin
bool fWitNess(const lltype &a, const lltype &n, char t, const lltype &u);
lltype modular_exp(const lltype &a, lltype b, const lltype &n);//d = a^b(mod n)
lltype fMultiModular(const lltype &a, lltype b, const lltype &n);//(a*b)%num
lltype fGCD(lltype a, lltype b);
void fFindFactor(const lltype &num)
{
if ( miller_rabin(num, MAX_COUNT) == true )
{
allFactor[++nFactor] = num;
return;
}
lltype factor;
do
{
factor = pollard_rho(rand()%(num-1) + 1, num);
}while ( factor >= num );
//printf("%I64d ",factor);
fFindFactor(factor);
fFindFactor(num/factor);
}
lltype pollard_rho(const lltype &c, const lltype &num)
{
int i(1), k(2);
lltype x = rand() % num;
lltype y = x, comDiv;
do
{
++i;
if ( (x = fMultiModular(x, x, num) - c) < 0 )
x += num;
if ( x == y )
break;
comDiv = fGCD((y-x+num)%num, num);
if ( comDiv > 1 && comDiv < num )
return comDiv;
if ( i == k )
{
y = x;
k <<= 1;
}
}while ( true );
return num;
}
//miller-rabin法测试素数, count 测试次数
bool miller_rabin(const lltype &n, int count)
{
if ( n == 1 )
return false;
if ( n == 2 )
return true;
lltype a, u; //为了谨慎起见用了 lltype, 而没有用 int
char t(0); //n-1 == (2^t)*u
for (u = n-1; !(u & 0x1); u>>=1)
++t;
for (int i = 1; i <= count; ++i)
{
a = rand() % (n-1) + 1;
if ( fWitNess(a, n, t, u) )
return false;
}
return true;
}
bool fWitNess(const lltype &a, const lltype &n, char t, const lltype &u)
{//if n must not be prime return true, else return false
lltype x, y;
x = modular_exp(a, u, n);
while ( t-- )
{
y = fMultiModular(x, x, n);
if ( y == 1 && x != 1 && x != n-1 )
return true; //must not
x = y;
}
return y != 1;
}
// d == a^b(mod n)
lltype modular_exp(const lltype &a, lltype b, const lltype &n)
{
lltype d(1), dTemp(a % n);//当前二进制位表示的是进制数值
while ( b > 0 )
{
if ( b & 0x1 )
d = fMultiModular(d, dTemp, n);//不直接 d*dTemp 是怕溢出
dTemp = fMultiModular(dTemp, dTemp, n);
b >>= 1;
}
return d;
}
//back = (a*b)%num ( n <= 2^62)
lltype fMultiModular(const lltype &a, lltype b, const lltype &n)
{
lltype back(0), temp(a % n);
//b %= n;
while ( b > 0 )
{
if ( b & 0x1 )
{
if ( (back = back + temp) > n )
back -= n;
}
if ( (temp <<= 1) > n )
temp -= n;
b >>= 1;
}
return back;
}
lltype fGCD(lltype a, lltype b)
{
lltype c;
while ( b )
{
c = b;
b = a%b;
a = c;
}
return a;
}
阅读全文(6395) | 评论:0 | 复制链接
(转)Prime Numbers, Factorization and Eule(2007-3-11 23:51:00)
Prime numbers and their properties were extensively studied by the ancient Greek mathematicians. Thousands of years later, we commonly use the different properties of integers that they discovered to solve problems. In this article we’ll review some definitions, well-known theorems, and number properties, and look at some problems associated with them.
A prime number is a positive integer, which is divisible on 1 and itself. The other integers, greater than 1, are composite. Coprime integers are a set of integers that have no common divisor other than 1 or -1.
The fundamental theorem of arithmetic:
Any positive integer can be divided in primes in essentially only one way. The phrase 'essentially one way' means that we do not consider the order of the factors important.
One is neither a prime nor composite number. One is not composite because it doesn’t have two distinct divisors. If one is prime, then number 6, for example, has two different representations as a product of prime numbers: 6 = 2 * 3 and 6 = 1 * 2 * 3. This would contradict the fundamental theorem of arithmetic.
Euclid’s theorem:
There is no largest prime number.
To prove this, let's consider only n prime numbers: p1, p2, …, pn. But no prime pi divides the number
N = p1 * p2 * … * pn + 1,
so N cannot be composite. This contradicts the fact that the set of primes is finite.
Exercise 1. Sequence an is defined recursively:

Prove that ai and aj, i ¹ j are relatively prime.
Hint: Prove that an+1 = a1a2…an + 1 and use Euclid’s theorem.
Exercise 2. Ferma numbers Fn (n ≥ 0) are positive integers of the form

Prove that Fi and Fj, i ≠ j are relatively prime.
Hint: Prove that Fn +1 = F0F1F2…Fn + 2 and use Euclid’s theorem.
Dirichlet’s theorem about arithmetic progressions:
For any two positive coprime integers a and b there are infinitely many primes of the form a + n*b, where n > 0.
Trial division:
Trial division is the simplest of all factorization techniques. It represents a brute-force method, in which we are trying to divide n by every number i not greater than the square root of n. (Why don't we need to test values larger than the square root of n?) The procedure factor prints the factorization of number n. The factors will be printed in a line, separated with one space. The number n can contain no more than one factor, greater than n.
void factor(int n)
{
int i;
for(i=2;i<=(int)sqrt(n);i++)
{
while(n % i == 0)
{
printf("%d ",i);
n /= i;
}
}
if (n > 1) printf("%d",n);
printf("\n");
}
Consider a problem that asks you to find the factorization of integer g(-231 < g <231) in the form
g = f1 x f2 x … x fn or g = -1 x f1 x f2 x … x fn
where fi is a prime greater than 1 and fi ≤ fj for i < j.
For example, for g = -192 the answer is -192 = -1 x 2 x 2 x 2 x 2 x 2 x 2 x 3.
To solve the problem, it is enough to use trial division as shown in function factor.
Sieve of Eratosthenes:
The most efficient way to find all small primes was proposed by the Greek mathematician Eratosthenes. His idea was to make a list of positive integers not greater than n and sequentially strike out the multiples of primes less than or equal to the square root of n. After this procedure only primes are left in the list.
The procedure of finding prime numbers gen_primes will use an array primes[MAX] as a list of integers. The elements of this array will be filled so that

At the beginning we mark all numbers as prime. Then for each prime number i (i ≥ 2), not greater than √MAX, we mark all numbers i*i, i*(i + 1), … as composite.
void gen_primes()
{
int i,j;
for(i=0;i<MAX;i++) primes[i] = 1;
for(i=2;i<=(int)sqrt(MAX);i++)
if (primes[i])
for(j=i;j*i<MAX;j++) primes[i*j] = 0;
}
For example, if MAX = 16, then after calling gen_primes, the array ‘primes’ will contain next values:
| i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| primes[i] | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
Goldbach's Conjecture:
For any integer n (n ≥ 4) there exist two prime numbers p1 and p2 such that p1 + p2 = n. In a problem we might need to find the number of essentially different pairs (p1, p2), satisfying the condition in the conjecture for a given even number n (4 ≤ n ≤ 2 15). (The word ‘essentially’ means that for each pair (p1, p2) we have p1 ≤ p2.)
For example, for n = 10 we have two such pairs: 10 = 5 + 5 and 10 = 3 + 7.
To solve this,as n ≤ 215 = 32768, we’ll fill an array primes[32768] using function gen_primes. We are interested in primes, not greater than 32768.
The function FindSol(n) finds the number of different pairs (p1, p2), for which n = p1 + p2. As p1 ≤ p2, we have p1 ≤ n/2. So to solve the problem we need to find the number of pairs (i, n – i), such that i and n – i are prime numbers and 2 ≤ i ≤ n/2.
int FindSol(int n)
{
int i,res=0;
for(i=2;i<=n/2;i++)
if (primes[i] && primes[n-i]) res++;
return res;
}
Euler’s totient function
The number of positive integers, not greater than n, and relatively prime with n, equals to Euler’s totient function φ (n). In symbols we can state that
φ (n) ={a Î N: 1 ≤ a ≤ n, gcd(a, n) = 1}
This function has the following properties:
- If p is prime, then φ (p) = p – 1 and φ (pa) = p a * (1 – 1/p) for any a.
- If m and n are coprime, then φ (m * n) = φ (m) * φ (n).
- If n =
, then Euler function can be found using formula:
φ (n) = n * (1 – 1/p 1) * (1 – 1/p 2) * ... * (1 – 1/p k)
The function fi(n) finds the value of φ(n):
int fi(int n)
{
int result = n;
for(int i=2;i*i <= n;i++)
{
if (n % i == 0) result -= result / i;
while (n % i == 0) n /= i;
}
if (n > 1) result -= result / n;
return result;
}
For example, to find φ(616) we need to factorize the argument: 616 = 23 * 7 * 11. Then, using the formula, we’ll get:
φ(616) = 616 * (1 – 1/2) * (1 – 1/7) * (1 – 1/11) = 616 * 1/2 * 6/7 * 10/11 = 240.
Say you've got a problem that, for a given integer n (0 < n ≤ 109), asks you to find the number of positive integers less than n and relatively prime to n. For example, for n = 12 we have 4 such numbers: 1, 5, 7 and 11.
The solution: The number of positive integers less than n and relatively prime to n equals to φ(n). In this problem, then, we need do nothing more than to evaluate Euler’s totient function.
Or consider a scenario where you are asked to calculate a function Answer(x, y), with x and y both integers in the range [1, n], 1 ≤ n ≤ 50000. If you know Answer(x, y), then you can easily derive Answer(k*x, k*y) for any integer k. In this situation you want to know how many values of Answer(x, y) you need to precalculate. The function Answer is not symmetric.
For example, if n = 4, you need to precalculate 11 values: Answer(1, 1), Answer(1, 2), Answer(2, 1), Answer(1, 3), Answer(2, 3), Answer(3, 2), Answer(3, 1), Answer(1, 4), Answer(3, 4), Answer(4, 3) and Answer(4, 1).
The solution here is to let res(i) be the minimum number of Answer(x, y) to precalculate, where x, y Î{1, …, i}. It is obvious that res(1) = 1, because if n = 1, it is enough to know Answer(1, 1). Let we know res(i). So for n = i + 1 we need to find Answer(1, i + 1), Answer(2, i + 1), … , Answer(i + 1, i + 1), Answer(i + 1, 1), Answer(i + 1, 2), … , Answer(i + 1, i).
The values Answer(j, i + 1) and Answer(i + 1, j), j Î{1, …, i + 1}, can be found from known values if GCD(j, i + 1) > 1, i.e. if the numbers j and i + 1 are not common primes. So we must know all the values Answer(j, i + 1) and Answer(i + 1, j) for which j and i + 1 are coprime. The number of such values equals to 2 * φ (i + 1), where φ is an Euler’s totient function. So we have a recursion to solve a problem:
res(1) = 1,
res(i + 1) = res(i) + 2 * j (i + 1), i > 1
Euler’s totient theorem:
If n is a positive integer and a is coprime to n, then a φ (n) º 1 (mod n).
Fermat’s little theorem:
If p is a prime number, then for any integer a that is coprime to n, we have
a p ≡ a (mod p)
This theorem can also be stated as: If p is a prime number and a is coprime to p, then
a p -1 ≡ 1 (mod p)
Fermat’s little theorem is a special case of Euler’s totient theorem when n is prime.
The number of divisors:
If n =
, then the number of its positive divisors equals to
(a1 + 1) * (a2 + 1) * … * (ak + 1)
For a proof, let A i be the set of divisors
. Any divisor of number n can be represented as a product x1 * x2 * … * x k , where xi Î Ai. As |Ai| = ai + 1, we have
(a1 + 1) * (a2 + 1) * … * (ak + 1)
possibilities to get different products x1 * x2 * … * xk.
For example, to find the number of divisors for 36, we need to factorize it first: 36 = 2² * 3². Using the formula above, we’ll get the divisors amount for 36. It equals to (2 + 1) * (2 + 1) = 3 * 3 = 9. There are 9 divisors for 36: 1, 2, 3, 4, 6, 9, 12, 18 and 36.
Here's another problem to think about: For a given positive integer n (0 < n < 231) we need to find the number of such m that 1 ≤ m ≤ n, GCD(m, n) ≠ 1 and GCD(m, n) ≠ m. For example, for n = 6 we have only one such number m = 4.
The solution is to subtract from n the amount of numbers, coprime with it (its amount equals to φ(n)) and the amount of its divisors. But the number 1 simultaneously is coprime with n and is a divisor of n. So to obtain the difference we must add 1. If n =
is a factorization of n, the number n has (a1 + 1) * (a2 + 1) * … * (ak + 1) divisors. So the answer to the problem for a given n equals to
n – φ(n) – (a1 + 1) * (a2 + 1) * … * (ak + 1) + 1
转自:http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=primeNumbers
阅读全文(1997) | 评论:0 | 复制链接
类设计者的核查表(2007-3-9 0:10:00)
摘自<<c++沉思录>>
1.你的类需要一个构造函数吗?
2.你的数据成员是私有的吗?
3.你的类需要一个无参的构造函数吗?
4.是不是每个构造函数初始化所有的数据成员?
5.类需要析构函数吗?
6.类需要一个虚析构函数吗?
7.你的类需要复制构造函数吗?
8.你的类需要一个赋值操作符吗?
9.你的赋值操作符能正确地将对象赋给对象本身吗?
10.你的类需要定义关系操作符吗?
11.删除数组时你记住了用delete[]吗?
12.记得在复制构造函数和赋值操作符的参数类型中加上const
了吗?
13.如果函数有引用参数,它们应该是const引用吗?
14.记得适当地声明成员函数为const的了吗?
阅读全文(1895) | 评论:0 | 复制链接
杂类集(2007-2-3 21:17:00)
Great Common Divisor
最大公约数
给定两个任意正整数n和任一质数p,求将n!表示成算术基本定理的形式的时候,p的指数.
count=0;
while(n)
{
count+=n/p;
n/=p;
}
cout<<count<<endl; 阅读全文(2232) | 评论:0 | 复制链接
hash function(2006-9-29 22:02:00)
经典字符串中出现的hash函数
(转载自http://www.ccw.com.cn/htm/app/aprog/01_8_22_3.asp)
1. PHP中出现的字符串Hash函数
static unsigned long str_hash_function (char *arKey , unsigned int nKeyLength) {
int h=0;
int g;
char *arEnd=arKey+nKeyLength;
while (arKey<arEnd) {
h=(h<<4)+*arKey++;
if ((g=(h&0xF0000000))) {
h=h^(g>>24);
h=h^g;
}
}
return h;
}
2. OpenSSL中出现的字符串Hash函数
unsigned long str_hash_function (char *str) {
int i , l;
unsigned long ret=0;
unsigned short *s;
if (str==NULL) return (0);
l=(strlen(str)+1)/2;
s=(unsigned short *) str;
for (i=0;i<l;i++) {
ret^=(s[i]<<(i&oxof));
return ret;
}
unsinged long str_hash_function2 (const char *str) {
unsigned long ret=0;
long n;
unsigned long v;
int r;
if ((c==NULL)||(*c==’\
n=0x100;
while (*c) {
v=n| (*c);
n+=0x100;
r=(int )((v>>2)^v)&0x
ret=(ret<>(32-r));
ret&=0xFFFFFFFFL;
retu^=v*v;
c++;
}
return ((ret>>16)^ret);
}
3. MySql中出现的字符串Hash函数(完全看不懂就不写了)
4. 很简单又好用的一个字符串的Hash函数
int hash_function () {
int h=0;
int i;
for (i=0;b[i];i++) h=5*h+b[i];
return h;
}
阅读全文(3224) | 评论:0 | 复制链接
计算几何算法概览(转)(2006-9-6 21:28:00)
| ||||||
| ||||||
| ||||||
阅读全文(3044) | 评论:0 | 复制链接
Bellman-Ford算法(2006-9-5 22:16:00)
该算法用来求边上权值为任意值的单源最短路径问题
伪代码如下:
void bellman_ford(int v)
{
for 1 to n
initialize dist[i][v]; //此时只经过一条边
for 2 to n-1 (i) //经过的边数不大于i条时
for 1 to n (j) //对于每一个目标顶点
for 1 to n (k) //经过该顶点时,与当前最小值比较,并更新当前值
if edge[k][j] > 0 && dist[k] > edge[k][j]+dist[j]
更新当前值
}//
阅读全文(7439) | 评论:3 | 复制链接
LIS(2006-8-20 21:04:00)
#include <iostream>
using namespace std;
#define MAXNUM 1000
char c[MAXNUM];
char b[MAXNUM+1];
void solve()
{
int i,first,last,mid,len;
len = 1;
i = 1;
b[1] = c[0];
while (c[i])
{
first = 1;
last = len+1;
while (first < last)
{
mid = (first+last)>>1;
if (b[mid] < c[i])first = mid+1;
else last = mid;
}
b[first] = c[i++];
if (len < first)len = first;
}
cout << len << endl;
}
int main()
{
cin >> c;
solve();
system("pause");
return 0;
}
ps:这是在看了别人的博客后自己试着去写的一个关于求最长递增子序列的程序。时间复杂度为O(nlogn).
阅读全文(2685) | 评论:0 | 复制链接
Josephus问题的数学方法(转)(2006-8-20 11:02:00)
无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大(例如上百万,上千万)的时候,几乎是没有办法在短时间内出结果的。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效率,就要打破常规,实施一点数学策略。
为了讨论方便,先把问题稍微改变一下,并不影响原意:
问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。
我们知道第一个人(编号一定是m%n-1) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):
k k+1 k+2 ... n-2, n-1, 0, 1, 2, ... k-2
并且从k开始报0。
现在我们把他们的编号做一下转换:
k --> 0
k+1 --> 1
k+2 --> 2
...
...
k-2 --> n-2
k-1 --> n-1
变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x'=(x+k)%n
如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:
令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]
递推公式
f[1]=0;
f[i]=(f[i-1]+m)%i; (i>1)
有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1
由于是逐级递推,不需要保存每个f[i],程序也是异常简单:
#i nclude <stdio.h>
main()
{
int n, m, i, s=0;
printf ("N M = "); scanf("%d%d", &n, &m);
for (i=2; i<=n; i++) s=(s+m)%i;
printf ("The winner is %d\n", s+1);
}
这个算法的时间复杂度为O(n),相对于模拟算法已经有了很大的提高。算n,m等于一百万,一千万的情况不是问题了。可见,适当地运用数学策略,不仅可以让编程变得简单,而且往往会成倍地提高算法执行效率。
阅读全文(3359) | 评论:2 | 复制链接
费马最後定理(转)(2006-8-19 20:13:00)
被公认执世界报纸牛耳地位地位的纽约时报於1993年6月24日在其一版头题刊登了一则有关数学难题得以解决的消息,那则消息的标题是「在陈年数学困局中,终於有人呼叫『我找到了』」。时报一版的开始文章中还附了一张留着长发、穿着中古世纪欧洲学袍的男人照片。这个古意盎然的男人,就是法国的数学家费马(Pierre de Fermat)(费马小传请参考附录)。费马是十七世纪最卓越的数学家之一,他在数学许多领域中都有极大的贡献,因为他的本行是专业的律师,为了表彰他的数学造诣,世人冠以「业余王子」之美称,在三百六十多年前的某一天,费马正在阅读一本古希腊数学家戴奥芬多斯的数学书时,突然心血来潮在书页的空白处,写下一个看起来很简单的定理这个定理的内容是有关一个方程式 x2 + y2 =z2的正整数解的问题,当n=2时就是我们所熟知的毕氏定理(中国古代又称勾股弦定理):x2 + y2 =z2,此处z表一直角形之斜边而x、y为其之两股,也就是一个直角三角形之斜边的平方等於它的两股的平方和,这个方程式当然有整数解(其实有很多),例如:x=3、y=4、z=5;x=6、y=8、z=10;x=5、y=12、z=13…等等。
费马声称当n>2时,就找不到满足xn +yn = zn的整数解,例如:方程式x3 +y3=z3就无法找到整数解。
当时费马并没有说明原因,他只是留下这个叙述并且也说他已经发现这个定理的证明妙法,只是书页的空白处不够无法写下。始作俑者的费马也因此留下了千古的难题,三百多年来无数的数学家尝试要去解决这个难题却都徒劳无功。这个号称世纪难题的费马最後定理也就成了数学界的心头大患,极欲解之而後快。
十九世纪时法国的法兰西斯数学院曾经在一八一五年和一八六0年两度悬赏金质奖章和三百法郎给任何解决此一难题的人,可惜都没有人能够领到奖赏。德国的数学家佛尔夫斯克尔(P‧Wolfskehl)在1908年提供十万马克,给能够证明费马最後定理是正确的人,有效期间为100年。其间由於经济大萧条的原因,此笔奖额已贬值至七千五百马克,虽然如此仍然吸引不少的「数学痴」。
二十世纪电脑发展以後,许多数学家用电脑计算可以证明这个定理当n为很大时是成立的,1983年电脑专家斯洛文斯基借助电脑运行5782秒证明当n为286243-1时费马定理是正确的(注286243-1为一天文数字,大约为25960位数)。
虽然如此,数学家还没有找到一个普遍性的证明。不过这个三百多年的数学悬案终於解决了,这个数学难题是由英国的数学家威利斯(Andrew Wiles)所解决。其实威利斯是利用二十世纪过去三十年来抽象数学发展的结果加以证明。
五0年代日本数学家谷山丰首先提出一个有关椭圆曲现的猜想,後来由另一位数学家志村五郎加以发扬光大,当时没有人认为这个猜想与费马定理有任何关联。在八0年代德国数学家佛列将谷山丰的猜想与费马定理扯在一起,而威利斯所做的正是根据这个关联论证出一种形式的谷山丰猜想是正确的,进而推出费马最後定理也是正确的。这个结论由威利斯在1993年的6月21日於美国剑桥大学牛顿数学研究所的研讨会正式发表,这个报告马上震惊整个数学界,就是数学门墙外的社会大众也寄以无限的关注。不过威利斯的证明马上被检验出有少许的瑕疵,於是威利斯与他的学生又花了十四个月的时间再加以修正。1994年9月19日他们终於交出完整无瑕的解答,数学界的梦魇终於结束。1997年6月,威利斯在德国哥庭根大学领取了佛尔夫斯克尔奖。当年的十万法克约为两百万美金,不过威利斯领到时,只值五万美金左右,但威利斯已经名列青史,永垂不朽了。
证明全过程:
http://cgd.best.vwh.net/home/flt/flt08.htm
阅读全文(2272) | 评论:0 | 复制链接








最新评论