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|AN
i1sNd-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