0. 问题描述

见老师博客

1.架构简介

经过软件工程的课程,我将学到的很多知识应用到了这次作业中首先,我从架构上来讲解下我的这次作业。

由于各个语言优势不相同,例如在C++课上我们讲到了C++的尴尬地位(但其实是一个折衷)。所以在这次作业中我也用到了类似思想,例如对于需要效率并不高的UI我采用了Python的PYQT界面的自动生成与方便的类型封装快速帮我解决了程序编写问题。但是对于效率依赖较高的的算法部分,我认为使用C会更快速解决问题,算法实现效率更好。

所以我采用的是界面由python编写,然后使用gcc编译出的DLL文件进行调用。以此发挥各个语言的优势。而在软件工程中我认为更为重要的一点就是封装,经过我了解,我才用了dll+.h文件的代码交流方式,对于代码的实现细节使用方并不需要了解,更为重要的是,这也是对代码创作者版权的一种保护。

2界面简介

界面简洁明了,左边的网格可供输入,也可以通过load一个矩阵文件来进行,通过点击GO!表示确认右边的矩阵,点击Reset将程序恢复到初始状态。三个选项钩分别表示不定形,垂直相连,水平相连的三个参数。然后4个播放功能键意义也很明了,分别表示播放,从头来,上一步,下一步。

在逻辑层面上封闭了非法操作,如当执行到最后一个状态,>>和>都会被锁定,保护程序的正确性。

3.算法简介

3.1 original.h

#ifndef ORIGINAL_H_INCLUDED

#define ORIGINAL_H_INCLUDED

#define SOLVE_CHOSEN -10001

/*

该文件包含了一系列求对象最大子对象的函数

*/

int maxsumline(int *p,int size);

/*

求一个序列p中包含的最大子序列,并将被选择的位置置为SOLVE_CHOSEN

*/

int maxsumcycle(int *p,int size);

/*

求一个循环序列p中包含的最大子序列,并将被选择的位置置为SOLVE_CHOSEN

循环序列代表着该序列首尾相连。

*/

int maxsumblock(int a[],int n,int m,int cycle,int expand);

/*

求一个矩阵的最大子矩阵,并将被选择的位置置为SOLVE_CHOSEN

n,m分别是它的长宽,cycle为1时代表该矩阵的左右是相连的,expand为1时代表着该矩阵的上下是相连的,并将

*/

#endif

问题分析

在一维情况下我们已经分析得到了基于长度n的O(n)时间复杂度的算法。那么我们可以先考虑在二维情况下是否可以得到基于长度n宽度m的O(m)时间复杂度的算法。如我在作业1里分析。设s[x][y]为以坐标(0,0)为左上角,(x,y)为右下角的点所形成的的矩形的加和。以(a,b)(x,y)构成的矩形的值为,(s[x][y] - s[a-1][y])-(s[x][b-1] - s[a-1][b-1]),不具备一维时的单调性,只能通过在此枚举一行。时间复杂度为O(m*n*n),无法达到最好的O(m*n)。

也就是说对于普通的问题,我们只需要枚举2行的组合即先枚举i再枚举小于等于i的j,加和j-i的区间,1维处理就可以了。

而对于-v的垂直相连参数,是很容易转化为普通问题的,普通问题中只考虑j-i的区间,而这里再考虑下i-n与0-j的区间就可以了,时间复杂度也为O(m*n*n)。

而对于-h的水平相连参数,我们可以从转化出的一维问题中考虑。对于1维情况下如果收尾相连应该如何处理。一开始我考虑的是复制一遍贴在右边,但其实实现起来限制过于复杂。如果选择了超越经线0的矩形其实就是踢掉了中间的一块矩形,于是只需要找到最小的矩形,然后用正行的权减去它,与普通解想比较即可。

3.2 atype.h

#ifndef ATYPE_H_INCLUDED

#define ATYPE_H_INCLUDED

#define SOLVE_CHOSEN -10001

#include <stdio.h>

#define N 32

#define M 32

#include <math.h>

#include <stdlib.h>

#include <time.h>

void SAA(int v,float T,float r,float Tmin);

/*

退火算法,v温度取的次数,T表示温度,r表示冷却速率,Tmin表示最终温度

*/

int deal(int o,int p,int c[],int vertical,int horizontal);

/*

使用的是退火算法求出一个相对较优解,o,p代表着矩阵c的长宽,vertical为1表示矩阵垂直相连,horizontal为1表示矩阵水平相连。返回得到块的值。

并将选中的点置为SOLVE_CHOSEN

执行过以次deal后才可以使用之后的单步功能

*/

int get_situation(int idx);

/*

返回第i次的退火解

*/

#endif

对于-a参数,这个历史遗留问题。经过并查集缩点之后(将正权点加合在一起作为一个点,并认为它的负权为0),建立一个Graph,然后通过随机挪动其中的一个点,即选还是不选作为状态转移可否的依据。然后再通过SAA的当前温度给出一个概率,表示新状态没有原来好但依然接受的概率。

3.3返回中间结果

在最最开始老师刚说的时候,我确实是想边运行边输出,但当老师说了可以先预处理一遍然后再进行帧操作,我决定使用这个方法,即在execute的时候将中间结果保存到一个文件里,然后进行运算。

4代码优化与注释

4.1注释见Github

4.2代码优化

4.2.1命名优化

首先有一个极为严重的问题往往被我们忽视,那就是build-in function,这是c语言内嵌函数。我在代码编写中写出了一个warning提示我声明y1这个变量在c里是个build-in function,但我一开始忽略了该问题,结果导致文件无法输出,至此我也不知道这两者之间的联系。不过我认为可以说明一些问题,那就是对于自己不了解的一些warning恰恰应该给出足够的重视,而对自己了然的一些warning或许可以采取忽视的态度,而不能因为连这个warning都不知道是什么意思就忽略掉了。

