#P3492. 第1题-基于决策树预判资源调配优先级
-
1000ms
Tried: 640
Accepted: 266
Difficulty: 2
所属公司 :
华为
时间 :2025年8月28日-留学生
-
算法标签>树
第1题-基于决策树预判资源调配优先级
解题思路
-
数据结构设计 用一个结构体(或类)存储单个节点的全部信息:
feature_index分裂特征下标threshold分裂阈值left左子节点行号right右子节点行号label分类结果(仅在叶子节点有效)
-
读取模型
- 读取 m 个节点并存入数组或列表,编号即其行号
-
推理过程
- 对每个样本,从根节点 (0) 开始
- 如果当前节点是叶节点(
feature_index == -1),输出该节点分类结果 - 否则,比较样本在
feature_index特征上的值与threshold,选择走向左或右子节点 - 重复直到到达叶节点
-
时间复杂度 对每个样本,最多遍历树的高度 h,因此时间复杂度为 O(n⋅h),节点总数为 m,一般 h≪m 空间复杂度为 O(m)。
C++
#include <iostream>
#include <vector>
using namespace std;
// 定义节点结构体
struct Node {
int feature_index; // 分裂特征下标
float threshold; // 分裂阈值
int left; // 左子节点行号
int right; // 右子节点行号
int label; // 分类结果
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int f, m, n;
cin >> f >> m >> n;
vector<Node> tree(m);
// 读取决策树节点信息
for (int i = 0; i < m; i++) {
cin >> tree[i].feature_index >> tree[i].threshold
>> tree[i].left >> tree[i].right >> tree[i].label;
}
// 对每个样本进行推理
for (int i = 0; i < n; i++) {
vector<float> features(f);
for (int j = 0; j < f; j++) {
cin >> features[j];
}
int current = 0; // 从根节点开始
while (true) {
if (tree[current].feature_index == -1) {
// 到达叶子节点,输出分类结果
cout << tree[current].label << "\n";
break;
}
// 根据阈值选择左右子节点
if (features[tree[current].feature_index] <= tree[current].threshold) {
current = tree[current].left;
} else {
current = tree[current].right;
}
}
}
return 0;
}
Python
# 定义节点类
class Node:
def __init__(self, feature_index, threshold, left, right, label):
self.feature_index = feature_index # 分裂特征下标
self.threshold = threshold # 分裂阈值
self.left = left # 左子节点行号
self.right = right # 右子节点行号
self.label = label # 分类结果
# 读取输入
f, m, n = map(int, input().split())
tree = []
for _ in range(m):
fi, thr, l, r, lbl = input().split()
# 转换数据类型,分裂阈值是 float
tree.append(Node(int(fi), float(thr), int(l), int(r), int(lbl)))
# 推理过程
for _ in range(n):
features = list(map(float, input().split()))
current = 0 # 从根节点开始
while True:
node = tree[current]
if node.feature_index == -1:
# 到叶子节点
print(node.label)
break
if features[node.feature_index] <= node.threshold:
current = node.left
else:
current = node.right
Java
import java.util.*;
public class Main {
// 定义节点类
static class Node {
int feature_index; // 分裂特征下标
double threshold; // 分裂阈值
int left; // 左子节点行号
int right; // 右子节点行号
int label; // 分类结果
Node(int fi, double thr, int l, int r, int lbl) {
feature_index = fi;
threshold = thr;
left = l;
right = r;
label = lbl;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int f = sc.nextInt();
int m = sc.nextInt();
int n = sc.nextInt();
Node[] tree = new Node[m];
// 读取决策树节点
for (int i = 0; i < m; i++) {
int fi = sc.nextInt();
double thr = sc.nextDouble();
int l = sc.nextInt();
int r = sc.nextInt();
int lbl = sc.nextInt();
tree[i] = new Node(fi, thr, l, r, lbl);
}
// 处理每个样本
for (int i = 0; i < n; i++) {
double[] features = new double[f];
for (int j = 0; j < f; j++) {
features[j] = sc.nextDouble();
}
int current = 0;
while (true) {
Node node = tree[current];
if (node.feature_index == -1) {
System.out.println(node.label);
break;
}
if (features[node.feature_index] <= node.threshold) {
current = node.left;
} else {
current = node.right;
}
}
}
sc.close();
}
}
题目内容
在无线通信系统中为了资源调配更加合理和及时,需要对未来一段时间网络的负载做出预判以确定资源调配的优先级。决策树是一种常用的模型,可以根据采集到的状态数据,结合时间段、天气等因素来推测合理的资源调配优先级。现在将一个训练好的分类决策树模型Tree 安装在系统中,请实现决策树的推算算法,根据输入特征返回资源调配优先级。
输入描述
输入包含多行数据:
- 首行是属性参数;
- 后续(m)行是决策树模型的结构数据;
- 再后续(n)行是待推理的样本。
1. 属性参数(首行)
包含 3个int类数据,分别表示:
- 特征数量 (f),
- 树模型的节点数 (m),
- 待推理样本的行数(n)。
2. 决策树模型 (T) ((T) 是 (m) 行5 列的矩阵)
- 一行数据表示决策树的一个节点,首行表示根节点(即(T)矩阵中的第0 行),共有(m)个节点。
- 5个列分别表示:
- 分裂特征的下标
- 分裂特征的阈值
- 当前节点左子节点的行号(即 (T)矩阵中第几行)
- 当前节点右子树的行号
- 分类结果(即资源调配优先级)
数据类型分别为:int,float,int,int,int;下标和行号均从0开始。
- 模型结构中有意义的数据均(≥0),无意义数据统一用(−1)表示。 例如:叶子节点无分裂特征,因此该字段填入(−1)。
- 决策规则:若样本特征的取值(≤) 分裂特征的阈值,则进入左子树,否则进入右子树。
3. 待推理样本((n) 行 (f) 列)
- 一行数据表示一个待推理的样本;
- 每行包含(f)个特征,数据类型为 float。
输出描述
返回分类结果。 注:一行一个分类结果,数据类型为 int。
样例1
输入
2 5 2
0 2.5 1 2 -1
-1 -1 -1 -1 1
1 5.0 3 4 -1
-1 -1 -1 -1 2
-1 -1 -1 -1 3
1.2 3.4
5.6 6.0
输出
1
3
说明
- 第 1 行:特征数量为2,模型节点数为5,待推理样本为 2 条。
- 第2 到 6 行:决策树模型,共 5 个节点。首行(第2行输入数据)为根节点。
- 第 7 到8 行:2 个待推理样本,每个样本包含2 个特征。
输出:两条样本的推理结果分别为 分类 1、分类 3。
样例2
输入
3 9 2
0 6.1 1 2 -1
2 7.0 3 4 -1
1 6.5 5 6 -1
-1 -1 -1 -1 1
1 10.3 7 8 -1
-1 -1 -1 -1 5
-1 -1 -1 -1 6
-1 -1 -1 -1 3
-1 -1 -1 -1 4
3.2 9.2 6.2
6.3 3.2 12.0
输出
1
5
说明
第 1 行:特征数量为3,模型节点数为 9,待推理样本为 2条。
第2 到10 行:决策树模型,共9 个节点。首行(第 2 行输入数据)为根节点。
第11 到12行:2 个待推理样本,每个样本包含 3 个特征。
输出:两条样本的推理结果分别为 分类 1、分类 5。