数据结构和算法

DSA 主页 DSA 概述 DSA 环境设置 DSA 算法基础 DSA 渐近分析

数据结构

DSA 数据结构基础 DSA 数据结构和类型 DSA 数组数据结构

链接列表

DSA 链接列表数据结构 DSA 双向链接列表数据结构 DSA 循环链表数据结构

堆栈 &队列

DSA 堆栈数据结构 DSA 表达式解析 DSA 队列数据结构

搜索算法

DSA 搜索算法 DSA 线性搜索算法 DSA 二分搜索算法 DSA 插值搜索 DSA 跳跃搜索算法 DSA 指数搜索 DSA 斐波那契搜索 DSA 子列表搜索 DSA 哈希表

排序算法

DSA 排序算法 DSA 冒泡排序算法 DSA 插入排序算法 DSA 选择排序算法 DSA 归并排序算法 DSA 希尔排序算法 DSA 堆排序 DSA 桶排序算法 DSA 计数排序算法 DSA 基数排序算法 DSA 快速排序算法

图形数据结构

DSA 图形数据结构 DSA 深度优先遍历 DSA 广度优先遍历 DSA 生成树

树数据结构

DSA 树数据结构 DSA 树遍历 DSA 二叉搜索树 DSA AVL 树 DSA 红黑树 DSA B树 DSA B+ 树 DSA 伸展树 DSA 尝试 DSA 堆数据结构

递归

DSA 递归算法 DSA 使用递归的汉诺塔 DSA 使用递归的斐波那契数列

分而治之

DSA 分而治之 DSA 最大最小问题 DSA 施特拉森矩阵乘法 DSA Karatsuba 算法

贪婪算法

DSA 贪婪算法 DSA 旅行商问题(贪婪方法) DSA Prim 最小生成树 DSA Kruskal 最小生成树 DSA Dijkstra 最短路径算法 DSA 地图着色算法 DSA 分数背包问题 DSA 作业排序截止日期 DSA 最佳合并模式算法

动态规划

DSA 动态规划 DSA 矩阵链乘法 DSA Floyd Warshall 算法 DSA 0-1 背包问题 DSA 最长公共子序列算法 DSA 旅行商问题(动态方法)

近似算法

DSA 近似算法 DSA 顶点覆盖算法 DSA 集合覆盖问题 DSA 旅行商问题(近似方法)

随机算法

DSA 随机算法 DSA 随机快速排序算法 DSA Karger 最小割算法 DSA Fisher-Yates 洗牌算法

DSA 有用资源

DSA 问答 DSA 快速指南


带截止期限的作业排序


作业调度算法用于在单个处理器上调度作业,以实现利润最大化。

作业调度算法的贪婪方法指出:"给定'n'个作业,每个作业都有开始时间和结束时间,需要以这样的方式调度它们,以便在最长截止期限内获得最大利润。"

作业调度算法

作业调度算法将一组具有截止期限和利润的作业作为输入,并调度子集最终输出结果为利润最高的作业。

算法

步骤 1 −  从输入的作业集合中找出最大截止期限值。

步骤 2 −  确定截止期限后,按利润降序排列作业。

步骤 3 −  选择利润最高的作业,且其时间周期不超过最大截止期限。
步骤 4 −  选定的作业集合作为输出。

示例

考虑以下任务及其截止期限和利润。以执行后产生最大利润的方式安排任务 −

S. No. 1 2 3 4 5
Jobs J1 J2 J3 J4 J5
Deadlines 2 2 1 3 4
Profits 20 60 40 100 80

步骤 1

从给定的截止日期中找出最大截止日期值 dm。

dm = 4.

步骤 2

按利润降序排列这些工作。

S. No. 1 2 3 4 5
Jobs J4 J5 J2 J3 J1
Deadlines 3 4 2 1 2
Profits 100 80 60 40 20

最大截止时间 dm 为 4。因此,所有任务必须在 4 之前结束。

选择利润最高的作业 J4。它占用了最大截止时间的 3 倍。

因此,下一个作业的时间段必须为 1。

总利润 = 100。

步骤 3

下一个利润最高的作业是 J5。但 J5 所花费的时间为 4,比截止时间多 3 倍。因此,它不能添加到输出集中。

步骤 4

下一个利润最高的作业是 J2。 J5 的耗时为 2,也超出了截止期限 1。因此,它不能添加到输出集中。

步骤 5

下一个利润更高的作业是 J3。J3 的耗时为 1,未超过给定的截止期限。因此,J3 被添加到输出集中。

总利润:100 + 40 = 140

步骤 6

