鱼C论坛

 找回密码
 立即注册
查看: 3091|回复: 3

[已解决]python回溯法 解 作业分配问题

[复制链接]
发表于 2017-4-2 21:33:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sun Apr  2 09:20:43 2017

  4. @author: xuxi
  5. """
  6. def assign(k,cost,n,mincost,c,job,task,bestSolution):

  7.     if (k > n and cost < mincost):
  8.         mincost = cost
  9.         for i in range(n):
  10.             bestSolution[i+1] = task[i+1]  
  11.     else:     
  12.         for i in range(n):
  13.             if (job[i+1] == 0 and (cost+int(c[k-1][i]))>0):
  14.                 job[i+1] = 1
  15.                 task[k] = i + 1
  16.                 assign(k+1,cost+int(c[k-1][i]),n,mincost,c,job,task,bestSolution)
  17.                 job[i+1] = 0
  18.                 task[k] = 0            
  19.     #return mincost,bestSolution
  20.    
  21. def output(mincost,n,bestSolution):
  22.     print('最小总费用%s'%mincost)
  23.     for i in range(n):
  24.         print('员工:%s执行任务%s'%(i+1,bestSolution[i+1]))

  25. def main():
  26.     f = open('input_assign04_01.dat')
  27.     c = []
  28.     for item in f.readlines():
  29.         c.append(item.rstrip('\n').split())
  30.     n = len(c)
  31.     mincost = 65535
  32.     job = []
  33.     task = []
  34.     bestSolution = []
  35.     for i in range(n+1):
  36.         job.append(0)
  37.         task.append(0)
  38.         bestSolution.append(0)
  39.     assign(1,0,n,mincost,c,job,task,bestSolution)
  40.     output(mincost,n,bestSolution)

  41.    
  42. if __name__ == '__main__':
  43.     main()
复制代码

问题为:有n份作业分配给n个人去完成,每人完成一份作业。假定第i个人完成第j份作业需要花费cij时间,cij>0,1≦i,j≦n。试设计一个回溯算法,将n份作业分配给n个人完成,使得总花费时间最短。
我是按照回溯法求解的,得出结果为: 搜狗截图20170402213153.png
结果明显不对,看了很久,希望有大神帮助看看
最佳答案
2017-4-2 22:00:52
n个人完成n项工作,每人完成1项,其实这是n的全排列问题。
如果用全排列解就很方便了,当然递归也可以,只是要设置边界条件,比较麻烦,而且效率比全排列低

例如,假定N=4的情况。
  1. from itertools import permutations as pt

  2. #Define
  3. cij = [[1,2,3,4],
  4.        [2,4,6,8],
  5.        [3,5,7,9],
  6.        [4,5,6,7]]

  7. def assign(n,cij=cij):
  8.     comb = pt(range(n),n)
  9.     min_comb = 9999
  10.     for c in comb:
  11.         temp = 0
  12.         for i in range(n):
  13.             temp += cij[i][c[i]]
  14.         if temp < min_comb:
  15.             min_comb = temp
  16.             min_c = c
  17.     return min_comb, min_c

  18. print assign(4)
复制代码

输出:
(17, (2, 0, 1, 3))
表示第0个人做第2项工作,第1个人做第0项工作,第2个人做第1项工作,第3个人做第3项工作,总共17个单位时间。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-4-2 21:34:50 | 显示全部楼层
输入的文本内容为:
1 2 3 4
3 2 1 4
3 1 1 4
1 1 1 1
主要是结果明显不对,输入的数据初始化没问题,原因肯定出在assign函数中
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-2 22:00:52 | 显示全部楼层    本楼为最佳答案   
n个人完成n项工作,每人完成1项,其实这是n的全排列问题。
如果用全排列解就很方便了,当然递归也可以,只是要设置边界条件,比较麻烦,而且效率比全排列低

例如,假定N=4的情况。
  1. from itertools import permutations as pt

  2. #Define
  3. cij = [[1,2,3,4],
  4.        [2,4,6,8],
  5.        [3,5,7,9],
  6.        [4,5,6,7]]

  7. def assign(n,cij=cij):
  8.     comb = pt(range(n),n)
  9.     min_comb = 9999
  10.     for c in comb:
  11.         temp = 0
  12.         for i in range(n):
  13.             temp += cij[i][c[i]]
  14.         if temp < min_comb:
  15.             min_comb = temp
  16.             min_c = c
  17.     return min_comb, min_c

  18. print assign(4)
复制代码

输出:
(17, (2, 0, 1, 3))
表示第0个人做第2项工作,第1个人做第0项工作,第2个人做第1项工作,第3个人做第3项工作,总共17个单位时间。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-3 09:33:38 | 显示全部楼层
jerryxjr1220 发表于 2017-4-2 22:00
n个人完成n项工作,每人完成1项,其实这是n的全排列问题。
如果用全排列解就很方便了,当然递归也可以,只 ...

感谢,原来 python还有这个模块。这个我也吸收吸收
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-19 18:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表