【知识碎片】4:SQL练习,MPI编程

SQL练习

--在E表中插入记录,把每个学生没学过的课程都插入到E表中
--使得每个学生都选修每门课
USE school;
INSERT INTO E(xh,xq,kh,gh)
SELECT EXPSET.xh,OK.xq,EXPSET.kh,OK.gh
FROM
(
SELECT *
FROM
    (
    SELECT S0.xh,O0.kh
    FROM
        dbo.S AS S0
            CROSS JOIN
        dbo.O AS O0
    ) AS NEWS
    EXCEPT --自带DISTINCT
    (
    SELECT E0.xh,E0.kh
    FROM
        dbo.E AS E0
    )
) AS EXPSET
LEFT JOIN
(
SELECT O1.xq,O1.gh,O1.kh
FROM
    dbo.O AS O1
) AS OK
ON
    OK.kh=EXPSET.kh
WHERE
    OK.gh>=ALL  (
                SELECT O2.gh
                FROM dbo.O AS O2
                WHERE O2.kh=OK.kh
                );


--求年龄大于所有女同学年龄的男学生姓名和年龄
USE school;
SELECT S0.xm AS '年龄',DATEDIFF(YEAR,S0.csrq,'2018-1-1') AS '年龄'
FROM dbo.S AS S0
WHERE
    S0.csrq<ALL (
                SELECT S1.csrq
                FROM dbo.S AS S1
                WHERE S1.xb='女'
                );

--在E表中修改08305001课程的平时成绩
--若成绩小于等于75分时提高5%
--若成绩大于75分时提高4%
USE school;
UPDATE dbo.E
SET E.pscj=E.pscj*1.04
WHERE E.pscj>75;

UPDATE dbo.E
SET E.pscj=E.pscj*1.05
WHERE E.pscj<75;

--删除没有开课的学院
--外键约束问题,以后找时间解决 
DELETE
FROM dbo.D
WHERE
    yxh not in  (
                SELECT yxh
                FROM
                    dbo.T
                        CROSS JOIN 
                    dbo.O
                WHERE T.gh=O.gh
                );

--查询优、良、中、及格、不及格学生人数
SELECT
(
    SELECT COUNT(*)
    FROM
    (
    SELECT zpcj
    FROM dbo.E
    GROUP BY zpcj
    HAVING zpcj>90
    ) AS LH
) AS '优秀',
(
    SELECT COUNT(*)
    FROM
    (
    SELECT zpcj
    FROM dbo.E
    GROUP BY zpcj
    HAVING zpcj>=80 AND zpcj<90
    ) AS LH
) AS '良好',
(
    SELECT COUNT(*)
    FROM
    (
    SELECT zpcj
    FROM dbo.E
    GROUP BY zpcj
    HAVING zpcj>=70 AND zpcj<80
    ) AS LH
) AS '中等',
(
    SELECT COUNT(*)
    FROM
    (
    SELECT zpcj
    FROM dbo.E
    GROUP BY zpcj
    HAVING zpcj>=60
    ) AS JG
) AS '及格',
(
    SELECT COUNT(*)
    FROM
    (
    SELECT zpcj
    FROM dbo.E
    GROUP BY zpcj
    HAVING zpcj<60
    ) AS BJG
) AS '不及格';

MPI编程

广播Bcast和规约Reduce

编写MPI程序,并行计算从1~N的整数和。

#include<stdio.h>
#include<mpi.h>//用mpi函数

const int MAX_STR=100;//字符数组最大长度

int main()
{
    int comm_sz;//进程数
    int my_rank;//本进程的编号
    int i,sum=0;//游标,本进程加和
    int allsum=0;//所有进程加和,给0号进程用
    int N;//待用户键入的数,表示从1加到N

    MPI_Init(NULL,NULL);//初始化MPI
    MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);//获取进程数
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);//获取本进程号

    if(my_rank==0)//如果是0号进程
    {
        printf("Input N:");
        scanf("%d",&N);//只有0号进程能接受标准输入
    }
    //将0号进程收到的N广播给所有进程
    MPI_Bcast(&N,1,MPI_INT,0,MPI_COMM_WORLD);

    int k=N/comm_sz;//k表示要分成的每份的data数目
    if(N%comm_sz!=0)//如果这样分还有剩余
        k+=1;//那么显然要加1,对于最后一个特殊处理即可

    //循环地把自己要加的数据加进sum里
    //对最后一个的特殊处理,即是看其是否到达N
    for(i=my_rank*k+1;i<=(my_rank+1)*k && i<=N;i++)
        sum+=i;

    //规约,采用MPI_SUM操作符说明是要做求和
    //将所有的sum作为输入,而只有0号进程接受并加进allsum
    MPI_Reduce(&sum,&allsum,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);

    //仅在0号进程上统计最后的加和
    if(my_rank==0)
        printf("%d\n",allsum);

    MPI_Finalize();//使用完释放为MPI分配的资源
    return 0;
}
putty的psftp工具传文件

要用老师的远程服务器传写好的文件上去,首先在putty里面保存好这个session(会话):
这里写图片描述

相关的工具有psftp,可以用SSH传文件上去,再这个目录下建一个文件夹(如root),把写好的代码放进去,上传时候这个路径就很好找了。
这里写图片描述