由于满足了最大截止期限,算法结束。在截止期限内调度的作业输出集为 {J4, J3,最大利润为 140。

示例

以下是使用贪婪方法的作业排序算法的最终实现 −

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

// A structure to represent a Jobs
typedef struct Jobs {
   char id; // Jobs Id
   int dead; // Deadline of Jobs
   int profit; // 如果工作在截止日期前或截止日期结束,则可获利
} Jobs;

// 此函数用于根据以下条件对所有 Job 进行排序:
// 利润
int compare(const void* a, const void* b){
    Jobs* temp1 = (Jobs*)a;
    Jobs* temp2 = (Jobs*)b;
    return (temp2->profit - temp1->profit);
}

// 找出两个数字中的最小值。
int min(int num1, int num2){
   return (num1 > num2) ? num2 : num1;
}
int main(){
   Jobs arr[] = { 
      { 'a', 2, 100 },
      { 'b', 2, 20 },
      { 'c', 1, 40 },
      { 'd', 3, 35 },
      { 'e', 1, 25 }
   };
   int n = sizeof(arr) / sizeof(arr[0]);
   printf("Following is maximum profit sequence of Jobs: 
");
   qsort(arr, n, sizeof(Jobs), compare);
    int result[n]; // 存储作业结果序列
    bool slot[n]; // 跟踪空闲时间段

   // 初始化所有槽为空闲
   for (int i = 0; i < n; i++)
      slot[i] = false;

   // 遍历所有给定的作业
   for (int i = 0; i < n; i++) {

      // 为该作业寻找一个空闲位置
      for (int j = min(n, arr[i].dead) - 1; j >= 0; j--) {

         // 找到空闲槽
         if (slot[j] == false) {
            result[j] = i;
            slot[j] = true;
            break;
         }
      }
   }

   // 打印结果
   for (int i = 0; i < n; i++)
      if (slot[i])
         printf("%c ", arr[result[i]].id);
   return 0;
}

输出

Following is maximum profit sequence of Jobs: 
c a d 
#include<iostream>
#include<algorithm>
using namespace std;
struct Job {
   char id;
   int deadLine;
   int profit;
};
bool comp(Job j1, Job j2){
   return (j1.profit > j2.profit); //根据利润比较工作
}
int min(int a, int b){
   return (a<b)?a:b;
}
int main(){
   Job jobs[] = { { 'a', 2, 100 },
      { 'b', 2, 20 },
      { 'c', 1, 40 },
      { 'd', 3, 35 },
      { 'e', 1, 25 }
	  };
   int n = 5;
   cout << "Following is maximum profit sequence of Jobs: "<<"
";
   sort(jobs, jobs+n, comp); //按利润对工作进行排序
   int jobSeq[n]; // 存储结果(作业序列)
   bool slot[n]; // 跟踪空闲时间段
   for (int i=0; i<n; i++)
     slot[i] = false; //initially all slots are free
   for (int i=0; i<n; i++) { //对于所有给定的工作
     for (int j=min(n, jobs[i].deadLine)-1; j>=0; j--) { //从最后一个空闲位置搜索
       if (slot[j]==false) {
         jobSeq[j] = i; // 将此作业添加到作业序列
         slot[j] = true; // 将此插槽标记为已占用
         break;
       }
     }
   }
   for (int i=0; i<n; i++)
     if (slot[i])
       cout << jobs[jobSeq[i]].id << " "; //显示序列
}

输出

Following is maximum profit sequence of Jobs: 
c a d 
import java.util.*;
public class Job {
    // 每个任务都有一个唯一的 ID、利润和截止日期
    char id;
    int deadline, profit;
    // 构造函数
    public Job() {}
    public Job(char id, int deadline, int profit) {
      this.id = id;
      this.deadline = deadline;
      this.profit = profit;
    } 
    // 调度作业的函数接受两个参数
    // 数组列表和要调度的作业数量
    void printJobScheduling(ArrayList<Job> arr, int t) {
        // 数组长度
        int n = arr.size();
        // 按照利润降序对所有作业进行排序
        // 利润
        Collections.sort(arr,(a, b) -> b.profit - a.profit);
        // 跟踪空闲时间段
        boolean result[] = new boolean[t];
        // 存储结果(作业序列)
        char job[] = new char[t];
        // 遍历所有给定的作业
        for (int i = 0; i < n; i++) {    
         // 为这项工作找到一个空闲的时间(请注意,我们
         // 从最后一个可能的插槽开始)
         for (int j = Math.min(t - 1, arr.get(i).deadline - 1); j >= 0; j--) {     
            // 找到空闲插槽
            if (result[j] == false) {
               result[j] = true;
               job[j] = arr.get(i).id;
               break;
            }
         }
      }
      // 打印序列
      for (char jb : job)
      System.out.print(jb + " ");
      System.out.println();
   }
   // 驱动代码
   public static void main(String args[]) {
      ArrayList<Job> arr = new ArrayList<Job>();
      arr.add(new Job('a', 2, 100));
      arr.add(new Job('b', 2, 20));
      arr.add(new Job('c', 1, 40));
      arr.add(new Job('d', 3, 35));
      arr.add(new Job('e', 1, 25));     
      // Function call
      System.out.println("Following is maximum profit sequence of Jobs: ");
      Job job = new Job();     
      // Calling function
      job.printJobScheduling(arr, 3);
   }
}

输出

Following is maximum profit sequence of Jobs: 
c a d 
arr = [
    ['a', 2, 100], 
    ['b', 2, 20], 
    ['c', 1, 40], 
    ['d', 3, 35], 
    ['e', 1, 25]
    ]
print("Following is maximum profit sequence of Jobs: ")
# 数组长度
n = len(arr)
t = 3
# 根据以下条件对所有作业进行排序
# 利润降序
for i in range(n):
   for j in range(n - 1 - i):
     if arr[j][2] < arr[j + 1][2]:
       arr[j], arr[j + 1] = arr[j + 1], arr[j]

# 跟踪空闲时间段
result = [False] * t

# 存储结果(作业序列)
job = ['-1'] * t

# 遍历所有给定的作业
for i in range(len(arr)):

    # 为该作业查找空闲时间段
    #(注意,我们从
    # 最后一个可能的时间段开始)
    for j in range(min(t - 1, arr[i][1] - 1), -1, -1):

     # 找到空闲插槽
     if result[j] is False:
       result[j] = True
       job[j] = arr[i][0]
       break

# 打印序列
print(job)

输出

Following is maximum profit sequence of Jobs: 
['c', 'a', 'd']