From 0c76fab9034da8469a556e459357c7d8ac740d75 Mon Sep 17 00:00:00 2001 From: fangyaoyao <1722634891@qq.com> Date: Wed, 30 Jul 2025 10:11:54 +0800 Subject: [PATCH] subject1_4 --- .../__pycache__/find_subgraph.cpython-310.pyc | Bin 0 -> 1663 bytes .../JointCloudParallel/find_subgraph.py | 66 ++++++ .../inference_prediction.py | 189 ++++++++++++++++++ subject1-4/JointCloudParallel/main.py | 16 ++ .../JointCloudParallel/model_weights.pth | Bin 0 -> 4484 bytes 5 files changed, 271 insertions(+) create mode 100644 subject1-4/JointCloudParallel/__pycache__/find_subgraph.cpython-310.pyc create mode 100644 subject1-4/JointCloudParallel/find_subgraph.py create mode 100644 subject1-4/JointCloudParallel/inference_prediction.py create mode 100644 subject1-4/JointCloudParallel/main.py create mode 100644 subject1-4/JointCloudParallel/model_weights.pth diff --git a/subject1-4/JointCloudParallel/__pycache__/find_subgraph.cpython-310.pyc b/subject1-4/JointCloudParallel/__pycache__/find_subgraph.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ffd7833d4120a3b679cddb047cfa91f4a371688 GIT binary patch literal 1663 zcmb7E&1)n@6tAlOn4X@`B(Q|ANi1sNd-bdLUcbE63JH8qHn*>S z2lNLDZ+-y?pTkhkVB&<+l=LaAEM*g??@+=W?mj1dmwViY)e}CijhQ?WbXi-GejtKn zeMETh8(mRKgeQUp?S~>fC0{@2H$;=yMN2f6?G;(jUkDFH=e6{!y8xTnhn$|n&F7@o zSOW`k)}zMbVm228it?)uu><1-hT4WngVET{8yXSYhIfF>z>RYz@$ed_mjt}gOuB&W z^!KCF!;6E@4nF-NPqN}9&FB2fSjK58(u-k|@kq@tM>3vX?M=TmokT^`{94E;A4bJ> z?tvG@VA`g#2FqInH$hQ{fh5&qxV!*jONuWqX~8sI(C-kfpmKrSlybQcgL0 z9u%H-7W5R(LgZ$pt6lCuocA=!LFs9>^tCs%QJ%d&dua6+rC-#*UrpDRf%dOx;lPb` z?XTdjA;XO5n*0%V!xgz;Wl+|E2V|%Wb*NqN|4q>-ny3L?!`{(AtJ!0_Pvj5qhPvhS zUJ2)xEnwZ!E#T6$-s@J=*6n56-V9o+Z!bH#RoxHFTDo1anGJPKoz4zs4@aczXa;X< zmR+#y>h6k`8@dChH!Opnbq7-Ep1l=f3_WIY3q!mM(+ENgE}&#J-6Ai@m`YaRpV$m* zfv(ZUX1>P^+dD9H{1PhStEwV=*fil$ny6xsPo~FRkZpo@$?b_Phd0w74e~4#gF?Kn z5*6jsBAFz&g6|!r`5;c!F@QUN5{sd?VO-Q0FUz@5#z{qH93=`9UM58Z(x|vHo{Y1R zFiy<5M9#*Kr&Ez}Q_n;)y1LAzGPP+wO~nvA6>|W_SGfc>#vSBPt^Rz<<3gAXo(zXV zifkaFSE}Hys(YJ;K9wEoUkWu(!Pg|diN=O1<03y3sv?#}WU&W-;ar&3U@pO5rBw0( znm6xs3LbBo6%%WvOmIgT$zNB>e#^r9x76<_seXueMfOSZ9q?V{rh&*NX#am^0{=qw z1g0hps80iD2iAbKDf>5YeYQhghC2akvXC;^M=6BSg}F=JKiM<(kGq4qCY+TYfh!Y4 z(Iif?DC*UE%;r^M_XLc~+9sOGPXJd*XKSp~HMR^mvyT`b1NZw^r=CS#a@#WD6*+ld1V Tv=g|&J_Z?(^8t1La_j#AfXb(7 literal 0 HcmV?d00001 diff --git a/subject1-4/JointCloudParallel/find_subgraph.py b/subject1-4/JointCloudParallel/find_subgraph.py new file mode 100644 index 0000000..4c243ea --- /dev/null +++ b/subject1-4/JointCloudParallel/find_subgraph.py @@ -0,0 +1,66 @@ +import networkx as nx +from collections import deque + + +def is_power_of_two(n): + return n > 0 and (n & (n - 1)) == 0 + + +def find_power_of_two_connected_subgraphs_optimized(G): + nodes = list(G.nodes()) + V = len(nodes) + result = set() # 使用集合存储排序后的节点元组去重 + + # 生成所有可能的2的幂次方大小(1, 2, 4, ..., 最大不超过V) + max_k = V.bit_length() + for s in [2 ** k for k in range(max_k) if 2 ** k <= V]: + if s == 1: + # 处理大小为1的子图(每个节点自身) + for node in nodes: + result.add((node,)) + else: + # 对每个节点作为起点,进行BFS扩展到大小为s的连通子图 + for start_node in nodes: + # 使用队列存储 (当前节点集合, 当前节点的邻居集合) + queue = deque() + queue.append(({start_node}, set(G.neighbors(start_node)))) + + while queue: + current_nodes, neighbors = queue.popleft() + current_size = len(current_nodes) + + if current_size == s: + # 记录排序后的节点元组(去重) + sorted_nodes = tuple(sorted(current_nodes)) + result.add(sorted_nodes) + continue + + # 扩展到下一层:仅当当前大小 + 1 <= s时,尝试添加邻居 + if current_size < s: + for neighbor in list(neighbors): # 避免修改迭代中的集合 + new_nodes = current_nodes.copy() + new_nodes.add(neighbor)#添加邻居后,邻居集合新增邻居的邻居 + new_neighbors = neighbors.copy() + new_neighbors.update(G.neighbors(neighbor)) + new_neighbors.difference_update(new_nodes) # 邻居的邻居需排除已访问节点 + queue.append((new_nodes, new_neighbors)) + + # 将集合转换为networkx子图 + subgraphs = [] + for node_tuple in result: + subgraph = G.subgraph(node_tuple) + subgraphs.append(subgraph) + + return subgraphs + +if __name__ == '__main__': + # 示例图 + G = nx.Graph() + G.add_edges_from([(1, 2), (2, 3), (3, 1), (4, 5), (5, 6), (6, 4), (2, 4)]) # 新增边2-4使图连通 + + # 查找所有大小为2的n次方的连通子图 + optimized_subgraphs = find_power_of_two_connected_subgraphs_optimized(G) + + # 输出结果 + for subgraph in optimized_subgraphs: + print(f"Nodes: {list(subgraph.nodes())}, Size: {len(subgraph.nodes())}") \ No newline at end of file diff --git a/subject1-4/JointCloudParallel/inference_prediction.py b/subject1-4/JointCloudParallel/inference_prediction.py new file mode 100644 index 0000000..9e0a983 --- /dev/null +++ b/subject1-4/JointCloudParallel/inference_prediction.py @@ -0,0 +1,189 @@ +import torch +import torch.nn as nn +import networkx as nx +import numpy as np +from transformers import HieraModel +import math +from tensorboardX import SummaryWriter # 导入 tensorboardX +from sklearn.preprocessing import StandardScaler + +from find_subgraph import find_power_of_two_connected_subgraphs_optimized + + +class InferenceTimePredictor(nn.Module): + def __init__(self, input_size, hidden_sizes, output_size): + super(InferenceTimePredictor, self).__init__() + layers = [] + in_size = input_size + for hidden_size in hidden_sizes: + layers.append(nn.Linear(in_size, hidden_size)) + layers.append(nn.ReLU()) + in_size = hidden_size + layers.append(nn.Linear(in_size, output_size)) + self.model = nn.Sequential(*layers) + + def forward(self, x): + return self.model(x) + + +def prepare_input(G, A, h, w): + node_compute_powers = [] + min_communication_bandwidths = [] + rental_costs = [] + for node in A: + node_compute_powers.append(G.nodes[node].get('compute_power', 0)) + rental_costs.append(G.nodes[node].get('rental_cost', 0)) + node_bandwidths = [] + for other_node in A: + if node != other_node: + bandwidth = G.get_edge_data(node, other_node, default={'bandwidth': 0})['bandwidth'] + node_bandwidths.append(bandwidth) + if node_bandwidths: + min_communication_bandwidths.append(min(node_bandwidths)) + else: + min_communication_bandwidths.append(0) + + min_compute_power = min(node_compute_powers) + min_communication_bandwidth = min(min_communication_bandwidths) + # 增加集合A的大小作为特征 + set_size = len(A) + + input_features = [min_compute_power, min_communication_bandwidth, h, w, set_size] + input_tensor = torch.tensor(input_features, dtype=torch.float32) + return input_tensor, sum(rental_costs) + + +def train_model(model, train_loader, criterion, optimizer, epochs, save_path): + model.train() + writer = SummaryWriter() # 创建 SummaryWriter 对象 + for epoch in range(epochs): + running_loss = 0.0 + for inputs, labels in train_loader: + optimizer.zero_grad() + outputs = model(inputs) + # 确保输出和标签维度一致 + loss = criterion(outputs, labels) + loss.backward() + optimizer.step() + running_loss += loss.item() + epoch_loss = running_loss / len(train_loader) + writer.add_scalar('Training Loss', epoch_loss, epoch) # 记录损失 + print(f'Epoch {epoch + 1}, Loss: {epoch_loss}') + + # 保存训练好的权重 + torch.save(model.state_dict(), save_path) + writer.close() # 关闭 SummaryWriter + + +def infer(model, G, A, h, w, scaler): + model.eval() + input_tensor, rental_cost_sum = prepare_input(G, A, h, w) + # 对输入进行归一化处理 + input_tensor = torch.tensor(scaler.transform([input_tensor.numpy()]), dtype=torch.float32) + with torch.no_grad(): + outputs = model(input_tensor) + predicted_time = outputs[0, 0].item() + predicted_cost = predicted_time * rental_cost_sum + return predicted_time, predicted_cost + + +def test(G, model_path, h, w, scaler): + # 加载模型 + input_size = 5 # 因为增加了一个特征,输入大小变为5 + hidden_sizes = [20, 15] + output_size = 2 + model = InferenceTimePredictor(input_size, hidden_sizes, output_size) + model.load_state_dict(torch.load(model_path)) + + # 找出所有可能的集合A + subgraphs = find_power_of_two_connected_subgraphs_optimized(G) + min_time = float('inf') + min_cost = float('inf') + min_time_set = None + min_cost_set = None + + for subgraph in subgraphs: + A = set(subgraph.nodes()) + predicted_time, predicted_cost = infer(model, G, A, h, w, scaler) + if predicted_time < min_time: + min_time = predicted_time + min_time_set = A + if predicted_cost < min_cost: + min_cost = predicted_cost + min_cost_set = A + + return min_time_set, min_cost_set, min_time, min_cost + + +if __name__ == '__main__': + # 简单示例 + input_size = 5 # 因为增加了一个特征,输入大小变为5 + hidden_sizes = [20, 15] + output_size = 2 + + # 创建模型实例 + model = InferenceTimePredictor(input_size, hidden_sizes, output_size) + + # 示例图的创建 + G = nx.Graph() + G.add_node(1, compute_power=100, rental_cost=8) + G.add_node(2, compute_power=200, rental_cost=20) + G.add_node(3, compute_power=150, rental_cost=15) + G.add_node(4, compute_power=450, rental_cost=100) + G.add_node(5, compute_power=150, rental_cost=15) + G.add_node(6, compute_power=150, rental_cost=15) + G.add_edge(1, 2, bandwidth=100) + G.add_edge(2, 3, bandwidth=200) + G.add_edge(2, 4, bandwidth=200) + G.add_edge(1, 3, bandwidth=150) + G.add_edge(4, 5, bandwidth=100) + G.add_edge(5, 6, bandwidth=200) + G.add_edge(4, 6, bandwidth=150) + + # 模拟训练数据 + # 这里只是简单示例,实际需要大量真实数据 + + train_inputs = [] + train_labels = [] + + subs = [{5}, {5}, {5}, {5, 6}, {5, 6}, {5, 6}, {2, 4, 5, 6}, {2, 4, 5, 6}, {2, 4, 5, 6}, {1}, {2}, {4}] + H = [256, 512, 1024, 256, 512, 1024, 256, 512, 1024, 1024, 1024, 1024] + W = [256, 512, 1024, 256, 512, 1024, 256, 512, 1024, 1024, 1024, 1024] + predicted_times = [5, 9, 16, 2.94, 5.29, 9.41, 1.66, 3, 5.33, 24, 12, 5.33] + for i in range(len(subs)): + A = subs[i] + h = H[i] + w = W[i] + input_tensor, rental_cost_sum = prepare_input(G, A, h, w) + train_inputs.append(input_tensor) + # 模拟标签,实际需要真实推理时间和成本 + predicted_time = predicted_times[i] + predicted_cost = predicted_time * rental_cost_sum + train_labels.append(torch.tensor([predicted_time, predicted_cost], dtype=torch.float32)) + + train_inputs = torch.stack(train_inputs) + # 对输入数据进行归一化处理 + scaler = StandardScaler() + + train_inputs_np = train_inputs.numpy() + train_inputs_np = scaler.fit_transform(train_inputs_np) + train_inputs = torch.tensor(train_inputs_np, dtype=torch.float32) + + train_labels = torch.stack(train_labels) + train_dataset = torch.utils.data.TensorDataset(train_inputs, train_labels) + train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=2, shuffle=True) + + # 训练模型 + criterion = nn.MSELoss() + optimizer = torch.optim.Adam(model.parameters(), lr=0.01) + epochs = 500 + save_path = 'model_weights.pth' + train_model(model, train_loader, criterion, optimizer, epochs, save_path) + + # 测试 + # 示例输入 + h = 512 + w = 512 + min_time_set, min_cost_set, min_time, min_cost = test(G, save_path, h, w, scaler) + print(f"推理时间最短的集合: {min_time_set, min_time}") + print(f"成本最低的集合: {min_cost_set, min_cost}") \ No newline at end of file diff --git a/subject1-4/JointCloudParallel/main.py b/subject1-4/JointCloudParallel/main.py new file mode 100644 index 0000000..9438229 --- /dev/null +++ b/subject1-4/JointCloudParallel/main.py @@ -0,0 +1,16 @@ +# 这是一个示例 Python 脚本。 + +# 按 Shift+F10 执行或将其替换为您的代码。 +# 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。 + + +def print_hi(name): + # 在下面的代码行中使用断点来调试脚本。 + print(f'Hi, {name}') # 按 Ctrl+F8 切换断点。 + + +# 按装订区域中的绿色按钮以运行脚本。 +if __name__ == '__main__': + print_hi('PyCharm') + +# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助 diff --git a/subject1-4/JointCloudParallel/model_weights.pth b/subject1-4/JointCloudParallel/model_weights.pth new file mode 100644 index 0000000000000000000000000000000000000000..693ae0742aba1e994f528f80a04f35509a16514b GIT binary patch literal 4484 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 L@-N}~u514X+ODV{ literal 0 HcmV?d00001 -- Gitee