動態規劃算法-以中學排班管理系統為例

1.動態規劃算法介紹?

1.算法思路

動態規劃算法通常用于求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每一個解都對應于一個值,我們希望找到具有最優值的解。動態規劃算法與分治法類似,其基本思想也是將待求解問題分解成若干個子問題,先求解子問題,然后從這些子問題的解得到原問題的解。與分治法不同的是,適合于用動態規劃求解的問題,經分解得到子問題往往不是互相獨立的。若用分治法來解這類問題,則分解得到的子問題數目太多,有些子問題被重復計算了很多次。如果能夠保存已解決的子問題的答案,而在需要時再找出已求得的答案,這樣就可以避免大量的重復計算,節省時間。我們可以用一個表來記錄所有已解的子問題的答案。不管該子問題以后是否被用到,只要它被計算過,就將其結果填入表中。這就是動態規劃法的基本思路。具體的動態規劃算法多種多樣,但它們具有相同的填表格式。

2.代碼介紹

/private static boolean foundOptimal = false; // 用于全局控制是否找到// 優化課程安排,使用遞歸模擬動態規劃過程private static void optimizeCourseScheduling(Scanner scanner, CourseService courseService) {System.out.print("輸入可用教室數量:");int capacity = scanner.nextInt(); // 用戶輸入教室的容量scanner.nextLine();List<CourseEntity> courses = courseService.getAllCourses(); // 獲取所有課程int n = courses.size(); // 課程總數int[] weights = new int[n]; // 每個課程占用的教室數量int[] values = new int[n]; // 每個課程的價值,這里使用教師ID// 為每門課程分配教師ID和教室資源System.out.println("正在為每門課程分配教師ID和教室資源...");for (int i = 0; i < n; i++) {weights[i] = 1; // 假設每個課程占用一個教室values[i] = courses.get(i).getTeacherId(); // 教師ID作為課程的價值}int maxValue = knapsack(0, weights, values, capacity, n);System.out.println("在可用教室數量為 " + capacity + " 的情況下,最大化的課程安排價值為:" + maxValue);// 初始化標記數組,所有課程初始為未選擇boolean[] selected = new boolean[n];foundOptimal = false; // 重置全局變量printSelectedCourses(0, weights, values, capacity, n, selected, maxValue);if (!foundOptimal) {System.out.println("未找到符合條件的課程安排。");}}// 遞歸函數模擬動態規劃解決背包問題
// 遞歸的深度為課程數量n,每層遞歸的復雜度與教室容量有關private static int knapsack(int index, int[] weights, int[] values, int capacity, int n) {// 基本情況:沒有課程可選或背包容量為0if (index == n || capacity == 0) {return 0;}// 如果當前課程的重量大于背包容量,則不能選擇該課程if (weights[index] > capacity) {return knapsack(index + 1, weights, values, capacity, n);}// 遞歸選擇:選擇包含當前課程或不包含當前課程的最大價值return Math.max(knapsack(index + 1, weights, values, capacity, n), // 不選擇當前課程values[index] + knapsack(index + 1, weights, values, capacity - weights[index], n) // 選擇當前課程);}// 遞歸回溯函數,意圖是打印出被選中的課程和教師IDprivate static boolean printSelectedCourses(int index, int[] weights, int[] values, int currentCapacity, int n, boolean[] selected, int maxValue) {if (foundOptimal) {return true; // 如果已經找到最優解,直接返回}if (index == n) {int currentValue = 0;for (int i = 0; i < n; i++) {if (selected[i]) {currentValue += values[i];}}if (currentCapacity == 0 && currentValue == maxValue) {// 打印當前選擇的課程for (int i = 0; i < n; i++) {if (selected[i]) {System.out.println("選擇的課程教師ID: " + values[i]);}}foundOptimal = true; // 標記已找到最優解return true;}return false;}// 不選擇當前課程selected[index] = false;printSelectedCourses(index + 1, weights, values, currentCapacity, n, selected, maxValue);// 嘗試選擇當前課程if (currentCapacity >= weights[index]) {selected[index] = true;printSelectedCourses(index + 1, weights, values, currentCapacity - weights[index], n, selected, maxValue);}return false;}

3.使用動態規劃算法模擬課程安排優化

1. `optimizeCourseScheduling` 方法:

?? ?作用:優化課程安排,使用遞歸模擬動態規劃過程。

?? ?參數列表:

???? ?`Scanner scanner`:用于接收用戶輸入的掃描器。

???? ?`CourseService courseService`:用于獲取課程數據的服務類。

2. `knapsack` 方法:

?? ?作用:模擬動態規劃解決背包問題,計算最大化的課程安排價值。

?? ?參數列表:

???? ?`int index`:當前處理的課程索引。

???? ?`int[] weights`:每個課程占用的教室數量。

???? ?`int[] values`:每個課程的價值(教師ID)。

???? ?`int capacity`:當前剩余的教室容量。

???? ?`int n`:課程總數。

