201871010129-郑文潇 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
项目 | 内容 |
---|---|
课程班级博客 | https://edu.cnblogs.com/campus/xbsf/2018CST |
这个作业要求链接 | https://www.cnblogs.com/nwnu-daizh/p/14604444.html |
我的课程学习目标 | 1.双人合作完成项目 2.通过github作对同伴个人项目仓库的源码 3.学习遗传算法 |
这个作业在哪些方面帮助我实现学习目标 | 通过这个作业,我知道了合作的重要性,对自己代码和同伴代码的查看与操作 |
结对方学号-姓名 | 谢金鑫-201871010127 |
结对方本次博客作业链接 | https://www.cnblogs.com/xiejinxin/p/14656025.html |
项目GitHub仓库地址 | https://github.com/zheng7968/- |
任务一
代码风格规范
包括:缩进、 行宽、括号(用括号清楚地表示逻辑优先级)、 断行与空白的{}行、分行、命名精简,会意、下划线、大小写 、注释等。
代码风格的原则是:简明,易读,无二义性。
代码设计规范
代码设计规范不光是程序书写的格式问题,而且牵涉到程序设计、模块之间的关系、设计模式等方方面面,要遵守下面的规定:
1.函数 现代程序设计语言中的绝大部分功能,都在程序的函数中实现。
2.goto 函数最好有单一的出口,为了达到这一目的,可以使用goto。只要有助于程序逻辑的清晰体现,什么方法都可以使用。
3.错误处理 当程序的主要功能实现后,给代码加一些错误处理。
4.参数处理 在Debug版本中,所有的参数都要验证其正确性。在正式版本中,对从外部(用户或别的模块)传递过来的参数,要验证其正确性。
5.断言 当你觉得某事肯定如何时,就可以用断言。
代码复审
- 找出代码的错误
- 发现逻辑错误
- 发现算法错误
- 发现潜在的错误和回归性错误
- 发现可能需要改进的地方
- 开发人员,传授经验,在交流中不断提升能力。
结对编程
结对编程:结对编程是软件开发过程中所使用的一种技术,两名程序开发人员共享同一台工作站。其中一个扮演驾驶者(Driver)的角色,进行代码编写,另一个扮演观察员(Observer)或导航员(Navigator)的角色,对代码进行评测。他们可以轮流编写代码和测试案例,还可以坐在一起交流思想,解决问题,而不会想偷懒去刷手机。
任务二
1.已对我的结对放谢金鑫实验二进行了中肯的评价
2.克隆结对方项目源码到本地机器,阅读并测试运行代码,参照《现代软件工程—构建之法》4.4.3节核查表复审同伴项目代码并记录。
核查项目 | 情况分析 |
---|---|
概要部分 | 代码符合设计需求和规格,功能未能完全实现,可读性和安全性有待提高。建议统一代码的格式规范,优化功能性和安全性。 |
设计规范部分 | 能遵从设计模式,存在无用代码。建议:尽可能实现系统功能,删除无用代码。 |
代码规范部分 | 修改部分符合代码规范和风格。 |
具体代码部分 | 代码的错误均已处理,但数据库的安全性有待提高。建议:改善程序与数据库的连接方式,提高安全性能。 |
效能 | 代码能正常编译,无超时情况 |
可读性 | 代码可读性较强,但是注释不清晰。建议:增加代码的功能注释,统一格式。 |
可测试性 | 建议:代码可增添新的单元测试。 |
任务三
1.需求分析
背包问题是一个经典的组合优化问题,有着广泛而重要的应用背景。{0-1}背包问题是最基本的KP问题形式,它的一般描述为:从若干具有价值系数与重量系数的物品(或项)中,选择若干个装入一个具有载重限制的背包,如何选择才能使装入物品的重量系数之和在不超过背包载重前提下价值系数之和达到最大?
在处理到第i个物品时,可以假设一共只有i个物品,如果前面i-1个物品的总的最大价值已经定下来了,那么第i个物品选不选将决定这1~i个物品能带来的总的最大价值。刚刚是自顶向下,接下来反过来自底向上,第1个物品选不选可以轻松地用初始化解决,接下来处理第i个物品时,假设只有2个物品就好,那他处理完后前2个物品能带来的最大总价值就确定了,这样一直推下去,就可以推出前n个物品处理完后能带来的最大总价值。
对于每个背包,都只有0和1的情况,也就是拿或者不拿两种情况
如果拿:那么空间就会减一点,比如说现在在考虑第i个物品拿不拿,如果说当前剩余空间为j,那么拿了之后空间就变为j-c[i],但是总价值却会增加一点,也就是增加w[i]
如果不拿:那么空间不会变,还是j,但是总价值也不会变化。
2.核心代码:
(1)初始界面
</head>
<body>
<font size="5">
<a href="sandain.html" title="读者你好,单击这里可以发电子邮件。">散点图</a><br />
<a href="dongtai.html" title="读者你好,欢迎进入FTP服务器。">动态规划</a><br />
<a href="huisu.html" title="读者你好,欢迎进入Telnet服务器。">回溯法</a><br />
<a href="yichuan.html" title="读者你好,欢迎进入Telnet服务器。">遗传算法</a>
</font>
</body>
</html>
(2)动态规划
def dp(num, maxWeight):
l = []
profitArr = []
profitArr = profit[num]
weightArr = []
weightArr = weight[num]
for i in range(maxWeight + 1):
l.append(0)
for i in range(len(profit[num])):
for j in range(maxWeight, -1, -1):
for k in range(3):
if j >= weightArr[i][k]:
l[j] = max(l[j], l[j - weightArr[i][k]] + profitArr[i][k])
print(l[maxWeight])
(3)回溯法
def huisu(num, maxWeight, x, y, totalP, totalW): # 访问一个节点 x,y 计算当前价值
if y != 3:
totalP = totalP + profit[num][x][y]
totalW = totalW + weight[num][x][y]
if x == len(profit[num]) - 1:
# 总价值和总重量
if totalW > maxWeight:
# print(totalP)
pathList.append(totalP)
return 0
else:
endMax.append(totalP)
pathList.append(totalP)
return 0
else:
for i in range(4):
huisu(num, maxWeight, x + 1, i, totalP, totalW)
return 0
(4)遗传算法
# coding=utf-8
import random
#背包问题
# 物品 重量 价格
X = {
1: [10, 15],
2: [15, 25],
3: [20, 35],
4: [25, 45],
5: [30, 55],
6: [35, 70]}
#终止界限
FINISHED_LIMIT = 5
#重量界限
WEIGHT_LIMIT = 80
#染色体长度
CHROMOSOME_SIZE = 6
#遴选次数
SELECT_NUMBER = 4
max_last = 0
diff_last = 10000
#判断退出
def is_finished(fitnesses):
global max_last
global diff_last
max_current = 0
for v in fitnesses:
if v[1] > max_current:
max_current = v[1]
print 'max_current:',max_current # 得到当前最大的价值
diff = max_current - max_last # 价值差,也就是适应度的改变的大小
# 这里判断连续两代的改变量如果都小于5,则停止迭代
if diff < FINISHED_LIMIT and diff_last < FINISHED_LIMIT:
return True
else:
diff_last = diff
max_last = max_current
return False
#初始染色体样态
def init():
chromosome_state1 = '100100'
chromosome_state2 = '101010'
chromosome_state3 = '010101'
chromosome_state4 = '101011'
chromosome_states = [chromosome_state1,
chromosome_state2,
chromosome_state3,
chromosome_state4]
return chromosome_states
#计算适应度
def fitness(chromosome_states):
fitnesses = []
for chromosome_state in chromosome_states: # 遍历所有的染色体
value_sum = 0 # 物品重量
weight_sum = 0 # 物品价值
# 将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标
for i, v in enumerate(chromosome_state):
# 对染色体中的1,即存在的物品体重和价格求和
if int(v) == 1:
weight_sum += X[i + 1][0]
value_sum += X[i + 1][1]
fitnesses.append([value_sum, weight_sum])
return fitnesses
#筛选
def filter(chromosome_states, fitnesses):
#重量大于80的被淘汰
index = len(fitnesses) - 1
while index >= 0:
index -= 1
if fitnesses[index][1] > WEIGHT_LIMIT:
chromosome_states.pop(index) # 弹出不符合条件的染色体
fitnesses.pop(index) # 弹出不符合条件的适应度
#print chromosome_states,'\n',fitnesses
#遴选
selected_index = [0] * len(chromosome_states) # 如果[0]*3得到的是[0,0,0]
for i in range(SELECT_NUMBER):
# 随机选择染色体,然后得到相应的索引
j = chromosome_states.index(random.choice(chromosome_states))
selected_index[j] += 1
return selected_index
# 交叉产生下一代
def crossover(chromosome_states, selected_index):
chromosome_states_new = []
index = len(chromosome_states) - 1
#print 'index:',index
while index >= 0: # 遍历完所有的染色体组的染色体(其中下标-1代表最后一个染色体的索引)
print 'index:',index
index -= 1
chromosome_state = chromosome_states.pop(index)
print 'chromosome_states_3:',chromosome_states # 弹出后的染色体组
print 'chromosome_state:',chromosome_state # 弹出的染色体
for i in range(selected_index[index]):
chromosome_state_x = random.choice(chromosome_states) # 随机选择一个染色体
print 'chromosome_state_x:',chromosome_state_x
pos = random.choice(range(1, CHROMOSOME_SIZE - 1)) # 随机[1, 2, 3, 4]其中的一个数
print 'pos:',pos
chromosome_states_new.append(chromosome_state[:pos] + chromosome_state_x[pos:])
print 'chromosome_states_new:',chromosome_states_new
chromosome_states.insert(index, chromosome_state) # 恢复原染色体组
print 'chromosome_states_4:', chromosome_states
return chromosome_states_new # 返回得到的新的染色体组
if __name__ == '__main__':
# 初始群体
chromosome_states = init() # 是全局的
print 'chromosome_states:',chromosome_states
n = 100 # 迭代次数
while n > 0:
n -= 1
#适应度计算
fitnesses = fitness(chromosome_states)
#print 'fitnesses:',fitnesses
if is_finished(fitnesses):
break # 如果符合条件,立刻停止循环
print '1:', fitnesses
#遴选
selected_index = filter(chromosome_states, fitnesses)
print '2:', selected_index
print 'chromosome_states_2:',chromosome_states
#产生下一代
chromosome_states = crossover(chromosome_states, selected_index)
print '3:', chromosome_states
print str(n)+'..................................' # 迭代次数
fitnesses = fitness(chromosome_states)
print 'fitnesses:',fitnesses
print chromosome_states
3.运行结果:
(1)初始界面:
(2)散点图
(3)动态规划
(4)回溯
(5)遗传
4.结对编程
PSP2.1 | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 10 | 7 |
· Estimate | · 估计这个任务需要多少时间,并规划大致工作步骤 | 8 | 5 |
Development | 开发 | 820 | 970 |
·· Analysis | 需求分析 (包括学习新技术) | 20 | 20 |
· Design Spec | · 生成设计文档 | 30 | 30 |
· Design Review | · 设计复审 (和同事审核设计文档) | 20 | 20 |
· Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
· Design | 具体设计 | 150 | 150 |
· Coding | 具体编码 | 420 | 520 |
· Code Review | · 代码复审 | 120 | 150 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 50 | 60 |
·· Test Report | · 测试报告 | 20 | 30 |
· Size Measurement | 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结 ,并提出过程改进计划 | 20 | 20 |
小结感受:两人合作真的能够带来1+1>2的效果吗?通过这次结对合作,请谈谈你的感受和体会。
在本次结对编程的过程中,我了解了合作是十分重要的,通过相互的讨论和监督使得代码更规范,功能更完善,逻辑较为严谨,特别是在单元测试和代码复审时,能更快的发现代码的错误,结对编程的效率比较高,在代码规范方面,意识到随意编写的危害,读代码改代码都很费劲,在按编写规范写程序后,逐渐改善了这种情况,但在结对编程中也遇到了问题,比如刚开始分工上打算一人主导一人辅助,但发现主导的人思维有时会混乱,所以就交换充当主导者的角色。本次项目做出改进在编程的过程中经常会出现事与愿违的事情,这样使得讨论陷入僵局,这时我们相互讨论取长补短解决问题