1. 什么是最优适应分配算法
分区分配算法(Partitioning Placement Algorithm) ,共有3种。分别为最佳适应算法、首次适应算法、循环首次适应算法。
1、最佳适应算法(Best Fit):
它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表(空闲区链)中的空闲分区要按大小从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。该算法保留大的空闲区,但造成许多小的空闲区。
2、首次适应算法(First Fit):
从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。
3、循环首次适应算法(Next Fit):
该算法是首次适应算法的变种。在分配内存空间时,不再每次从表头(链首)开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。
2. 求多个矩阵联乘的最优算法!
程序功能:用分而治之算法计算两个n维矩阵相乘的结果
其中n必须是2的正整数次幂。
运行过程:首先,根据提示输入矩阵的维数n
其次,根据提示分别输入矩阵A和B
最后,显示矩阵A和矩阵B以及其相乘结果矩阵C
****************************************/
#include "stdio.h"
#define mytype int//矩阵元素的数据类型
#define myinputmode "%d"//矩阵元素的输入格式
#define myprintmode "%4d"//矩阵元素的输出格式
/*以上参数的设置可根据所计算矩阵的元素的数值类型进行相应改变
如更改为浮点型数据则可以使用下面的设置
#define mytype float
#define myinputmode "%f"
#define myprintmode "%6.2f"
*/
/////////////////////////////////////////
/****************************************
函数名:is2
参数:m为长整型整数
功能:检测m是否是2的正整数次幂
返回值:返回布尔型变量
true则表示m为2的正整数次幂
false则表示m不是2的正整数次幂
****************************************/
bool is2(long m)
{
if(m<0)return false;
if(m>=2)
{
if((m%2)==0) return is2(m/2);
else return false;
}
else
{
if(m==1)return true;
else return false;
}
return false;
}
/////////////////////////////////////////
/****************************************
函数名:inputmatrix
参数:M为指向数组的指针,用来存储输入的矩阵
m长整型,是数组M所存矩阵的维数
name字符型数组,是需要进行数据输入的矩阵的名字
功能:矩阵数据输入的函数,通过输入矩阵的每个元素将
矩阵存入数组
返回值:无
****************************************/
void inputmatrix(mytype * M,long m,char *name)
{
long i,j;
for(i=0;i<m;i++)
for(j=0;j<m;j++)
{
printf("Please input the %s(%d,%d):",name,i+1,j+1);
getchar();
scanf(myinputmode,&M[i*m+j]);
}
}
/////////////////////////////////////////
/****************************************
函数名:printmatrix
参数:M为指向数组的指针,数组中存储着矩阵
m长整型,是数组M所存矩阵的维数
name字符型数组,是需要进行数据输入的矩阵的名字
功能:矩阵数据输出显示的函数,将矩阵元素一一显示一在屏幕上
返回值:无
****************************************/
void printmatrix(mytype * M,long m,char *name)
{
long i,j;
printf("\nMatrix %s:\n",name);
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
printf(myprintmode,M[i*m+j]);
}
printf("\n");
}
}
/////////////////////////////////////////
/****************************************
函数名:Matrix_add_sub
参数:A,B为指向数组的指针,数组中存储着矩阵
C为指向数组的指针,用来存储运算结果
m长整型,是数组A、B、C所存矩阵的维数
add为布尔型变量,为true则C=A+B,为false则C=A-B
功能:根据add值对A、B进行加减运算并将结果存入C
返回值:无
****************************************/
void Matrix_add_sub(mytype * A,mytype * B,mytype * C,long m,bool add)
{
long i;
for(i=0;i<m*m;i++)
{
if(add)
C[i]=A[i]+B[i];
else
C[i]=A[i]-B[i];
}
}
/////////////////////////////////////////
/****************************************
函数名:GetHalfValue
参数:B为指向数组的指针,数组中存储着矩阵。其中B是指向m维矩阵中的一个元素。
A为指向数组的指针,用来接收B中的四分之一数据
m长整型,是数组B所指矩阵的维数
功能:从B所在位置向左和向右取矩阵的m/2维的子矩阵(子矩阵中包括B所指元素)并存入A
返回值:无
****************************************/
void GetHalfValue(mytype * A,mytype * B,long m)
{
long i,j;
for(i=0;i<m/2;i++)
{
for(j=0;j<m/2;j++)
{
A[i*m/2+j]=B[i*m+j];
}
}
}
/////////////////////////////////////////
/****************************************
函数名:UpdateHalfValue
参数:B为指向数组的指针,数组中存储着矩阵。其中B是指向m维矩阵中的一个元素。
A为指向数组的指针,存储着一个m/2维矩阵
m长整型,是数组B所指矩阵的维数
功能:把A矩阵所有元素存入从B所在位置向左和向右的m/2维的子矩阵(子矩阵中包括B所指元素)
返回值:无
****************************************/
void UpdateHalfValue(mytype * A,mytype * B,long m)
{
long i,j;
for(i=0;i<m/2;i++)
{
for(j=0;j<m/2;j++)
{
B[i*m+j]=A[i*m/2+j];
}
}
}
/////////////////////////////////////////
/****************************************
函数名:Matrix_multiplication
参数:A,B为指向数组的指针,数组中存储着矩阵。
C为指向数组的指针,用来存储计算结果
m长整型,是指针A、B所指矩阵的维数
功能:用分而治之算法和Strassen方法计算A与B的乘积并存入C
返回值:无
****************************************/
void Matrix_multiplication(mytype * A,mytype * B,mytype * C,long m)
{
if(m>2)//当矩阵维数大于2时
{
//将矩阵A、B分为四个小矩阵,分别为A1、A2、A3、A4、B1、B2、B3、B4
mytype *A1=new mytype[m*m/4],*A2=new mytype[m*m/4],*A3=new mytype[m*m/4],*A4=new mytype[m*m/4],*B1=new mytype[m*m/4],*B2=new mytype[m*m/4],*B3=new mytype[m*m/4],*B4=new mytype[m*m/4],*C1=new mytype[m*m/4],*C2=new mytype[m*m/4],*C3=new mytype[m*m/4],*C4=new mytype[m*m/4];
GetHalfValue(A1,&A[0],m);
GetHalfValue(A2,&A[m/2],m);
GetHalfValue(A3,&A[m*m/2],m);
GetHalfValue(A4,&A[m*m/2+m/2],m);
GetHalfValue(B1,&B[0],m);
GetHalfValue(B2,&B[m/2],m);
GetHalfValue(B3,&B[m*m/2],m);
GetHalfValue(B4,&B[m*m/2+m/2],m);
//利用Strassen方法计算D、E、F、G、H、I、J
mytype *D=new mytype[m*m/4],*E=new mytype[m*m/4],*F=new mytype[m*m/4],*G=new mytype[m*m/4],*H=new mytype[m*m/4],*I=new mytype[m*m/4],*J=new mytype[m*m/4];
mytype *temp1=new mytype[m*m/4],*temp2=new mytype[m*m/4];
//D=A1(B2-B4)
Matrix_add_sub(B2,B4,temp1,m/2,false);
Matrix_multiplication(A1,temp1,D,m/2);
//E=A4(B3-B1)
Matrix_add_sub(B3,B1,temp1,m/2,false);
Matrix_multiplication(A4,temp1,E,m/2);
//F=(A3+A4)B1
Matrix_add_sub(A3,A4,temp1,m/2,true);
Matrix_multiplication(temp1,B1,F,m/2);
//G=(A1+A2)B4
Matrix_add_sub(A1,A2,temp1,m/2,true);
Matrix_multiplication(temp1,B4,G,m/2);
//H=(A3-A1)(B1+B2)
Matrix_add_sub(A3,A1,temp1,m/2,false);
Matrix_add_sub(B1,B2,temp2,m/2,true);
Matrix_multiplication(temp1,temp2,H,m/2);
//I=(A2-A4)(B3+B4)
Matrix_add_sub(A2,A4,temp1,m/2,false);
Matrix_add_sub(B3,B4,temp2,m/2,true);
Matrix_multiplication(temp1,temp2,I,m/2);
//J=(A1+A4)(B1+B4)
Matrix_add_sub(A1,A4,temp1,m/2,true);
Matrix_add_sub(B1,B4,temp2,m/2,true);
Matrix_multiplication(temp1,temp2,J,m/2);
//利用Strassen方法计算C1、C2、C3、C4
//C1=E+I+J-G
Matrix_add_sub(E,I,temp1,m/2,true);
Matrix_add_sub(J,G,temp2,m/2,false);
Matrix_add_sub(temp1,temp2,C1,m/2,true);
//C2=D+G
Matrix_add_sub(D,G,C2,m/2,true);
//C3=E+F
Matrix_add_sub(E,F,C3,m/2,true);
//C4=D+H+J-F
Matrix_add_sub(D,H,temp1,m/2,true);
Matrix_add_sub(J,F,temp2,m/2,false);
Matrix_add_sub(temp1,temp2,C4,m/2,true);
//将计算结果存入数组C
UpdateHalfValue(C1,&C[0],m);
UpdateHalfValue(C2,&C[m/2],m);
UpdateHalfValue(C3,&C[m*m/2],m);
UpdateHalfValue(C4,&C[m*m/2+m/2],m);
//释放内存
delete[] A1,A2,A3,A4,B1,B2,B3,B4,C1,C2,C3,C4,D,E,F,G,H,I,J,temp1,temp2;
}
else
{
//当矩阵维数小于2时用Strassen方法计算矩阵乘积
mytype D,E,F,G,H,I,J;
//D=A1(B2-B4)
D=A[0]*(B[1]-B[3]);
//E=A4(B3-B1)
E=A[3]*(B[2]-B[0]);
//F=(A3+A4)B1
F=(A[2]+A[3])*B[0];
//G=(A1+A2)B4
G=(A[0]+A[1])*B[3];
//H=(A3-A1)(B1+B2)
H=(A[2]-A[0])*(B[0]+B[1]);
//I=(A2-A4)(B3+B4)
I=(A[1]-A[3])*(B[2]+B[3]);
//J=(A1+A4)(B1+B4)
J=(A[0]+A[3])*(B[0]+B[3]);
//C1=E+I+J-G
C[0]=E+I+J-G;
//C2=D+G
C[1]=D+G;
//C3=E+F
C[2]=E+F;
//C4=D+H+J-F
C[3]=D+H+J-F;
}
}
/////////////////////////////////////////
int main()
{
long n;
//提示输入n维矩阵的维数
printf("Please input the dimension of the Matrix.(n):");
//获得用户输入的n维矩阵维数
scanf("%d",&n);
while(!is2(n))//检查维数是否是2的幂,不是则要求重新输入
{
printf("Please reinput the dimension of the Matrix.(n):");
scanf("%d",&n);
}
//开辟空间存储用来存储n维矩阵元素
mytype *A=new mytype[n*n];
mytype *B=new mytype[n*n];
mytype *C=new mytype[n*n];
//输入矩阵A、B
inputmatrix(A,n,"A");
inputmatrix(B,n,"B");
if(n>1)//矩阵维数大于1则用分而治之算法计算
Matrix_multiplication(A,B,C,n);
else//矩阵维数为1则直接计算
*C=(*A)*(*B);
//输出矩阵A、B、C
printmatrix(A,n,"A");
printmatrix(B,n,"B");
printmatrix(C,n,"C");
//释放内存
delete[] A,B,C;
getchar();getchar();
return 1;
}
3. 请问数钱的贪婪算法怎样确保得到最优解
贪婪算法:总是作出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅是在某种意义上的局部最优解。
(注:贪婪算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题它能产生整体最优解。但其解必然是最优解的很好近似解。
基本思路:——从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止
实现该算法的过程:
从问题的某一初始解出发;
while 能朝给定总目标前进一步 do
求出可行解的一个解元素;
由所有解元素组合成问题的一个可行解;
基本要素:
1、 贪婪选择性质:所求问题的整体最优解可以通过一系列局部最优的选择,即贪婪选择来达到。(与动态规划的主要区别)
采用自顶向下,以迭代的方式作出相继的贪婪选择,每作一次贪婪选择就将所求问题简化为一个规模更小的子问题。
对于一个具体问题,要确定它是否具有贪婪选择的性质,我们必须证明每一步所作的贪婪选择最终导致问题的最优解。通常可以首先证明问题的一个整体最优解,是从贪婪选择开始的,而且作了贪婪选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法证明,通过每一步作贪婪选择,最终可得到问题的一个整体最优解。
2、最优子结构性质:包含子问题的最优解
1、 设有n个活动的安排,其中每个活动都要求使用同一资源,如演讲会场,而在同一时间只允许一个活动使用这一资源。每个活动都有使用的起始时间和结束时间。问:如何安排可以使这间会场的使用率最高。
活动 起始时间 结束时间
1 1 4
2 3 5
3 0 6
4 5 7
5 3 8
6 5 9
7 6 10
8 8 11
9 8 12
10 2 13
11 12 14
算法:一开始选择活动1,然后依次检查活动一i是否与当前已选择的所有活动相容,若相容则活动加入到已选择的活动集合中,否则不选择活动i,而继续检查下一活动的相容性。即:活动i的开始时间不早于最近加入的活动j的结束时间。
Prodere plan;
Begin
n:=length[e];
a {1};
j:=1;
for i:=2 to n do
if s[i]>=f[j] then
begin a a∪{i};
j:=i;
end
end;
例1 [找零钱] 一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪婪准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。
假设需要找给小孩6 7美分,首先入选的是两枚2 5美分的硬币,第三枚入选的不能是2 5美分的硬币,否则硬币的选择将不可行(零钱总数超过6 7美分),第三枚应选择1 0美分的硬币,然后是5美分的,最后加入两个1美分的硬币。
贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少(见练习1)。
4. 怎样应用贪心算法求得最优解
动态规划要求。。具有最优子结构,记f[i]最优时,f[i - 1]的解也最优。。。最终可以得到最优解
贪心算法,一般只能得到近优解或者局部最优解。。
5. 数学建模怎样处理一堆数据然后求出最优解
优化问题的话可以考虑用lingo求解,语法不难,看一个例子就会了,问题复杂的话需要比较长的时间,起码是半个小时,有的还要一晚上,因为它是不停迭代求解。也可以用MATLAB进行算法求解,比较着名的有模拟退火算法,蚁群算法,粒子群算法等等,都有现成的程序。
6. 求数独游戏最优算法,该怎么处理
一般的标准数独的普通算法就是暴搜,公认比较好的算法就是舞蹈链Dancing Links,一些简单的题目暴搜结合逻辑解法的剪枝可能时间优势更大,几年前最快的数独算法是一个叫周运栋的中国人的zsolve,具体算法不详,目前没听说还有更快的算法 。
7. 什么是网格搜索法如何用它来优化学习算法
网格搜索法是指定参数值的一种穷举搜索方法,通过将估计函数的参数通过交叉验证的方法进行优化来得到最优的学习算法。
即,将各个参数可能的取值进行排列组合,列出所有可能的组合结果生成“网格”。然后将各组合用于SVM训练,并使用交叉验证对表现进行评估。在拟合函数尝试了所有的参数组合后,返回一个合适的分类器,自动调整至最佳参数组合,可以通过clf.best_params_获得参数值
8. 求最优解的算法
拉蛤螂日乘子法或线性规划和非线性规划,都可以得到最优解。
9. 迷宫问题得到最优算法的条件是什么
源程序://base.h#include#include#include#defineTRUE1#defineFALSE0#defineOK1#defineERROR0#defineOVERFLOW-2typedefintStatus;//stack.h#include"base.h"#defineINIT_SIZE100//存储空间初始分配量#defineINCREMENT10//存储空间分配增量typedefstruct{//迷宫中r行c列的位置intr;intc;}PostType;typedefstruct{intord;//当前位置在路径上的序号PostTypeseat;//当前坐标intdi;//往下一坐标的方向}SElemType;//栈元素类型typedefstruct{SElemType*base;//栈基址,构造前销毁后为空SElemType*top;//栈顶intstackSize;//栈容量}Stack;//栈类型StatusInitStack(Stack&S){//构造空栈sS.base=(SElemType*)malloc(INIT_SIZE*sizeof(SElemType));if(!S.base)exit(OVERFLOW);//存储分配失败S.top=S.base;S.stackSize=INIT_SIZE;returnOK;}//InitStackStatusStackEmpty(StackS){//若s为空返回TRUE,否则返回FALSEif(S.top==S.base)returnTRUE;returnFALSE;}//StackEmptyStatusPush(Stack&S,SElemTypee){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stackSize){//栈满,加空间S.base=(SElemType*)realloc(S.base,(S.stackSize+INCREMENT)*sizeof(SElemType));if(!S.base)exit(OVERFLOW);//存储分配失败S.top=S.base+S.stackSize;S.stackSize+=INCREMENT;}*S.top++=e;returnOK;}//pushStatusPop(Stack&S,SElemType&e){//若栈不空删除栈//顶元素用e返回并返回OK,否则返回ERRORif(S.top==S.base)returnERROR;e=*--S.top;returnOK;}//PopStatusDestroyStack(Stack&S){//销毁栈S,free(S.base);S.top=S.base;returnOK;
10. 请牛人指点,如何以最优的算法,对两点间的距离进行排序
开一个计数数组vis[i],一开始清零,然后输入第一个数列,每输入一个数x,就vis[x]++。这样vis[i]代表i这个数字出现的次数。然后输入第二个数列,每输入一个数x,就vis[x]--,处理过程中检查vis[x]是不是负数,如果是则说明两个数列不相等,处理完之后,若vis[i]中全为0,说明相等。时间复杂度O(N),空间复杂度O(maxnum) 当数据的数值范围不大的时候可以使用这个方法。