动态规划算法-以机房管理系统为例

1.动态规划算法介绍 

1.算法思路

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。

2.代码介绍

// 推荐最优上机时间的方法,接收机器ID和上机类型ID作为参数
public static void recommendOptimalSessionTime(int machineID, int typeID) {
    // 获取当前机器的会话列表,即所有已安排的上机时间段
    List<Session> sessions = getSessionsByMachine(machineID); 
    // 计算最优时间槽,基于当前机器的会话列表、上机类型ID
    List<TimeSlot> timeSlots = calculateOptimalTimeSlots(machineID, typeID, sessions); 

    // 如果存在可用的时间槽
    if (!timeSlots.isEmpty()) {
        // 获取效率最高的时间槽
        TimeSlot optimalSlot = timeSlots.get(0); 
        // 打印推荐的最优上机时间详细信息
        System.out.println("推荐的最优上机时间:");
        System.out.println("开始时间:" + optimalSlot.getStartTime());
        System.out.println("结束时间:" + optimalSlot.getEndTime());
        System.out.println("效率:" + optimalSlot.getEfficiency());
    } else {
        // 如果没有可用的时间槽,则输出提示信息
        System.out.println("没有可用的上机时间。");
    }
}

// 交互式方法,提示用户输入机器ID和上机类型ID,并调用算法
private static void recommendOptimalSessionTime() {
    // 用户输入机器ID
    System.out.print("请输入机器ID:");
    int machineID = scanner.nextInt();
    scanner.nextLine();
    // 用户输入上机类型ID
    System.out.print("请输入上机类型ID:");
    int typeID = scanner.nextInt();
    scanner.nextLine();

    // 调用算法执行推荐逻辑,并传入用户输入的机器ID和上机类型ID
    recommendOptimalSessionTime(machineID, typeID);
}

// 核心算法方法,计算最优时间槽
public static List<TimeSlot> calculateOptimalTimeSlots(int machineID, int typeID, List<Session> sessions) {
    List<TimeSlot> timeSlots = new ArrayList<>();
    // 根据上机类型ID获取对应的费率,用于计算效率
    double rate = getRateByTypeID(typeID); 

    // 初始化时间槽,从当前时间开始,每隔30分钟一个槽,持续24小时
    long startTime = System.currentTimeMillis();
    long endTime = startTime + 24 * 60 * 60 * 1000; // 结束时间为当前时间加24小时
    long interval = 30 * 60 * 1000; // 时间槽间隔设置为30分钟

    // 创建时间槽列表
    for (long t = startTime; t < endTime; t += interval) {
        // 每个时间槽从当前时间开始,持续30分钟
        TimeSlot slot = new TimeSlot(new Timestamp(t), new Timestamp(t + interval));
        timeSlots.add(slot);
    }

    // 动态规划计算每个时间槽的效率
  
    for (TimeSlot slot : timeSlots) {
        double efficiency = calculateEfficiency(slot, sessions, rate);
        slot.setEfficiency(efficiency);
    }

    // 按效率从高到低排序时间槽
    timeSlots.sort((a, b) -> Double.compare(b.getEfficiency(), a.getEfficiency()));

    // 返回排序后的最优时间槽列表
    return timeSlots;
}

// 计算单个时间槽的效率的方法
private static double calculateEfficiency(TimeSlot slot, List<Session> sessions, double rate) {
    double efficiency = 0;
    // 遍历所有会话,如果会话与时间槽冲突,则降低效率
    for (Session session : sessions) {
        if (slot.getStartTime().before(session.getEndTime()) && slot.getEndTime().after(session.getStartTime())) {
            efficiency -= rate; // 效率降低,因为会话与时间槽冲突
        }
    }
    // 如果时间槽内没有冲突的会话,则效率增加
    efficiency += rate;
    return efficiency;
}

3.算法应用概括

动态规划(Dynamic Programming, DP)是一种算法思想,它将复杂问题分解为更简单的子问题,通过解决子问题来构建解决方案。在给定的代码中,推荐最优上机时间的算法。

以下是使用动态规划思想的大致步骤:

在提供的代码中,我们有几个方法,每个方法都有特定的功能和参数列表。下面是对每个方法及其参数的分析:

1. `recommendOptimalSessionTime(int machineID, int typeID)`:

    功能: 推荐基于机器ID和上机类型ID的最优上机时间。

    参数:

      `machineID`: 表示特定机器的唯一标识符。

      `typeID`: 表示上机类型的唯一标识符。

2. `recommendOptimalSessionTime()`:

    功能: 交互式方法,提示用户输入机器ID和上机类型ID,然后调用`recommendOptimalSessionTime(int, int)`方法。

    参数: 无(直接使用`scanner`对象从用户那里获取输入)。

3. `calculateOptimalTimeSlots(int machineID, int typeID, List<Session> sessions)`:

    功能: 计算给定机器和上机类型下的所有可能时间槽的最优时间槽列表。

    参数:

      `machineID`: 特定机器的ID。

      `typeID`: 上机类型的ID。

      `sessions`: 一个`Session`对象列表,表示当前机器上已经安排的会话。

4. `calculateEfficiency(TimeSlot slot, List<Session> sessions, double rate)`:

    功能: 计算给定时间槽的效率,考虑了与现有会话的冲突和上机类型的费率。

    参数:

      `slot`: 要评估的`TimeSlot`对象。

      `sessions`: 当前机器上已经安排的会话列表。

      `rate`: 上机类型的费率,用于计算效率的影响。

5. `getRateByTypeID(int typeID)`:

    功能: 根据提供的上机类型ID,从数据库中检索对应的费率。

    参数:

      `typeID`: 上机类型的ID。

6. `getSessionsByMachine(int machineID)`:

    功能: 从数据库中检索与特定机器ID关联的所有会话。

    参数:

      `machineID`: 机器的ID。

 方法内部逻辑分析:

 `recommendOptimalSessionTime(int machineID, int typeID)`:

   调用`getSessionsByMachine(machineID)`来获取特定机器的所有会话。

   使用这些会话和上机类型ID调用`calculateOptimalTimeSlots(...)`来找到最优时间槽。

   如果存在最优时间槽,打印其详细信息;否则,打印没有可用时间的信息。

 `calculateOptimalTimeSlots(...)`:

   初始化时间槽列表,从当前时间开始,每隔30分钟,直到24小时后。

   对于每个时间槽,调用`calculateEfficiency(...)`来计算效率。

   使用排序来找到效率最高的时间槽。

 `calculateEfficiency(...)`:

   对于每个时间槽,遍历所有会话,检查是否有冲突。

   如果时间槽与会话时间重叠,降低效率值。

   最终返回计算出的效率值。

 `getRateByTypeID(typeID)` 和 `getSessionsByMachine(machineID)`:

   这两个方法负责从数据库中检索必要的信息,它们使用预paredStatement来避免SQL注入,并处理数据库连接和结果集。

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值