命名上由于C是面向过程的,很多地方写的东西只是该层函数所需要的,但我对于全局变量的把握依然不高,但是算法上的东西真的有必要去追求完美的拓展性吗,我觉得这个问题有待商榷,更多的我觉得只需要帮列在.h文件里的那些函数命名规范好就够了,因为其他人根本就不需要看里面的东西呀。

4.2.2 MagicNumber

把所有的魔数都转化成了一个常数类型。

4.2.3功能分化

把原本放在一起的两个dll分别以atype.dll与original.dll的两个文件进行完整剥离。另外在两个.c文件里我写了main函数用来测试。

4.2.4代码覆盖率

非常有意义的一项测试,我只是尝试了几个较小的数据,对dll里的函数进行了测试。

work-10的更多相关文章

  1. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 5.安装Database软件 5. ...

  2. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...

  3. ArcGIS 10.0紧凑型切片读写方法

    首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...

  4. CI Weekly #10 | 2017 DevOps 趋势预测

    2016 年的最后几个工作日,我们对 flow.ci Android & iOS 项目做了一些优化与修复: iOS 镜像 cocoapods 版本更新: fir iOS上传插件时间问题修复: ...

  5. 10个最好用的HTML/CSS 工具、插件和资料库

    大家在使用HTML/CSS开发项目的过程中,有使用过哪些工具,插件和库?下面介绍的10种HTML/CSS工具,插件和资料库,是国外程序员经常用到的. Firebug Lite FirebugLite ...

  6. 【Win 10 应用开发】启动远程设备上的应用

    这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...

  7. 在Ubuntu 16.10安装mysql workbench报未安装软件包 libpng12-0错误

    1.安装mysql workbench,提示未安装软件包 libpng12-0 下载了MySQL Workbench 6.3.8   在安装的时候报错: -1ubu1604-amd64.deb 提示: ...

  8. Ubuntu 16.10 安装byzanz截取动态效果图工具

    1.了解byzanz截取动态效果图工具 byzanz能制作文件小,清晰的GIF动态效果图,不足就是,目前只能通过输入命令方式来录制. byzanz主要的参数选项有: -d, --duration=SE ...

  9. Ubuntu 16.10 安装KolourPaint 4画图工具

    KolourPaint 4画图工具简单实用,可以绘画.视频处理和图标编辑: • 绘画:绘制图表和“手绘” • 视频处理:编辑截图和照片;应用特效 • 图标编辑:绘画剪贴和标识透明化 1.在Ubuntu ...

  10. 【解决方案】Myeclipse 10 安装 GIT 插件 集成 步骤 图解

    工程开发中,往往要使用到集成GIT ,那么下面说说插件安装步骤 PS:以Myeclipse 10 为例,讲解集成安装步骤. ----------------------main------------ ...

随机推荐

  1. js判断浏览器类型 js判断ie6不执行

    js判断浏览器类型 $.browser  对象 $.browser.version 浏览器版本 var binfo = ''; if ($.browser.msie) { binfo = " ...

  2. NFC(3)Android上的NFC,开启NFC,3种NDEF数据

    Android对NFC技术的支持 Android2.3.1(API Level = 9)开始支持NFC技术,但Android2.x和Android3.x对NFC的支持非常有限.而从Android4.0 ...

  3. BCB遍历所有窗体的组件

    for(iFormIdx=0; iFormIdx<Screen->FormCount; iFormIdx++) { TForm *pForm = Screen->Forms[iFor ...

  4. MyBatis 实践 -Mapper与DAO

    MyBatis 实践 标签: Java与存储 MyBatis简介 MyBatis前身是iBatis,是一个基于Java的数据持久层/对象关系映射(ORM)框架. MyBatis是对JDBC的封装,使开 ...

  5. CodeForces Round #290 Fox And Dinner

    而是Div2的最后一题,当时打比赛的时候还不会最大流.自己能够把它写出来然后1A还是很开心的. 题意: 有n个不小于2的整数,现在要把他们分成若干个圈.在每个圈中,数字的个数不少于3个,而且相邻的两个 ...

  6. UVa 12230 (期望) Crossing Rivers

    题意: 从A到B两地相距D,之间有n段河,每段河有一条小船,船的位置以及方向随机分布,速度大小不变.每段河之间是陆地,而且在陆地上行走的速度为1.求从A到B的时间期望. 分析: 我们只要分析每段河的期 ...

  7. Websocket和PHP Socket编程

    本来是搜一些html5 websocket资料看的,结果被引去看了php的socket编程.下面是一些简单的例子,在命令行运行php脚本就行 [命令行运行PHP]PHP中有一个php.exe文件,可以 ...

  8. C扩展Python

    基本想法: 先看中文小介绍,再看英文详细文档. 1. 参考 首先参考THIS, IBM的工程师好像出了好多这样的文章啊,而且每次看到时间戳,我都想戳自己- -! 2. ERROR 可能遇到错误: fa ...

  9. 流媒体相关知识介绍 及其 RTP 应用

    一.流媒体简介 随着Internet的日益普及,在网络上传输的数据已经不再局限于文字和图形,而是逐渐向声音和视频等多媒体格式过渡.目前在网络上传输音频/视频(Audio/Video,简称A/V)等多媒 ...

  10. linux面试题3

    1. 下面的网络协议中,面向连接的的协议是: A . A 传输控制协议 B 用户数据报协议 C 网际协议 D 网际控制报文协议 2. 在/etc/fstab文件中指定的文件系统加载参数中, D 参数一 ...