软件工程实践2017第二次做业

Github链接https://github.com/zora02/object-oriented/tree/master/BIN
https://github.com/zora02/object-oriented/blob/master/shuduku.cpphtml

1、项目相关要求

利用程序随机构造出N个已解答的数独棋盘 。ios

输入c++

数独棋盘题目个数N(0< N <= 1000000)git

输出github

随机生成N个不重复的已解答完毕的数独棋盘,并输出到sudoku.txt中。c#

2、遇到的困难及解决方法

构造数独:最开始想经过随机数先生成一个九宫格,再删除掉里面的重复数,再求解。但是这个方法我写出来之后常常进入死循环,试了不少办法,就是改不出bug(╥﹏╥),并且这个代码效率比较慢。后来我去百度知道了回溯法构造数独,以为这个方法效率高些,并学习了来使用。windows

参考代码:http://blog.csdn.net/hustspy1990/article/details/7464698xcode

(其实看了这个代码之后,我深受影响,把本身的设想都推翻了,总以为本身的方法不太好,想学习这个方法。我认真理解了这个方法之后,就用了,可是代码写出来就差很少了,我挺惧怕被判抄袭的,我不知道学习了这个方法用起来,算不算抄袭(´・_・`))dom


生成随机数:在生成随机数的时候,最开始我不会使用随机数,就去查资料:函数

http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html

rand()产生的随机数在每次运行的时候都是与上一次相同的。若要不一样,用函数srand()初始化它。能够利用srand((unsigned int)(time(NULL))的方法,产生不一样的随机数种子,由于每一次运行程序的时间是不一样的。

由于是生成多个随机数独,因此我把构造数独的函数放到循环里去生成,结果发现每次产生的数独都同样,最开始觉得是随机数的随机性没有那么强,但是这与资料里说的用time初始化种子每次都不同相矛盾。我就去尝试把随机生成的不完整数独输出查看,发现每次输出的数独并不同。觉得本身构造方法错了,但是我以为这个方法不影响不一样数独的随机性。

去查了资料发现:

应用在一个FOR循环中,取到的多个随机值就基本相同的缘由以下:
用系统时间作随机种子并不保险,若是应用程序在一个较快的计算机上运行,则该计算机的系统时钟可能没有时间在此构造函数的调用之间进行更改,Random 的不一样实例的种子值

原来是srand()不能放在for循环内,应该放到外面初始化种子才不会重复。中途还想要用guid生成随机数,可是好像在c#中适用,c++用的不多,不太方便的样子。


使用命令行编译:因为我没有windows系统的电脑,本身电脑装双系统,又装vs的话系统很容易崩掉,惨痛教训,因此个人IDE是Xcode。做业里要求的用命令行进行编译,我是借用别人的电脑进行尝试和修改的,可是好像不太成功,-c能够编译,可是好像没法识别后面的数,数目要输入两遍(T_T),查了好久资料也不知道怎么解决。

3、关键代码

检查九宫格内数是否合法:利用bool函数判断

bool shudu_check(int shudu[][9],int x,int y)
{
    int i,j;
    int temp = shudu[x][y];
    //检验同一行数是否有重复
    for(i=0;i<9;i++)
    {
        if(i!=x && shudu[i][y] == temp)
            return false;
    }
    //检验同一列数是否有重复
    for(j=0;j<9;j++)
    {
        if(j!=y && shudu[x][j] == temp)
            return false;
    }
    //检验小九宫格内数是否有重复
    int x0=(x/3)*3;
    int y0=(y/3)*3; //(x0,y0)是(x,y)所属小九宫格内左上角第一格的坐标
    for (i = x0; i<x0+3; i++)
    {
        for(j=y0; j<y0+3; j++)
        {
            if(i!=x && j!=y && shudu[i][j]==temp)
                return false;
        }
    }
    return true;
}

构造数独:回溯法,基本思想就是深度优先搜索(DFS),对不完整随机数独每一个数进行检查,数知足条件就检查下一个数,不知足条件就退回,并把数置0,从新赋予知足条件的数。

void shudu_generate(int flag)
{
    int shudu[9][9]={0};
    int x, y;
    shudu[0][0]=4;
    //生成随机数赋值给九宫格
    for(int i=0; i<9; i++)
    {
        int a=rand()%81;
        if(a/9!=0 || a%9!=0)  //限制shudu[0][0]为固定值
            shudu[a/9][a%9]=i+1;
    }
    
    //回溯法构造数独
    int t=1;
    while(flag==1)
    {
        x=t/9;
        y=t%9;
        while(flag==1)
        {
            shudu[x][y]++;
            if(shudu[x][y]>9) //回溯,把数置零
            {
                shudu[x][y]=0;
                t--;break;
            }
            else if(shudu_check(shudu,x,y)==true)//合法,检查下一个数
            {
                t++;break;
            }
        }
        if(t==81)
        {
            shudu_print(shudu);
            cout<<endl;
            flag=0;
        }
    }
    return;
}

4、测试运行及性能分析

(先在这里解释一下,我代码和博客的编写都是在Mac系统下完成的,只是借用别人的windows电脑编译完成,生成exe文件提交,因此我测试运行与性能分析都是由Xcode完成,请见谅T_T)

测试运行

测试结果截屏

性能分析

(因为种种缘由我借用的windows电脑里的vs软件没法生成性能分析报告,好像是缺乏一个项目,可是我下了sp1,仍是不行,因此我尝试着用xcode,可是我好像不太会用)

其实我没有搞懂性能分析报告,看得有点迷,也不知道该如何下手去修改代码(>_<)
也没有在网上找到一些教程,更多关于xcode性能测试的教程都是关于ios开发的

只是找到这篇http://blog.csdn.net/ggghub/article/details/50325637 多是本身知识储备太少,我基本看不太懂这个性能分析该如何使用,因此我没有去优化代码,真的不知道怎么改(T_T)可是我试着去看看运行比较大数据的时候CPU的状况,好像不太乐观??CPU占比有点大是这个意思吗?我以为可能仍是构造数独函数消耗最大。

这是刚开始测试num=1000的状况:

5、PSP

PSP2.1 Personal Software Process Stages 预估耗时 实际耗时
Planning 计划 1.5h 3-4h
· Estimate · 估计这个任务须要多少时间 2days 3days
Development 开发 2h 3h
· Analysis · 需求分析 (包括学习新技术) 3-4h 3-4h
· Design Spec · 生成设计文档 1h 2-3h
· Design Review · 设计复审 (和同事审核设计文档) 30mins 1h
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30mins 30mins
· Design · 具体设计 1h 1h
· Coding · 具体编码 2h 3h
· Code Review · 代码复审 30mins 1h
· Test · 测试(自我测试,修改代码,提交修改) 1h 2h
Reporting 报告 1h 1.5h
· Test Report · 测试报告 10mins 1h
· Size Measurement · 计算工做量
· Postmortem & Process Improvement Plan · 过后总结, 并提出过程改进计划 1h 1.5h
合计

因为一些事情,完成做业的时间跨度蛮大的,因此没有认真的计时,我只是写了个大概的时间,没有办法具体合计出来,请见谅。

相关文章
相关标签/搜索