搜索算法题目:软件补丁

题目描述: 在一个软件中发现了n个错误B={b1,b2,..bn},有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 { int time; int id; char cond[MAXN]; char modify[MAXN]; }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) { int cnt,bsize,errorNum; scanf("%d %d",&bsize,&programNum); for(int i=0;icnt) minTimeCost = cnt; return; } char tempB[MAXN]; int index; for(int i=0;i=0&&cnt+program[i].time<=minTimeCost)) { pa[program[i].id][index] = true; change(program[i],B,bsize,tempB); int errNum = 0; for(int j=0;j #include #define MAXN 20 #define MAXM 100 #define MAXSIZE 1024*1024 #define mustExist '+' #define shouldNotExist '-' #define bugProduced '+' #define bugCorrected '-' #define withoutEffect '0' typedef struct { unsigned sec:MAXN; }bitSec; typedef struct { int time; int id; char cond[MAXN]; char modify[MAXN]; }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) { int cnt,bsize,errorNum; scanf("%d %d",&bsize,&programNum); for(int i=0;icnt) minTimeCost = cnt; return; } bitSec tempB; int index; for(int i=0;i=0&&cnt+program[i].time<=minTimeCost)) { pa[program[i].id][index] = true; change(program[i],B,bsize,tempB); int errNum = 0; for(int j=0;j>j)%2; backtrack(cnt+program[i].time,B,bsize,errNum); memcpy(&B,&tempB,sizeof(bitSec)); pa[program[i].id][index] = false; } } } static bool match(programInfo &program,const bitSec &B,int n) { //检查是否可以选择program bool select = true; for(int i=0;i>(n-1-j))&1); } duplicate = pa[id][index]; return duplicate; } static void change(programInfo &program,bitSec &B,int n,bitSec &tempB) { memcpy(&tempB,&B,sizeof(bitSec)); for(int i=0;i #include #define MAXN 20 #define MAXM 100 #define MAXSIZE 1024*1024 #define mustExist '+' #define shouldNotExist '-' #define bugProduced '+' #define bugCorrected '-' #define withoutEffect '0' #define NO_BUGS 0xFFFFF #define ALL_BUGS 0 static long pa[MAXSIZE]; //记录到达该状态所使用的时间 static int open; static int close; static long maxlong; typedef struct { int time; int id; char cond[MAXN]; char modify[MAXN]; }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) { int i,bsize; scanf("%d %d",&bsize,&programNum); for(i=0;imax) max = open; //调整max } } pa[state] = -1; //已经扩展的节点对应的队列元素记为-1 if(state==min) { while(pa[min]==-1) min++; //调整min } }while(true); return pa[goal]; } static bool match(programInfo &program,long B,int n) { //检查是否可以选择program bool select = true; for(int i=0;i=0&&pa[i]=0&&pa[i]<=maxlong表示对应节点为等待扩展节点 minTime = pa[i]; minState = i; } return minState; }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值