Readme
运行环境:
Win10+python3.7.3
IDE:Pycharm
分析设计:
有n份作业分配给n个人去完成,每人完成一份作业。
假定第i个人完成第j份作业需要花费cij时间,cij>0,1≦i,j≦n。试设计一个回溯算法,将n份作业分配给n个人完成,使得总花费时间最少。
这是一个寻找最优解的问题,通常的解决办法就是穷举出所有结果,找出最优解
数据结构:
输入数据来源于文件:input_assign04_01.dat. input_assign04_02.dat. input_assign04_03.dat. input_assign04_04.dat. input_assign04_05.dat. input_assign04_06.dat. input_assign04_07.dat.
文件内是n*n矩阵的元素,每行的元素代表完每个工人成该任务所需要的时间,每列代表某个工人完成每个工作需要的时间,读出的数据放在matrix中。
matrix[i][j]表示第j个工人完成第i个任务需要的时间。
Class Worker 中
使用user_distributed来标记在某一次求解中某工人是否被分配了任务
使用user_work来记录每次找到更适合的解的时候,工人工作分配情况
使用min_cost来记录最小的时间消耗和
使用n来记录用户或者作业的数量,题设中二者相等
初始化函数中完成从文件中读取数据,初始化相关变量的工作
back_track函数为回朔算法的主体部分deep 表示当前分配到第几个任务了,cost用来记录本次求解的花费情况
write_into_file函数将结果写入文件
代码
from time import sleep
class Worker:
# n = 0 # 矩阵大小n*n
# matrix = [] # 存放每人解决每个问题时间的矩阵
# user_distributed = [] # 用户是否分配了工作
# min_cost = 8000 # 默认一个最大的时间消费值
# user_work = [] # 接受用户分配的工作
# 初始化必要参数
def __init__(self, input_file, output_file,n=0,matrix=[],user_distributed=[],min_cost=8000,user_work=[]):
self.input_file = input_file
self.output_file = output_file
self.n = n
self.matrix = matrix
self. user_distributed = user_distributed
self.min_cost = min_cost
self. user_work = user_work
with open(self.input_file) as file:
for line in file:
data_source = line.rstrip().split(' ')
temp = []
for time in data_source:
temp.append(int(time))
self.matrix.append(temp)
self.n = len(self.matrix)
# 初始化 工人是否分配标记 工人最有分配结果
for i in range(self.n):
self.user_distributed.append(0)
self.user_work.append(0)
# 回朔法寻找最优解
def back_track(self, deep, cost):
if deep == self.n:
if cost < self.min_cost:
self.min_cost = cost
for k in range(self.n):
self.user_work[k] = self.user_distributed[k]
return
else:
for i in range(self.n):
if self.user_distributed[i] == 0: # 没有分配工作的人
self.user_distributed[i] = deep+1 # 标记当前公认已经被标记分配了工作
time = self.matrix[deep][i]
self.back_track(deep+1, cost+time)
self.user_distributed[i] = 0
# 将算法执行结果存入文件中
def write_into_file(self):
file = open(self.output_file, 'a')
file.write('最优解消耗总时间为:' + str(self.min_cost) + '\n')
for i in range(self.n):
file.write('第' + str(i+1) + '位工人完成第' + str(self.user_work[i]) + '份工作\n')
def main():
for i in range(7):
input_file = 'input_assign04_0{}.dat'.format(i+1)
output_file = 'output_0{}.dat'.format(i+1)
worker = Worker(input_file,output_file,n=0,matrix=[],user_distributed=[],min_cost=8000,user_work=[])
worker.back_track(0, 0)
print('第{}组输入'.format(i+1))
print('最少工作时间为:',worker.min_cost)
print('每个人完成的任务序号依次为:',worker.user_work)
worker.write_into_file()
sleep(300)
# 算法启动
if __name__ == '__main__':
main()