You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
8.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import random
from turtledemo.paint import switchupdown
from pfsp_simulated_annealing.machine import Machine
from pfsp_simulated_annealing.workpiece import Workpiece
class Simulate:
def __init__(self, n, m, p):
self.Wnum = n #声明一个整数变量Wnum表示工件的数量。
self.Mnum = m #声明一个整数变量Mnum表示机器的数量。
self.cost = [[0] * m for _ in range(n)] #声明一个二维整数数组cost用于存储每个工件在每台机器上的加工时间。
for i in range(n):
for j in range(m):
self.cost[i][j] = p[i * m + j]
self.management = [[j for j in range(n)] for _ in range(m)] #声明一个二维整数数组management用于存储工件的调度顺序。
self.Time = [[0] * n for _ in range(m)] #声明一个二维整数数组Time用于存储每台机器上每个工件的开始加工时间也就是调度顺序。
self.switchx = 0 #声明两个整数变量switchx和switchy用于存储交换操作中的两个工件的索引。
self.switchy = 0
self.switchrow = 0
self.M = [Machine() for _ in range(m)] #声明一个Machine对象数组M用于存储每台机器的信息。
self.W = [Workpiece() for _ in range(n)] #声明一个Workpiece对象数组W用于存储每个工件的信息。
print(f"Simulate初始化")
self.print_data() #打印出来看看有没有错误
def random_reset(self): #其实就是初始化工件在每个机器上的调度顺序
"随机重置工件在每个机器上的调度顺序"
for i in range(self.Mnum): # 遍历每台机器
for j in range(self.Wnum): # 遍历工件
# 生成随机索引
x = random.randint(j, self.Wnum - 1)
# 交换
self.management[i][j], self.management[i][x] = self.management[i][x], self.management[i][j]
print("工件初始调度顺序 (management):")
for man in self.management:
print(man)
def roll_back(self):
"""交换管理矩阵中指定行的两个元素""" #根据保存的rowxy把交换过的位置给交换回去
# 保存当前行、列的值
temp = self.management[self.switchrow][self.switchx]
# 交换元素
self.management[self.switchrow][self.switchx] = self.management[self.switchrow][self.switchy]
self.management[self.switchrow][self.switchy] = temp
def random_exchange(self): #找到下一个调度方案,并且每次只改变一台机器上的两个工件之间的调度顺序
"""随机交换两个工件在同一台机器的调度位置""" #同时还得记录是哪俩个交换了位置
random.seed() # 用于初始化随机数生成器
self.switchrow = random.randint(0, self.Mnum - 1)
self.switchx = random.randint(0, self.Wnum - 1)
self.switchy = random.randint(0, self.Wnum - 1)
#print(f"随机改变了第{self.switchrow}台机器,第{self.switchx}和{self.switchy}个工件之间的调度顺序")
# 交换工件位置
self.management[self.switchrow][self.switchx], self.management[self.switchrow][self.switchy] = \
self.management[self.switchrow][self.switchy], self.management[self.switchrow][self.switchx]
#print("随机交换后的管理信息:")
#for row in self.management:
# print(row)
def f(self):
#print("模拟一个车间调度系统中的调度过程,直到所有工件完成在所有机器上的处理")
rtime = 0 #记录总花费时间
while True:
#判断是否有工件加工完毕并且可以转移到下一台机器上
for i in range(self.Mnum):
current_piece = self.M[i].process() #获得当前这个机器正在处理的工件索引
if current_piece != self.Wnum - 1: #如果当前工件的索引不等于最后一个也就是这次测试的工件的数量
x = self.management[i][current_piece + 1] #得到这台机器下一个要处理的工件的号码
if self.M[i].left_time == 0 and self.W[x].left_time == 0 and self.W[x].being_processed == i - 1:
#当前这台机器的剩余加工时间为0 并且 这台机器的下一个要加工的工件的剩余加工时间为0
# 并且这台机器的下一个要加工的工件的现在停留在前一台机器上
#也就是说,当前机器空闲了,当前机器的下一个要加工的工件它刚好在前一台机器,并且在前一台工具那也已经加工完了,那这台机器就可以开始加工这个工件了
self.M[i].next_wp(self.cost[x][i]) #当前机器开始加工下一个工件,设置时间为下一个工件在那台机器上要耗费的时间
self.W[x].next_machine(self.cost[x][i]) #这个工件转移到下一台机器加工 因为加工顺序必须是从0 1 2 3 4 这样一台台排下去的
self.Time[i][current_piece + 1] = rtime #记录这台机器第几个工件的开始加工时间因为current_price
#同时减少机器和工件的加工时间每次都减1
for i in range(self.Mnum):
self.M[i].next_time()
for i in range(self.Wnum):
self.W[i].next_time()
flag = False #判断是否全部加工完毕
for i in range(self.Wnum):
if self.W[i].left_time != 0 or self.W[i].being_processed != self.Mnum - 1:
flag = True
break
if not flag:
#print(f"此次调度方案耗时:{rtime}")
return rtime + 1
rtime += 1
def output_data(self):
# 构建 management_str 字符串
management_str = []
for i in range(self.Mnum):
row = []
for j in range(self.Wnum):
row.append(str(self.management[i][j]))
management_str.append('\t'.join(row))
management_str = '\n'.join(management_str)
# 写入 management.txt 文件
file_name = "output/management.txt"
try:
with open(file_name, 'w', encoding='utf-8') as fw:
fw.write(management_str)
fw.flush()
print(f"写入文件 {file_name} 成功")
except IOError as e:
print(f"写入文件 {file_name} 时出错: {e}")
# 构建 time_str 字符串
time_str = []
for i in range(self.Mnum):
row = []
for j in range(self.Wnum):
row.append(f"{self.Time[i][j]}\t{self.Time[i][j] + self.cost[self.management[i][j]][i]}")
time_str.append('\t'.join(row))
time_str = '\n'.join(time_str)
# 写入 time.txt 文件
file_name = "output/time.txt"
try:
with open(file_name, 'w', encoding='utf-8') as fw:
fw.write(time_str)
fw.flush()
print(f"写入文件 {file_name} 成功")
except IOError as e:
print(f"写入文件 {file_name} 时出错: {e}")
def reset_for_new_round(self): #重置所有的参数
for i in range(self.Wnum):
self.W[i].reset()
for i in range(self.Mnum):
self.M[i].reset()
def print_data(self):
print(f"工件数量: {self.Wnum}")
print(f"机器数量: {self.Mnum}")
print("加工时间 (cost):")
for row in self.cost:
print(row)
print("工件调度顺序 (management):")
for man in self.management:
print(man)
print("开始加工时间 (Time):")
for row in self.Time:
print(row)
print("机器状态 (M):")
for machine in self.M:
print(machine)
print("工件状态 (W):")
for workpiece in self.W:
print(workpiece)