1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
| """ Author: TUUG Date: April 26, 2024 20:59 Description: 求解资源受限项目调度问题并画图. """ import numpy as np import pandas as pd from collections import defaultdict import matplotlib.pyplot as plt import random import math
plt.rcParams["axes.labelsize"]=14 plt.rcParams["xtick.labelsize"]=12 plt.rcParams["ytick.labelsize"]=12 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False
class Activity(object): ''' 活动类:包含 1.活动ID 2.活动持续时间 3.活动资源需求量 4.活动紧前活动 5.活动最早开始时间 6.活动最晚开始时间 7.活动是否被访问 ''' def __init__(self, id, duration, resourceRequest, successor): self.id = id self.time_long = duration self.duration = duration self.resourceRequest = np.array(resourceRequest)[0] self.predecessor = None self.successor = successor self.visited = False self.start = None self.end = None class Day: def __init__(self,id,total_resource): self.id = id self.total_resource = total_resource self.resource_used = 0 self.resource_left = total_resource self.act_list = [] def start_act(act,day,days): """启动活动""" if act.visited == False: act.visited = True act.start = day.id-1 act.end = act.start + act.time_long for i in range(act.time_long): execute_act(act,days[days.index(day)+i]) if act.time_long == 0: execute_act(act,day) def execute_act(act,day): """执行活动""" act.duration -= 1 day.resource_used += act.resourceRequest day.resource_left -= act.resourceRequest day.act_list.append(act.id) def can_start1(act,day,days): a = days.index(day) for j in range(act.time_long): if days[min(a+j,len(days)-1)].resource_left < act.resourceRequest: return False return True def can_start2(act,act_done): for preAct in act.predecessor: if preAct not in act_done: return False return True
def pre_done(act,act_done,activities): ans = [0 if activities[i] in act_done else 1 for i in act.predecessor] return sum(ans)
def read_data_from_RCP_file(file_name): ''' 读取标准化文件中的所有活动信息,包括 1.活动数 2.项目资源数 3.项目资源种类数 4.项目资源限量 5.所有活动的ID,持续时间,资源需求,紧前活动 :param fileName: :return: 标准化文件数据 ''' f = open(file_name) taskAndResourceType = f.readline().split(' ') num_activities = int(taskAndResourceType[0]) num_resource_type = int(taskAndResourceType[1]) total_resource = np.array([int(value) for value in f.readline().split(' ')[:-1]]) activities = {} preActDict = defaultdict(lambda: []) for i in range(num_activities): nextLine = [int(value) for value in f.readline().split(' ')[:-1]] task = Activity(i + 1, nextLine[0], nextLine[1:2], nextLine[3:]) activities[task.id] = task for act in nextLine[3:]: preActDict[act].append(i + 1) f.close() for actKey in activities.keys(): activities[actKey].predecessor = preActDict[activities[actKey].id].copy() return num_activities, num_resource_type, total_resource, activities
file_name = r'D:/python代码库/实验/mv9.rcp' num_activities, num_resource_type, total_resource, activities = read_data_from_RCP_file(file_name) total_resource = total_resource[0]
num_days = sum([i.duration for i in activities.values()])
days = [Day(i,total_resource) for i in range(1,num_days+1)] act_list = [i for i in activities.values()] act_done = [] act_candidate = [activities[1]]
for day in days: for act in act_candidate: if act.time_long == 0: act.start = day.id-1 act.end = day.id-1 act_done.append(act) act_candidate.remove(act) for i in act.successor: act_candidate.append(activities[i]) for act in act_candidate: if can_start1(act,day,days): start_act(act,day,days) for act in act_list: if act.end: if act.end <= day.id and act not in act_done: act_done.append(act) for act in act_candidate: for suc in act.successor: if pre_done(activities[suc],act_done,activities) == 0: act_candidate.append(activities[suc]) for act in act_candidate: if act in act_done: act_candidate.remove(act)
def plot_square(matrix): fig, ax = plt.subplots() cmap = plt.get_cmap('viridis') norm = plt.Normalize(vmin=0, vmax=matrix.max()) for i in range(matrix.shape[0]): for j in range(matrix.shape[1]): color = cmap(norm(matrix[i, j])) if matrix[i, j] == 0: color = 'white' square = plt.Rectangle((j, total_resource-1-i), 1, 1, fill=True, color=color, edgecolor='black') ax.add_patch(square) if matrix[i, j] != 0: plt.text(j + 0.5, total_resource-1-i + 0.5, str(matrix[i, j]), color='black',fontsize=12, ha='center', va='center') ax.set_xlim(0, matrix.shape[1]) ax.set_ylim(0, matrix.shape[0]) ax.set_aspect('equal', adjustable='box') ax.set_xlabel('日期') ax.set_ylabel('资源') plt.title('项目调度图') plt.show()
ans = [days[i].act_list for i in range(num_days)] ans.remove([]) b = {} for i in range(len(activities)): b[i+1] = activities[i+1].resourceRequest def copy(sub_ans,b): result = [item for item in sub_ans for _ in range(b.get(item, 1))] return result ans_new = [[]] * len(ans) for i in range(len(ans)): ans_new[i] = copy(ans[i],b)
start_time = [] for i in range(1,len(activities)+1): start_time.append(activities[i].start)
total_time = 0 for i in range(1,len(activities)+1): if activities[i].successor == []: total_time = activities[i].end+1
a = np.zeros((total_resource,len(ans_new)),dtype=int) for i in range(len(ans_new)): for j in range(len(ans_new[i])): a[total_resource-1-j,i] = int(ans_new[i][j])
plot_square(a)
|