3. `printSelectedCourses` 方法:

?? ?作用:遞歸回溯函數,意圖是打印出被選中的課程和教師ID。

?? ?參數列表:

???? ?`int index`:當前處理的課程索引。

???? ?`int[] weights`:每個課程占用的教室數量。

???? ?`int[] values`:每個課程的價值(教師ID)。

???? ?`int currentCapacity`:當前剩余的教室容量。

???? ?`int n`:課程總數。

???? ?`boolean[] selected`:標記數組,表示每個課程是否被選擇。

???? ?`int maxValue`:最大化的課程安排價值。

?詳細描述

1. `optimizeCourseScheduling` 方法:

?? ?該方法首先接收用戶輸入的教室容量,然后獲取所有課程數據。

?? ?為每門課程分配教師ID和教室資源,并初始化權重和價值數組。

?? ?調用 `knapsack` 方法計算最大化的課程安排價值。

?? ?初始化標記數組 `selected`,并調用 `printSelectedCourses` 方法打印出被選中的課程和教師ID。

?? ?如果未找到符合條件的課程安排,則輸出提示信息。

2. `knapsack` 方法:

?? ?該方法是用于模擬動態規劃解決背包問題。

?? ?基本情況:如果沒有課程可選或背包容量為0,則返回0。

?? ?如果當前課程的重量大于背包容量,則不能選擇該課程。

?? ?遞歸選擇:選擇包含當前課程或不包含當前課程的最大價值。

3. `printSelectedCourses` 方法:

?? ?該方法是遞歸回溯函數,用于打印出被選中的課程和教師ID。

?? ?如果已經找到最優解,直接返回。

?? ?遞歸終止條件:如果處理完所有課程,計算當前選擇的課程價值,如果滿足條件則打印選擇的課程并標記已找到最優解。

?? ?不選擇當前課程,繼續遞歸處理下一個課程。

?? ?嘗試選擇當前課程,如果當前容量足夠,繼續遞歸處理下一個課程。

總結

這段代碼的核心是一個簡化的課程安排優化問題,模擬動態規劃算法,以解決類似于背包問題的資源分配問題。程序的目標是在有限的教室資源下最大化課程的總價值,這里使用教師ID作為價值的代表。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/42312.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/42312.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/42312.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

干貨 | 2024大模型場景下智算平臺的設計與優化實踐(免費下載)

誠摯邀請您微信掃描以下二維碼加入方案驛站知識星球&#xff0c;獲取上萬份PPT/WORD解決方案&#xff01;&#xff01;&#xff01;感謝支持&#xff01;&#xff01;&#xff01;

android pdf框架-11,查看圖片

前10篇文章,9章關于pdf的,pdf解析后,里面也是有各種圖片,于是利用pdf的view來展示圖片,似乎也是個不錯的想法. android手機中的圖片查看功能,有的可以展示,有的不能.比如華為,榮耀對大體積的png是可以顯示的,小米是不顯示,只有縮略圖. 一張png50m大,比如清明上河圖,原圖是tif…

【C++】string的底層原理及實現

文章目錄 string類的存儲結構默認成員函數構造函數析構函數拷貝構造函數賦值重載 容量操作size()capacity()reserve()resize()clear() 遍歷與訪問operator[ ]迭代器范圍與for 增刪查改push_back()pop_back()append()operatorinsert()erase()c_str()find()substr() 非成員函數op…

c#的List<T>的SelectMany 和Select

在C#中&#xff0c;List<T>&#xff08;以及任何實現了IEnumerable<T>的集合&#xff09;的Select和SelectMany擴展方法都是LINQ&#xff08;Language Integrated Query&#xff09;的一部分&#xff0c;用于對集合中的元素進行查詢和轉換。 盡管它們的作用有些相…

Virtualbox和ubuntu之間的關系

1、什么是ubuntu Ubuntu 是一個類似于 Windows 的操作系統&#xff0c;但它是基于 Linux 內核開發的開源操作系統 2、什么是Virtualbox VirtualBox 是一款虛擬機軟件&#xff0c;使我們可以物理機上創建和運行虛擬機 也就是說,VirtualBox 提供了一個可以安裝和運行其他操作系…

力扣考研經典題 反轉鏈表

核心思想 頭插法&#xff1a; 不斷的將cur指針所指向的節點放到頭節點之前&#xff0c;然后頭節點指向cur節點&#xff0c;因為最后返回的是head.next 。 解題思路 1.如果頭節點是空的&#xff0c;或者是只有一個節點&#xff0c;只需要返回head節點即可。 if (head null …

算法訓練營day70

題目1&#xff1a;108. 冗余連接 (kamacoder.com) #include<iostream> #include<vector>using namespace std;int n; vector<int> father(10001, 0);void init() {for(int i 1;i < n;i) father[i] i; }int find(int u) {return u father[u] ? u : fa…

Echarts中的熱力圖和漏斗圖(在Vue中使用熱力圖和漏斗圖)

