进程管理和资源分配算法
背景介绍
你正在为一款设备管理软件设计其核心的进程管理和资源分配模块。该系统负责管理多种类型的设备(无线、数通、接入),每种类型的设备都由一个专门的进程组进行管理。你的任务是实现这套系统的功能,确保设备能够被正确地创建、删除,并能按需统计。
核心概念
-
设备类型与进程组 (Device Types & Process Groups):
- 系统共管理 3 种设备类型,其
deviceType值分别为:1(无线),2(数通),3(接入)。 - 每种设备类型都由一个同号的进程组进行管理。
- 系统共管理 3 种设备类型,其
-
进程 (Process):
- 每个进程组内都有
procNum个进程。 - 进程的编号
procId从 0 开始,到procNum - 1。 - 每个进程的初始内存资源上限都是
maxMemSize。
- 每个进程组内都有
-
设备 (Device):
- 每个设备有一个全局唯一的
deviceId。 - 创建设备会消耗其所在进程的内存资源。
- 每个设备有一个全局唯一的
功能要求
你需要实现一个 DeviceMgtSystem 类,支持以下操作:
DeviceMgtSystem(int procNum, int maxMemSize)
-
功能: 系统初始化。
-
效果:
- 为 3 个设备类型分别创建进程组。
- 每个进程组内创建
procNum个进程。 - 每个进程的可用内存初始化为
maxMemSize。
createDevice(int deviceId, int deviceType, int memSize)
-
功能: 在指定的
deviceType对应的进程组内,为新设备deviceId分配资源。 -
负载均衡规则:
- 优先规则: 在所有能满足
memSize要求的进程中,优先选择空闲内存最多的进程。 - 平局规则: 若空闲内存相同,则选择进程编号 (
procId) 最小的。
- 优先规则: 在所有能满足
-
返回值:
- 成功: 返回设备被分配到的进程编号
procId。 - 失败: 如果该进程组内所有进程的可用内存都不足以满足
memSize,则创建失败,返回-1。
- 成功: 返回设备被分配到的进程编号
deleteDevice(int deviceId)
-
功能: 删除指定的设备,并释放其占用的内存。
-
返回值:
- 成功: 如果
deviceId存在,则删除并返回true。 - 失败: 如果
deviceId不存在,返回false。
- 成功: 如果
queryDevice(int deviceType)
-
功能: 查询指定
deviceType下的所有设备信息。 -
特殊情况:
productId为 0 时,表示查询所有产品(即所有设备)。(注:此处原文为productId,根据上下文应为deviceType)。 -
返回格式:
-
一个设备信息列表,每个设备信息格式为
[deviceId, memSize, procId]。 -
返回顺序 (多级排序):
- 主排序: 按设备消耗的内存
memSize降序排列。 - 次排序: 若
memSize相同,按设备所在的进程procId升序排列。 - 最终排序: 若
procId也相同,按deviceId升序排列。
- 主排序: 按设备消耗的内存
-
输入格式
procNum:1 <= procNum <= 5maxMemSize:100 <= maxMemSize <= 1000deviceType:1 <= deviceType <= 3memSize:1 <= memSize <= 100deviceId:1 <= deviceId <= 1000data(主存): 输入的十六进制字符串,2 <= data.length <= 30000且为偶数。linkRelations(连接关系):1 <= linkRelations <= 10000
(注:上述输入格式描述似乎混合了多个问题,这里根据函数原型和样例,仅保留与本题相关的约束。)
输出格式
- 根据每个函数的原型要求返回相应的值。最终的整体输出由评测框架完成。
样例 1 解读
输入:
// 操作序列
["DeviceMgtSystem", "createDevice", "createDevice", "createDevice", "queryDevice", "createDevice", "queryDevice", "deleteDevice"]
// 参数序列
[[[2, 200]], [8, 1, 50], [12, 1, 30], [3, 1, 30], [1], [15, 1, 30], [1], [10]]
输出:
[null, 0, 1, 1, [[8, 50, 0], [3, 30, 1], [12, 30, 1]], 0, [[8, 50, 0], [15, 30, 0], [3, 30, 1], [12, 30, 1]], false]
一步步解释:
| # | 调用 | 解释与系统状态变化 (仅展示进程组 1) | 返回值 |
|---|---|---|---|
| 1 | DeviceMgtSystem(2, 200) | 初始化。进程组1状态: P0: 200, P1: 200 | null |
| 2 | createDevice(8, 1, 50) | P0, P1 内存相同,选编号小的 P0。P0 内存变为 150。 | 0 |
| 3 | createDevice(12, 1, 30) | P1 (200) 内存 > P0 (150),选 P1。P1 内存变为 170。 | 1 |
| 4 | createDevice(3, 1, 30) | P1 (170) 内存 > P0 (150),选 P1。P1 内存变为 140。 | 1 |
| 5 | queryDevice(1) | 设备列表: {id:8, mem:50, proc:0}, {id:12, mem:30, proc:1}, {id:3, mem:30, proc:1}。 排序: mem降序->8在前; 3和12 mem相同, proc相同, 按id升序->3在前。 | [[8, 50, 0], [3, 30, 1], [12, 30, 1]] |
| 6 | createDevice(15, 1, 30) | P1 (140) 内存 < P0 (150),选 P0。P0 内存变为 120。 | 0 |
| 7 | queryDevice(1) | 设备列表: ...{id:15, mem:30, proc:0}。 排序: mem=30时, 15(p0) < 3(p1) < 12(p1)。 | [[8, 50, 0], [15, 30, 0], [3, 30, 1], [12, 30, 1]] |
| 8 | deleteDevice(10) | 设备 10 不存在。 | false |
import java.util.*;
import java.util.stream.Collectors;
/**
* 模拟一个设备管理系统.
* 该系统通过分层的进程组结构来管理不同类型的设备,
* 核心功能包括基于负载均衡规则的设备创建、设备删除以及按复杂规则排序的设备查询。
*/
public class DeviceMgtSystem {
// --- 内部数据结构定义 ---
/**
* 内部类,表示一个被管理的设备.
* 存储了设备自身的信息以及它所属的进程ID。
*/
private static class Device {
int id; // 设备ID
int memSize; // 消耗的内存大小
int procId; // 所属进程的ID
public Device(int id, int memSize, int procId) {
this.id = id;
this.memSize = memSize;
this.procId = procId;
}
}
/**
* 内部类,表示一个管理进程.
* 封装了进程的属性,如内存使用情况,以及其管理的所有设备。
*/
private static class Process {
int id; // 进程ID
int maxMemSize; // 最大内存上限
int usedMem; // 已使用的内存
// 使用Map可以快速通过设备ID找到设备对象
Map<Integer, Device> managedDevices;
public Process(int id, int maxMemSize) {
this.id = id;
this.maxMemSize = maxMemSize;
this.usedMem = 0;
this.managedDevices = new HashMap<>();
}
/** 获取当前进程的空闲内存. */
public int getFreeMem() {
return this.maxMemSize - this.usedMem;
}
/** 在该进程下添加一个设备. */
public void addDevice(Device device) {
this.managedDevices.put(device.id, device);
this.usedMem += device.memSize;
}
/** 从该进程下移除一个设备. */
public void removeDevice(Device device) {
this.managedDevices.remove(device.id);
this.usedMem -= device.memSize;
}
}
// --- DeviceMgtSystem 类的成员变量 ---
/**
* 二维数组,用于存储所有进程组.
* 第一维的索引对应 deviceType - 1 (0, 1, 2)
* 第二维是该进程组下的所有进程.
*/
private final Process[][] processGroups;
/**
* 全局设备位置映射表.
* 这是一个关键的优化,使得删除设备时可以O(1)时间复杂度定位到设备所在的进程。
* Key: deviceId, Value: 管理该设备的Process对象.
*/
private final Map<Integer, Process> deviceLocationMap;
/**
* 初始化设备管理系统.
* @param procNum 每个进程组的进程数量
* @param maxMemSize 每个进程的内存上限
*/
public DeviceMgtSystem(int procNum, int maxMemSize) {
// 共3种设备类型,所以有3个进程组
this.processGroups = new Process[3][procNum];
this.deviceLocationMap = new HashMap<>();
// 初始化所有进程
for (int i = 0; i < 3; i++) {
for (int j = 0; j < procNum; j++) {
processGroups[i][j] = new Process(j, maxMemSize);
}
}
}
/**
* 创建一个新设备.
* @return 成功则返回所在进程编号;否则返回-1.
*/
public int createDevice(int deviceId, int deviceType, int memSize) {
Process[] targetGroup = this.processGroups[deviceType - 1];
Process bestProcess = null;
// 遍历目标进程组,根据“负载均衡规则”寻找最佳进程
for (Process currentProcess : targetGroup) {
// 筛选条件:进程必须有足够的剩余内存
if (currentProcess.getFreeMem() >= memSize) {
if (bestProcess == null) {
// 如果还没找到过候选进程,当前进程就是最好的
bestProcess = currentProcess;
} else {
// 规则1:优先选择空闲内存较多的
if (currentProcess.getFreeMem() > bestProcess.getFreeMem()) {
bestProcess = currentProcess;
}
// 规则2:空闲内存相同,选择编号较小的
else if (currentProcess.getFreeMem() == bestProcess.getFreeMem() && currentProcess.id < bestProcess.id) {
bestProcess = currentProcess;
}
}
}
}
// 如果没有找到合适的进程,则创建失败
if (bestProcess == null) {
return -1;
}
// 创建成功,更新状态
Device newDevice = new Device(deviceId, memSize, bestProcess.id);
bestProcess.addDevice(newDevice);
deviceLocationMap.put(deviceId, bestProcess); // 更新全局位置映射
return bestProcess.id;
}
/**
* 删除一个设备.
* @return 如果设备存在并成功删除,返回true;否则返回false.
*/
public boolean deleteDevice(int deviceId) {
// 利用全局映射表快速定位设备所在的进程
Process process = deviceLocationMap.get(deviceId);
if (process == null) {
return false; // 设备不存在
}
// 从进程中获取并移除设备信息
Device deviceToDelete = process.managedDevices.get(deviceId);
process.removeDevice(deviceToDelete);
// 从全局映射表中移除
deviceLocationMap.remove(deviceId);
return true;
}
/**
* 查询指定设备类型下的所有设备信息.
* @return 按复杂规则排序后的设备信息列表.
*/
public List<List<Integer>> queryDevice(int deviceType) {
List<Device> allDevicesInGroup = new ArrayList<>();
Process[] targetGroup = this.processGroups[deviceType - 1];
// 1. 收集指定进程组中的所有设备
for (Process process : targetGroup) {
allDevicesInGroup.addAll(process.managedDevices.values());
}
// 2. 根据题目的三级排序规则进行排序
allDevicesInGroup.sort(
// 优先按 memSize 降序
Comparator.comparingInt((Device d) -> d.memSize).reversed()
// memSize 相同,按 procId 升序
.thenComparingInt(d -> d.procId)
// procId 相同,按 deviceId 升序
.thenComparingInt(d -> d.id)
);
// 3. 将排序后的Device对象列表转换为题目要求的 List<List<Integer>> 格式
return allDevicesInGroup.stream()
.map(d -> Arrays.asList(d.id, d.memSize, d.procId))
.collect(Collectors.toList());
}
}