• 个人项目——最后篇


    一、实现过程:

      首先这个项目我把求解和生成分开写了,生成函数我用回溯法+规则变换来生成终局。先用随机数加回溯生成一个终局,再通过这个终局交换行、列、数字生成1372个终局。这样共需要随机回溯生成1000个左右终局即可。实现过程用了5个函数,分别是dfs回溯生成函数,一个初始化函数,一个随机填数函数,一个变换函数,一个打印函数。dfs函数从1到81号格子填数,然后填的数由随机填数函数决定。一直填满最后判断是否合格,再回溯。再根据这个终局先交换两行,再交换两列最后交换两个数字的方式构造1372个终局。

     

             求解函数我用了跳舞链的数据结构,共用了7个函数,分别是删除列函数、恢复列函数、dfs,初始化函数、读入函数,输出函数,找对应关系函数,关系见流程图。

    对于单元测试,我是这样设计的:

            1.对于输出到文件的函数,重新打开文件比对结果

            2.对于不输出到文件的函数,比对返回值或参数变化是否符合预期

            3.对于调用其它函数的函数,因为它调用的函数已有专门的单元测试确保其正确,所以可以只检查不是有调用过所产生的变化是否符合预期。

    二、性能分析:

             对于求解1000000组空白在30个左右的数独用时30s左右,

     

    可知时间主要是在删除行和恢复行的过程。一开始性能瓶颈是输入输出速度太慢,经过使用字符读入和字符输出后优化了将近20s。

             对于生成1000000个终局,用时6s左右,

     

    时间主要是在变换的过程,原本的性能瓶颈在dfs过程以及输出过于慢,通过使用变换规则和字符输出优化。

    三、代码说明:

    生成程序:

    Dfs过程

     

    变换过程

     

    求解程序:

    读入函数:

     

    初始化函数:

    Dfs求解过程:

     

    四、时间表

     

  • 相关阅读:
    有关WCSF的几点整理
    应用Response.Write实现带有进度条的多文件上传
    使用Response.Write实现在页面的生命周期中前后台的交互
    多线程实现Thread.Start()与ThreadPool.QueueUserWorkItem两种方式对比
    LinQ to SQL 及 non-LinQ方式实现Group的Performance对比
    Object.assign()方法
    继承
    面对对象和原型链
    画布实现验证码
    日期的格式 字符串转日期
  • 原文地址:https://www.cnblogs.com/Lylist/p/8811270.html
Copyright © 2020-2023  润新知