熱力圖 (Heatmap) Echarts的熱力圖用于展示兩個維度數據矩陣中的值分布情況。它通過在平面上劃分成多個矩形區域&#xff0c;并用不同的顏色填充這些區域來表示數據的大小或強度。顏色漸變從淺到深通常映射著數值從小到大&#xff0c;從而直觀展示數據的集中程度和分布模式。熱…

Mojolicious測試驅動開發:單元與集成測試的藝術

標題&#xff1a;Mojolicious測試驅動開發&#xff1a;單元與集成測試的藝術 Mojolicious是一個現代化的Perl Web開發框架&#xff0c;它不僅提供了強大的Web應用開發能力&#xff0c;還內置了豐富的測試工具來支持單元測試和集成測試。本文將深入探討如何在Mojolicious中進行…

人工智能期末復習簡答題

簡答: 子句集的化簡(1).消去連接詞”—>”和”<—>” (2)減少否定符號的轄域 (3)對變元標準化 (4)化為前束范式 (5)消去存在量詞 (6)化為Skolem標準形 (7)消去全稱量詞 (8)消去合取詞 (9)更換變元名稱 2.在狀態空間搜索中,Open表與Close…

半同步主從復制

半同步主從復制的概念 半同步主從復制&#xff08;Semisynchronous Replication, SBR&#xff09;是MySQL數據庫中的一種數據復制方式&#xff0c;它在異步復制的基礎上增加了一定程度的同步性&#xff0c;旨在提高數據安全性&#xff0c;減少數據丟失的風險。 半同步主從復制…

LeetCode 3101.交替子數組計數:等差數列求和(較詳題解)

【LetMeFly】3101.交替子數組計數&#xff1a;等差數列求和&#xff08;較詳題解&#xff09; 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/count-alternating-subarrays/ 給你一個二進制數組 nums 。 如果一個子數組中 不存在 兩個 相鄰 元素的值 相同 的情況&a…

階段三:項目開發---大數據開發運行環境搭建:任務8:安裝配置Redis

任務描述 知識點&#xff1a;安裝配置Redis 重 點&#xff1a; 安裝配置Redis 難 點&#xff1a;無 內 容&#xff1a; Redis&#xff08;Remote Dictionary Server )&#xff0c;即遠程字典服務&#xff0c;是一個開源的使用ANSI C語言編寫、支持網絡、可基于內存亦可…

【C++:運算符重載】

運算符重載 特點&#xff1a; 函數名由operator運算符組成 注&#xff1a; 不能通過其他符號創建新的操作符&#xff0c;只能使用C/C語法存在的操作符重載操作符必須有一個類類型參數&#xff0c;原因&#xff1a;不能重載操作符改變內置類型的行為當類成員操作符重載時&#…

web自動化(五)上傳文件

我們需要準備一個上傳文件的html&#xff0c;創建a.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>文件上傳示例</title> </head> <body><form action"/upload"…

電路基礎知識匯總

1.0 串連&#xff0c;并聯&#xff0c;混連 串聯的定義 電路串聯是一種電路元件的連接方式&#xff0c;其中各個元件沿著單一路徑互相連接&#xff0c;形成一個連續的鏈。在串聯電路中&#xff0c;每個節點最多只連接兩個元件&#xff0c;這意味著電流只有一條路徑可以通過整個…

Apache Seata Mac下的Seata Demo環境搭建

本文來自 Apache Seata官方文檔&#xff0c;歡迎訪問官網&#xff0c;查看更多深度文章。 本文來自 Apache Seata官方文檔&#xff0c;歡迎訪問官網&#xff0c;查看更多深度文章。 Mac下的Seata Demo環境搭建&#xff08;AT模式&#xff09; 前言 最近因為工作需要&#xf…

Git教程

文章目錄 Git分布式版本控制工具版本控制器的方式常用命令遠程倉庫Tip Git分布式版本控制工具 ? Git是一個開源的分布式版本控制系統&#xff0c;可以有效、高速地處理從很小到非常大的項目版本管理。 ? Git是分布式的&#xff0c;Git不需要有中心服務器&#xff0c;我們每…

【感謝告知】本賬號內容調整,聚焦于Google賬號和產品的使用經驗和問題案例分析

親愛的各位朋友&#xff1a; 感謝您對本賬號的關注和支持&#xff01; 基于對朋友們需求的分析和個人興趣的轉變&#xff0c;該賬號從今天將對內容做一些調整&#xff0c;有原來的內容改為Google&#xff08;谷歌&#xff09;賬號和產品的使用經驗&#xff0c;以及相關問題的…

24西安電子科技大學經濟與管理學院—考研錄取情況

24西安電子科技大學—經理與管理學院—考研錄取統計 01、經理與管理學院各個方向 02、24經濟與管理近三年復試分數線對比 1、經管院24年院線相對于23年院線普遍下降2-15分&#xff0c;個別專業上漲4-10分。 2、經管院應用經濟學2024年院線350分&#xff1b;管理科學與工程院線…