搜尋演算法題目 軟體補丁

2021-04-14 02:01:39 字數 3032 閱讀 5691

題目描述: 在乙個軟體中發現了n個錯誤b=,有p1,p2…pm個補丁程式。如果想要在軟體中應用pi程式,則軟體中必須存在bi(包含若干個錯誤),並且bj不能存在。然後,軟體將修正錯誤fi(如果錯誤存在的話),並且產生錯誤fj。 初始情況下軟體中包含了b中的所有錯誤,然後按照某一順序在軟體中應用補丁程式(應用某個補丁程式時,軟體必須符合該補丁程式的應用條件,且執行該程式需要一段時間)。要求找到乙個應用補丁程式的最優順序,修改軟體中的所有錯誤,並且所用的時間最少。注意,每個補丁程式可以應用多次。 輸入首先是兩個整數n和m,分別表示軟體中的錯誤個數和傳送的補丁個數。其中n和m滿足條件:1<=n<=20 1<=m<=100。 接下來的m行按順序描述m個補丁程式的情況,第i行描述第i-1號補丁程式。每一行包含乙個整數(表示在軟體中應用該補丁程式所需的時間)和兩個n個字元的字串。 第乙個字串描述應用第i-1號補丁程式的條件,說明在軟體中某錯誤應該存在還是不存在。字串中的第i個字元,如果是』+』,表示在軟體中必須存在第bi號錯誤;如果是』-』,表示軟體中錯誤bi不能存在;如果是』0』,表示錯誤bi存在或不存在均可。 第二個字串描述應用第i-1號補丁程式後的效果。字串中的第i個字元,如果是』+』,表示產生乙個新錯誤bi;如果是』-』,表示錯誤bi被修改好了;如果是』0』,表示錯誤bi不變。 解答方案:採用回溯法+廣度優先搜尋。對中間結果進行剪枝,記錄已經進行的擴充套件以進行判重。將軟體錯誤的狀態記錄為乙個20位的二進位制數,用1來表示軟體中存在某個錯誤,用0來表示軟體中不存在某個錯誤,1的位置對應錯誤的編號(從左到右從0開始計算),比如0010表示存在編號為2的錯誤。一共有2^20=1048576種狀態。將軟體錯誤的狀態作為節點,選取滿足條件的補丁程式進行擴充套件。選取的補丁程式須滿足以下幾點: (1)滿足應用該補丁程式的條件(根據輸入獲得); (2)當前軟體錯誤的狀態+選取該補丁程式不存在重複擴充套件; (3)當前修正總共所花的時間加上選取的補丁程式所花的時間不大於當前記錄的最優值。 採用整型二維陣列記錄已經擴充套件的節點。每一行對應乙個補丁程式,該行的每一列表示在某個錯誤狀態下選取該補丁程式。將軟體錯誤的狀態的二進位制形式轉化為十進位制以對應列的序號。位操作的使用。 優化的解決方案基於優先佇列的廣度優先搜尋演算法用乙個佇列儲存擴充套件出的節點,min和max分別表示佇列中可擴充套件節點的左邊界和右邊界。每次從佇列[min..max]中選取用時最少的節點進行擴充套件,直到選取的用時最少的節點是目標節點。佇列最大容量為2^20=1048576。佇列中每個元素記錄到達該狀態的最小用時。已經擴充套件的節點對應佇列元素的值為-1。每次擴充套件後需要對min和max進行重新調整。 **: 原始** #include

#include

#define maxn 20 #define maxm 100 #define maxsize 1024*1024 #define mustexist '+' #define shouldnotexist '-' #define bugproduced '+' #define bugcorrected '-' #define withouteffect '0' typedef struct programinfo; static bool pa[maxm][maxsize]; static programinfo program[maxm]; static int programnum; static int mintimecost; static int size; static void backtrack(int ,char ,int ,int ); static bool match(programinfo &,char ,int ); static bool duplicate(programinfo &,char ,int ,int & ); static void change(programinfo &,char ,int ,char ); int main(int argc,char **argv) char tempb[maxn]; int index; for(int i=0;i=0&&cnt+program[i].time<=mintimecost)) bitsec; typedef struct programinfo; static bool pa[maxm][maxsize]; static programinfo program[maxm]; static int programnum; static int mintimecost; static int size; static void backtrack(int ,bitsec ,int ,int ); static bool match(programinfo &, const bitsec &, int ); static bool duplicate(programinfo &, const bitsec &, int ,int & ); static void change(programinfo &, bitsec &,int ,bitsec & ); int main(int argc,char **argv) bitsec tempb; int index; for(int i=0;i=0&&cnt+program[i].time<=mintimecost)) } } static bool match(programinfo &program,const bitsec &b,int n) duplicate = pa[id][index]; return duplicate; } static void change(programinfo &program,bitsec &b,int n,bitsec &tempb) programinfo; static programinfo program[maxm]; static int programnum; static long mintimecost; static int size; static int bfs(int , int ); static bool match(programinfo &,long , int ); static long change(programinfo &, long , int ); static int getstate(int ,int ); int main(int argc,char **argv) } pa[state] = -1; //已經擴充套件的節點對應的佇列元素記為-1 if(state==min) }while(true); return pa[goal]; } static bool match(programinfo &program,long b,int n) return minstate; }

A 搜尋演算法

啟發式搜尋演算法 要理解 a 搜尋演算法,還得從啟發式搜尋演算法開始談起。所謂啟發式搜尋,就在於當前搜尋結點往下選擇下一步結點時,可以通過乙個啟發函式 來進行選擇,選擇代價最少的結點作為下一步搜尋結點而跳轉其上 遇到有乙個以上代價最 少的結點,不妨選距離當前搜尋點最近一次展開的搜尋點進行下一步搜尋 ...

A 搜尋演算法

a 演算法是基於bfs的一種入門級啟發式搜尋演算法,就是將bfs的佇列改為基於估價的優先佇列,可以快速地找到答案。優先隊列為小根堆 while 優先佇列不為空 取出隊頭並擴充套件 將擴充套件節點以估價值 當前值為優先順序入隊 endwhile估價函式越接近真實值演算法越優,但一定不能大於真實值,否則...

搜尋演算法小結

搜尋演算法是利用計算機的高效能來有目的的窮舉乙個問題的部分和所有的可能情況,從而求出問題的解的一種方法。常用的搜尋演算法有 一.回溯法 回溯演算法是所有搜尋演算法中最為基本的一種演算法,其採用了一種 走不通就掉頭 思想作為其控制結構,其相當於採用了先根遍歷的方法來構造解答樹,可用於找解或所有解以及最...