这时候可以打开psftp了,用open后跟域名的方式,在里面登录,登录好以后进到自己的文件夹,就能用put上传,get下载了:
这里写图片描述

另一边SSH登录的账户,在这边上传完立刻就可以用了(网速快就是好):
这里写图片描述

书上例子1

一对一通信。

#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>
#include<string.h>

const int MAX_STRING=100;

int main()
{
    char greeting[MAX_STRING];//用来交换信息
    int comm_sz;//进程数目
    int my_rank;//本进程号码

    MPI_Init(NULL,NULL);//初始化MPI,会等所有进程完成初始化再继续
    MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);//获得进程数目
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);//获得本进程号码

    if(my_rank!=0)//不是0号进程
    {
        //把这句话写进字符串(字符数组)greeting里
        sprintf(greeting,"Greetings from process %d of %d!",
                my_rank,comm_sz);
        //发送给0号进程
        //(消息始址,尺寸大小,
        //类型,目的进程号,标签,通信域)
        MPI_Send(greeting,strlen(greeting)+1,
                MPI_CHAR,0,0,MPI_COMM_WORLD);   
    }
    else//0号进程
    {
        //这里my_rank也就是0
        printf("Greetings from process %d of %d!\n",
                my_rank,comm_sz);
        //按进程号接收其它进程发来的消息
        int q;
        for(q=1;q<comm_sz;q++)
        {
            //按进程号收信息
            //(接收到何处,尺寸大小,类型,源进程号,
            //标签,通信域,更多信息)
            MPI_Recv(greeting,MAX_STRING,MPI_CHAR,q,
                    0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
            printf("%s\n",greeting);
        }
    }

    MPI_Finalize();

return 0;
}

这里写图片描述

这里写图片描述

书上例子2

计算函数的定积分,只能在小梯形数目被进程数目整除的情况下正确运行。

#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>
#include<string.h>

/*MPI并行梯形积分法*/

//具体的要积分的函数
double f(double x)
{
    return 3*x*x+2*x+1; 
}

//计算个范围内函数的梯形积分法近似积分的函数
double Trap(
        double left_endpt,//左边界
        double right_endpt,//右边界
        int trap_count,//分成多少份
        double base_len//每一份的长度
    )
{
    double estimate,x;//总积分面积,移动的x
    int i;
    //头尾两个高度(函数值)只用到一次
    estimate=(f(left_endpt)+f(right_endpt))/2.0;
    //除了头尾这两份的函数值用到两次,其加和
    for(i=1;i<=trap_count-1;i++)
    {
        x=left_endpt+i*base_len;//x每次移动base_len这么长
        estimate+=f(x);//加上这一处的函数值(左右梯形用了两次所以不除以2)
    }
    estimate=estimate*base_len;//再整体乘以每一份的长度base_len即可
    return estimate;
}


int main()
{
    int my_rank;//本进程号
    int comm_sz;//总进程数
    int n=1024;//1024个小区间
    int local_n;//每个进程处理的小梯形数目
    double a=0.0;//起始点
    double b=3.0;//终止点
    double h;//小梯形的高(x方向小长度)
    double local_a;//本进程处理的起始点
    double local_b;//本进程处理的终止点
    double local_int;//自己这个进程负责的那部分的积分值
    double total_int;//总积分值,给0号进程用
    int source;//在接收消息时,用来指示源进程的游标

    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);//获取本进程号
    MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);//总进程数

    h=(b-a)/n;//计算小梯形高
    local_n=n/comm_sz;//本进程处理的小梯形数=总数/总进程数

    local_a=a+my_rank*local_n*h;//本进程处理的起始点=起始点+我的进程号*每个进程应当处理的总长度
    local_b=local_a+local_n*h;//本进程处理的终止点=本进程处理的起始点+每个进程应处理的长度
    local_int=Trap(local_a,local_b,local_n,h);//计算在这个范围内,用local_n个小梯形模拟,每个小梯形高度是h(感觉这后两个参数互相多余)时,算出来的面积

    if(my_rank!=0)//如果不是0号进程
    {
        //把每个进程处理完得到的面积发给0号进程
        //(消息始址,尺寸大小,类型,目的进程号,标签,
        //通信域)
        MPI_Send(&local_int,1,MPI_DOUBLE,0,0,
                MPI_COMM_WORLD);
    }
    else//对于0号进程
    {
        total_int=local_int;//总数初始化为自己计算的面积
        for(source=1;source<comm_sz;source++)
        {
            //接收来自其它进程的消息
            //(接收到何处,尺寸大小,类型,
            //源进程号,标签,通信域,
            //更多信息)
            MPI_Recv(&local_int,1,MPI_DOUBLE,
                    source,0,MPI_COMM_WORLD,
                    MPI_STATUS_IGNORE);
            total_int+=local_int;//加到总积分上
        }
    }

    if(my_rank==0)//仅由0号进程输出结果
    {
        printf("With n=%d trapezoids,our estimate\n",n);
        printf("of the integral from %f to %f=%.15e\n",
                a,b,total_int);
    }
    MPI_Finalize();
return 0;
}

这里写图片描述

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值