点对算法
㈠ 3、离散数学的思想和知识点对计算机算法设计、程序设计有哪些作用
离散数学课程所传授的思想和方法,广泛地体现在计算机科学技术及相关专业的诸领域,从科学计算到信息处理,从理论计算机科学到计算机应用技术,从计算机软件到计算机硬件,从人工智能到认知系统,无不与离散数学密切相关。由于数字电子计算机是一个离散结构,它只能处理离散的或离散化了的数量关系, 因此,无论计算机科学本身,还是与计算机科学及其应用密切相关的现代科学研究领域,都面临着如何对离散结构建立相应的数学模型;又如何将已用连续数量关系建立起来的数学模型离散化,从而可由计算机加以处理。
㈡ n个点距离最短算法
所需的算法就是排序取中间点.
因为,
到线段两端点的距离和最短的点必然在该线段上;将n个点按从小到大排序,则未被选中的点必须均匀分布在被选中的点的两侧,才能保证被选中的点能够在每一对点(两点分别在该点左侧和右侧)组成的线段上;
所以,
必须选择中间点,【即:当n为奇数时,选择第 (n+1)/2 个点;当n为偶数时,选择第 n/2 个点或第 (n+2)/2 个点;】,才能使该点到所有点距离和最短.
x1 x2 x3 x4 x5
2 4 5 6 100
选择中间点 x3 = 5 ,没错啊
㈢ ACM:给定点集S,求S中周长最小的三角形(点集中点数N<=20000),求一个复杂度可接受的算法(n^2以下)
关于搜寻一定范围内素数的算法及其复杂度分析
——曾晓奇
关于素数的算法是信息学竞赛和程序设计竞赛中常考的数论知识,在这里我跟大家讲一下寻找一定范围内素数的几个算法。看了以后相信
对大家一定有帮助。
正如大家都知道的那样,一个数 n 如果是合数,那么它的所有的因子不超过sqrt(n)--n的开方,那么我们可以用这个性质用最直观的方法
来求出小于等于n的所有的素数。
num = 0;
for(i=2; i<=n; i++)
{ for(j=2; j<=sqrt(i); j++)
if( j%i==0 ) break;
if( j>sqrt(i) ) prime[num++] = i; //这个prime[]是int型,跟下面讲的不同。
}
这就是最一般的求解n以内素数的算法。复杂度是o(n*sqrt(n)),如果n很小的话,这种算法(其实这是不是算法我都怀疑,没有水平。当然没
接触过程序竞赛之前我也只会这一种求n以内素数的方法。-_-~)不会耗时很多.
但是当n很大的时候,比如n=10000000时,n*sqrt(n)>30000000000,数量级相当大。在一般的机子它不是一秒钟跑不出结果,它是好几分钟都跑不
出结果,这可不是我瞎掰的,想锻炼耐心的同学不妨试一试~。。。。
在程序设计竞赛中就必须要设计出一种更好的算法要求能在几秒钟甚至一秒钟之内找出n以内的所有素数。于是就有了素数筛法。
(我表达得不清楚的话不要骂我,见到我的时候扁我一顿我不说一句话。。。)
素数筛法是这样的:
1.开一个大的bool型数组prime[],大小就是n+1就可以了.先把所有的下标为奇数的标为true,下标为偶数的标为false.
2.然后:
for( i=3; i<=sqrt(n); i+=2 )
{ if(prime[i])
for( j=i+i; j<=n; j+=i ) prime[j]=false;
}
3.最后输出bool数组中的值为true的单元的下标,就是所求的n以内的素数了。
原理很简单,就是当i是质(素)数的时候,i的所有的倍数必然是合数。如果i已经被判断不是质数了,那么再找到i后面的质数来把这个质
数的倍数筛掉。
一个简单的筛素数的过程:n=30。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
第 1 步过后2 4 ... 28 30这15个单元被标成false,其余为true。
第 2 步开始:
i=3; 由于prime[3]=true, 把prime[6], [9], [12], [15], [18], [21], [24], [27], [30]标为false.
i=4; 由于prime[4]=false,不在继续筛法步骤。
i=5; 由于prime[5]=true, 把prime[10],[15],[20],[25],[30]标为false.
i=6>sqrt(30)算法结束。
第 3 步把prime[]值为true的下标输出来:
for(i=2; i<=30; i++)
if(prime[i]) printf("%d ",i);
结果是 2 3 5 7 11 13 17 19 23 29
这就是最简单的素数筛选法,对于前面提到的10000000内的素数,用这个筛选法可以大大的降低时间复杂度。把一个只见黑屏的算法
优化到立竿见影,一下就得到结果。关于这个算法的时间复杂度,我不会描述,没看到过类似的记载。只知道算法书上如是说:前几年比
较好的算法的复杂度为o(n),空间复杂度为o(n^(1/2)/logn).另外还有时间复杂度为o(n/logn),但空间复杂度为O(n/(lognloglogn))的算法。
我水平有限啦,自己分析不来。最有说服力的就是自己上机试一试。下面给出这两个算法的程序:
//最普通的方法:
#include<stdio.h>
#include<math.h>
#define N 10000001
int prime[N];
int main()
{
int i, j, num = 0;
for(i=2; i<N; i++)
{ for(j=2; j<=sqrt(i); j++)
if( j%i==0 ) break;
if( j>sqrt(i) ) prime[num++] = i;
}
for(i=2; i<100; i++) //由于输出将占用太多io时间,所以只输出2-100内的素数。可以把100改为N
if( prime[i] )printf("%d ",i);
return 0;
}
//用了筛法的方法:
#include<stdio.h>
#include<math.h>
#define N 10000001
bool prime[N];
int main()
{
int i, j;
for(i=2; i<N; i++)
if(i%2) prime[i]=true;
else prime[i]=false;
for(i=3; i<=sqrt(N); i++)
{ if(prime[i])
for(j=i+i; j<N; j+=i) prime[i]=false;
}
for(i=2; i<100; i++)//由于输出将占用太多io时间,所以只输出2-100内的素数。可以把100改为N
if( prime[i] )printf("%d ",i);
return 0;
}
装了vc的同学上机跑一下这两个程序试一试。这个差别,绝对是天上地下。前面那个程序绝对是n分钟黑屏的说。
另外,对于这样的筛法,还可以进一步优化,就是bool型数组里面只存奇数不存偶数。如定义prime[N],则0表示
3,1表示5,2表示7,3表示9...。如果prime[0]为true,则表示3时素数。prime[3]为false意味着9是合数。
这样的优化不是简单的减少了一半的循环时间,比如按照原始的筛法,数组的下标就对应数。则在计算30以内素
数的时候3个步骤加起来走了15个单位时间。但是用这样的优化则是这样:
则由于只存3 5 7 9 11 13 15 17 19 21 23 25 27 29,只需要14个单元
第 1 步 把14个单元赋为true (每个单元代表的数是2*i+3,如第0单元代表3,第1单元代表5...)
第 2 步开始:
i=0; 由于prime[0]=true, 把 [3], [6], [9], [12]标为false.
i=1; 由于prime[1]=true, 把 [6], [11]标为false
i=2 2*i+3>sqrt(30)算法结束。
这样优化以后总共只走6个单位时间。
当n相当大以后这样的优化效果就更加明显,效率绝对不仅仅是翻倍。
出了这样的优化以外,另外在每一次用当前已得出的素数筛选后面的数的时候可以一步跳到已经被判定不是素数的
数后面,这样就减少了大量的重复计算。(比如我们看到的,i=0与i=1时都标了[6],这个就是重复的计算。)
我们可以发现一个规律,那就是3(即i=0)是从下标为[3]的开始筛的,5(即i=1)是从下标为[11]开始筛的(因为[6]
已经被3筛过了)。然后如果n很大的话,继续筛。7(i=2)本来应该从下标为[9]开始筛,但是由于[9]被筛过了,而
[16]也已经被5(i=1)筛过了。于是7(i=2)从[23](就是2*23+3=49)开始筛。
于是外围循环为i时,内存循环的筛法是从 i+(2*i+3)*(i+1)即i*(2*i+6)+3开始筛的。
这个优化也对算法复杂度的降低起到了很大的作用。
相比于一般的筛法,加入这两个优化后的筛法要高效很多。高兴去的同学可以试着自己编写程序看一看效率。我这里
有程序,需要的可以向我要。不懂得也可以问我。
上面的素数筛法是所有程序设计竞赛队员都必须掌握的,而后面加了两个优化的筛法是效率很高的算法,是湖南大学
huicpc39同学设计的(可能是学来的,也可能是自创的。相当强悍)。在数量级更大的情况下就可以发现一般筛法和
优化后的筛法的明显区别。
另外,台湾的ACMTino同学也给我介绍了他的算法:a是素数,则下一个起点是a*a,把后面的所有的a*a+2*i*a筛掉。
这上面的所有的素数筛选的算法都可以再进一步化为二次筛选法,就是欲求n以内的素数,就先把sqrt(n)内的素数求
出来,用已经求得的素数来筛出后面的合数。
我把一般的筛选法的过程详细的叙述了一遍,应该都懂了吧?后面的优化过程及不同的方法,能看懂最好。不是很难的。
相关知识:
最大公约数只有1和它本身的数叫做质数(素数)——这个应该知道吧?-_-b
至今为止,没有任何人发现素数的分布规律,也没有人能用一个公式计算出所有的素数。关于素数的很多的有趣的性质或者科学家的努力
我不在这里多说,大家有兴趣的话可以到网络或google搜一下。我在下面列出了一个网址,上面只有个大概。更多的知识需要大家一点一点
地动手收集。
http://www.scitom.com.cn/discovery/universe/home01.html
1.高斯猜测,n以内的素数个数大约与n/ln(n)相当,或者说,当n很大时,两者数量级相同。这就是着名的素数定理。
2.十七世纪费马猜测,2的2^n次方+1,n=0,1,2…时是素数,这样的数叫费马素数,可惜当n=5时,2^32+1就不是素数,
至今也没有找到第六个费马素数。
3.18世纪发现的最大素数是2^31-1,19世纪发现的最大素数是2^127-1,20世纪末人类已知的最大素数是2^859433-1,用十进制表示,这是一个258715位的数字。
4.孪生素数猜想:差为2的素数有无穷多对。目前知道的最大的孪生素数是1159142985×2^2304-1和1159142985×2^2304+1。
5.歌德巴赫猜想:大于2的所有偶数均是两个素数的和,大于5的所有奇数均是三个素数之和。其中第二个猜想是第一个的自然推论,因此歌德巴赫猜想又被称为1+1问题。我国数学家陈景润证明了1+2,即所有大于2的偶数都是一个素数和只有两个素数因数的合数的和。国际上称为陈氏定理。
㈣ 地理中对跖点的算法,求详细经过,举个例子,一定要详细经过,我地理学的撇,求详细,谢谢
地理中对跖点就是这个地点关于地心的对称点。计算一个地点关于地心的对称点位置时,把南北纬度互换,把经度换成与该地点相差180°即可。例如计算北纬40°,东经120°关于地心对称的位置,把北纬换成南纬,即南纬40°,把经度换成相差180°的,就是西经60° 。
㈤ 用C++写的分治算法求最近点对的问题,求高手解答! 出错提示:访问冲突
重新检查你程序中的数组使用,是否越界,还是指针指向的内存空间有问题,因为你给的是程序的片段,所以无法帮你调试运行,只能够看了之后提出建议,谢谢!
祝你成功~~~
㈥ 24点的算法技巧
1、利用3×8=24、4×6=24求解。
把牌面上的四个数想办法凑成3和8、4和6,再相乘求解。如3、3、6、10可组成(10—6÷3)×3=24等。又如2、3、3、7可组成(7+3—2)×3=24等。实践证明,这种方法是利用率最大、命中率最高的一种方法。
2、利用0、11的运算特性求解。
如3、4、4、8可组成3×8+4—4=24等。又如4、5、J、K可组成11×(5—4)+13=24等。
3、在有解的牌组中,用得最为广泛的是以下六种解法:(我们用a、b、c、d表示牌面上的四个数)
①(a—b)×(c+d)
如(10—4)×(2+2)=24等。
②(a+b)÷c×d
如(10+2)÷2×4=24等。
③(a-b÷c)×d
如(3—2÷2)×12=24等。
④(a+b-c)×d
如(9+5—2)×2=24等。
⑤a×b+c—d
如11×3+l—10=24等。
⑥(a-b)×c+d
如(4—1)×6+6=24等。
(6)点对算法扩展阅读
乘法是加法的简便运算,除法是减法的简便运算。
减法与加法互为逆运算,除法与乘法互为逆运算。
整数的加减法运算法则:
1、相同数位对齐;
2、从个位算起;
3、加法中满几十就向高一位进几;减法中不够减时,就从高一位退1当10和本数位相加后再减。
加法运算性质
从加法交换律和结合律可以得到:几个加数相加,可以任意交换加数的位置;或者先把几个加数相加再和其他的加数相加,它们的和不变。例如:34+72+66+28=(34+66)+(72+28)=200。
㈦ 二十四点算法是什么
例如:4个数A、B、C、D,我们可以用F(A,B,C,D)=24来表示。那么。我们就可以把函数F拆解成F1(B,C,D)=P1(24,A)。(意思是:B,C,D之间的四则运算可以得到A和24之间的四则运算结果)。那么F1又可以继续拆解为C和D之间的四则运算关系得到结果后再和B来一次四则运算结果。这样,就可以得到很简单的一个数组6*6*6=216种结果而已。当然,这是A,B,C,D顺序固定的组合,那么把A,B,C,D换个位置,又一种组合。所以,所有的结果有6*6*6*12种。但,我们还是忽略了一种情况:A和B的值与C和D的值再进行四则运算,那么我们还需要再加一组6*6*6就可以了。
㈧ 如何对点进行k均值聚类算法 matlab
在聚类分析中,K-均值聚类算法(k-means algorithm)是无监督分类中的一种基本方法,其也称为C-均值算法,其基本思想是:通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果.\x0d假设要把样本集分为c个类别,算法如下:\x0d(1)适当选择c个类的初始中心;\x0d(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类,\x0d(3)利用均值等方法更新该类的中心值;\x0d(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代.\x0d下面介绍作者编写的一个分两类的程序,可以把其作为函数调用.\x0d%% function [samp1,samp2]=kmeans(samp); 作为调用函数时去掉注释符\x0dsamp=[11.1506 6.7222 2.3139 5.9018 11.0827 5.7459 13.2174 13.8243 4.8005 0.9370 12.3576]; %样本集\x0d[l0 l]=size(samp);\x0d%%利用均值把样本分为两类,再将每类的均值作为聚类中心\x0dth0=mean(samp);n1=0;n2=0;c1=0.0;c1=double(c1);c2=c1;for i=1:lif samp(i)<th0\x0dc1=c1+samp(i);n1=n1+1;elsec2=c2+samp(i);n2=n2+1;endendc1=c1/n1;c2=c2/n2; %初始聚类中心t=0;cl1=c1;cl2=c2;\x0dc11=c1;c22=c2; %聚类中心while t==0samp1=zeros(1,l);\x0dsamp2=samp1;n1=1;n2=1;for i=1:lif abs(samp(i)-c11)<abs(samp(i)-c22)\x0dsamp1(n1)=samp(i);\x0dcl1=cl1+samp(i);n1=n1+1;\x0dc11=cl1/n1;elsesamp2(n2)=samp(i);\x0dcl2=cl2+samp(i);n2=n2+1;\x0dc22=cl2/n2;endendif c11==c1 && c22==c2t=1;endcl1=c11;cl2=c22;\x0dc1=c11;c2=c22;\x0dend %samp1,samp2为聚类的结果.\x0d初始中心值这里采用均值的办法,也可以根据问题的性质,用经验的方法来确定,或者将样本集随机分成c类,计算每类的均值.\x0dk-均值算法需要事先知道分类的数量,这是其不足之处.
㈨ Floyd算法是什么
Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。
通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。
从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
采用的是(松弛技术),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3); 其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]} map[i,j]表示i到j的最短距离 K是穷举i,j的断点 map[n,n]初值应该为0,或者按照题目意思来做。
当然,如果这条路没有通的话,还必须特殊处理,比如没有map[i,k]这条路
㈩ C#获取不规则点列图各点坐标的方法 算法 问题
建议:
先基于原数据的点建立平面直角坐标系,确定各个点的位置
以两列间最小间隔和两行间最小间隔的公约数为一个区间,制作矩阵,如果不好确定,以“1”为单位制作矩阵
确定每一横行的和每一纵列,然后进行获取点坐标,赋值