公交调度-车次链编制贪心算法

---恢复内容开始---

  1 package cn.edu.karel.work.public_transit_problem;
  2
  3 import java.io.File;
  4 import java.io.FileNotFoundException;
  5 import java.io.FileReader;
  6 import java.io.IOException;
  7 import java.util.ArrayList;
  8 import java.util.List;
  9
 10 /**
 11  * GreedSolute类
 12  *
 13  * @author Karel Zuo
 14  * @time 2015.6.4
 15  * @version 1.0
 16  * @description 贪心算法求解公交时刻表和车次链问题
 17  */
 18 public class GreedSolute {
 19     /** 发车时刻表数据 */
 20     static File forward = new File("D:/mycode/Eclipse/Bus Scheduel Problem/scheduel1/ForwardScheduel/start time.txt");
 21     static File backward = new File("D:/mycode/Eclipse/Bus Scheduel Problem/scheduel1/BackScheduel/start time.txt");
 22     static int sum = 0;
 23
 24     public static void main(String[] args) throws IOException{
 25         /** 创建时刻表 */
 26         Scheduel scheduel = new Scheduel();
 27         inputForward(scheduel);
 28         inputBackward(scheduel);
 29
 30         /** 固定行车计划 */
 31         ArrayList<TrainsitChain> chain = creatFixedPlan(scheduel);
 32
 33         /** 可变行车计划 */
 34         //chain = creatVariablePlan(scheduel,chain);
 35     }
 36
 37     /**
 38      * 将发车时刻表中的所有车次按照 FIFO规则排序
 39      *
 40      * @param scheduel 发车时刻表
 41      * @return list 排序后的车次序号列表
 42      */
 43     public static ArrayList<Integer> sortScheduel(Scheduel scheduel){
 44         /** 排序后的车次序号列表 */
 45         ArrayList<Integer> list = new ArrayList<Integer>();
 46
 47         int i = 0;
 48         int j = 0;
 49         int k = 0;
 50         while(i<scheduel.tranListForward.size() && j<scheduel.tranListBack.size())
 51         {
 52             if(scheduel.tranListForward.get(i).arriveTime <= scheduel.tranListBack.get(j).arriveTime)
 53             {
 54                 list.add(k, scheduel.tranListForward.get(i).id);
 55                 i++;
 56             }
 57             else
 58             {
 59                 list.add(k, scheduel.tranListBack.get(j).id);
 60                 j++;
 61             }
 62             k++;
 63         }
 64         while(i<scheduel.tranListForward.size())
 65         {
 66             list.add(k++, scheduel.tranListForward.get(i++).id);
 67         }
 68         while(j<scheduel.tranListBack.size())
 69         {
 70             list.add(k++, scheduel.tranListBack.get(j++).id);
 71         }
 72         return list;
 73     }
 74
 75     /**
 76      * 贪心算法搜索出剩余车次中最长的车次链
 77      *
 78      * @param list 按照FIFO规则排序后的车次的列表
 79      * @param scheduel 用于搜索车次链的发车时刻表
 80      * @return chain 搜索到的车次链
 81      */
 82     public static TrainsitChain searchChain(ArrayList<Integer> list,Scheduel scheduel){
 83         TrainsitChain chain = new TrainsitChain();
 84
 85         /** 以当前剩余车次中的第一个车次为该车次链的首个车次*/
 86         int index = list.get(0);
 87         int len = scheduel.tranListForward.size();
 88         if(index >= len ){
 89             index -= len;
 90             chain.addTransit(scheduel.tranListBack.get(index));
 91         }else{
 92             chain.addTransit(scheduel.tranListForward.get(index));
 93         }
 94         list.remove(0);
 95
 96         /**遍历当前剩余车次搜索到最长车次链 */
 97         int i=0;
 98         while(i<list.size())
 99         {
100             int next = list.get(i);
101             int l = chain.theChain.size();
102             /** 判断该车次是上行还是下行 */
103             if(next >= len)
104             {
105                 next -= len;
106                 if(scheduel.tranListBack.get(next).getStartTime() >= chain.end){
107                     /** 车次链上前后辆车次行驶方向不同 */
108                     if(chain.theChain.get(l-1).isForward){
109                         chain.addTransit(scheduel.tranListBack.get(next));
110                         list.remove(i);
111                     }
112                     else
113                         i++;
114                 }
115                 else
116                     i++;
117             }
118             else{
119                 if(scheduel.tranListForward.get(next).getStartTime() >= chain.end)
120                 {
121                     if(!chain.theChain.get(l-1).isForward){
122                         chain.addTransit(scheduel.tranListForward.get(next));
123                         list.remove(i);
124                     }
125                     else
126                         i++;
127                 }
128                 else
129                     i++;
130             }
131         }
132         return chain;
133     }
134
135     /**
136      * 读取上行数据
137      * @throws IOException
138      */
139     public static void inputForward(Scheduel scheduel) throws IOException{
140         try{
141             int i = 0;
142             FileInputStream fis = new FileInputStream(forward);
143             InputStreamReader isr = new InputStreamReader(fis);
144             @SuppressWarnings("resource")
145             LineNumberReader lnr = new LineNumberReader(isr);
146             String s = null;
147             while ((s = lnr.readLine()) != null) {
148                 int data = Integer.parseInt(s.trim());
149                 Transit t = new Transit();
150                 t.setID(i);
151                 t.setStartTime(data);
152                 t.setArriveTime(data+Transit.RUN_FOWARD_TIME);
153                 t.setForward(true);
154                 if(i!=0)
155                     t.setAdjust(scheduel.tranListForward.get(i-1));
156                 scheduel.addTransitForward(t);
157                 i++;
158             }
159         }catch(FileNotFoundException e){
160             e.printStackTrace();
161         }
162         System.out.println("上行数据:  ");
163         System.out.println(scheduel.tranListForward.size());
164     }
165
166     /**
167      * 读取下行数据
168      * @throws IOException
169      */
170     public static void inputBackward(Scheduel scheduel) throws IOException{
171         try{
172             int i = 0;
173             int len = scheduel.tranListForward.size();
174             FileInputStream fis = new FileInputStream(backward);
175             InputStreamReader isr = new InputStreamReader(fis);
176             @SuppressWarnings("resource")
177             LineNumberReader lnr = new LineNumberReader(isr);
178             String s = null;
179             while ((s = lnr.readLine()) != null) {
180                 int data = Integer.parseInt(s.trim());
181                 Transit t = new Transit();
182                 t.setID(i+len);
183                 t.setStartTime(data);
184                 t.setArriveTime(data+Transit.RUN_BACK_TIME);
185                 t.setForward(false);
186                 scheduel.addTransitBack(t);
187                 if(i!=0)
188                     t.setAdjust(scheduel.tranListBack.get(i-1));
189                 i++;
190             }
191         }catch(FileNotFoundException e){
192             e.printStackTrace();
193         }
194         System.out.println("下行数据:  ");
195         System.out.println(scheduel.tranListBack.size());
196     }
197
198     /**
199      * 根据当前时刻表,不作改动,计算固定行车计划
200      *
201      * @param scheduel 当前时刻表
202      * @return chainList 固定行车计划车次链集合
203      */
204     public static ArrayList<TrainsitChain> creatFixedPlan(Scheduel scheduel){
205         ArrayList<TrainsitChain> chainList = new ArrayList<TrainsitChain>();
206         ArrayList<Integer> trainsitList = new ArrayList<Integer>();
207         trainsitList = sortScheduel(scheduel);
208         while(!trainsitList.isEmpty())
209         {
210             chainList.add(searchChain(trainsitList,scheduel));
211         }
212         System.out.println("车次链数目(最小车队规模): "+chainList.size());
213
214         int n = chainList.size();
215         int i;
216         for( i=0;i<n;i++)
217         {
218             int m = chainList.get(i).theChain.size();
219             System.out.println("车次链:"+ (i+1) +"的组成:");
220             System.out.println();
221             for(int j=0;j<m;j++)
222             {
223                 System.out.print(chainList.get(i).theChain.get(j).getStartTime()+"("+chainList.get(i).theChain.get(j).getIsForward()+")"+" , ");
224             }
225             System.out.println();
226         }
227
228         return  chainList;
229     }
230
231     /**
232      * 在允许范围内调整发车时刻得到可变行车计划
233      * @param scheduel 行车计划
234      * @param plan 固定行车计划
235      * @return chain 可变行车计划
236      */
237     public static ArrayList<TrainsitChain> creatVariablePlan(Scheduel scheduel, ArrayList<TrainsitChain> plan){
238         sum++;
239         System.out.println("********************** 可变行车计划 *******************************");
240 //        System.out.println("********************** 原始发车时刻表 *******************************");
241 //        for(Transit t:scheduel.tranListForward)
242 //            System.out.println("ID:  " + t.getID() + "   发车时间:" + t.getStartTime() );
243 //        for(Transit t:scheduel.tranListBack)
244 //            System.out.println("ID:  " + t.getID() + "   发车时间:" + t.getStartTime() );
245
246         ArrayList<TrainsitChain> chain;
247
248         /** 计算n值,找到最大点 */
249         int last = scheduel.tranListForward.size();
250         for(Transit t:scheduel.tranListForward){
251             for(Transit s:scheduel.tranListBack){
252                 if(s.getStartTime() >= t.getArriveTime()){
253                     if(s.getArriveTime() >= scheduel.tranListForward.get(last-1).getStartTime())
254                         t.setN(scheduel.tranListForward.get(last-1).getID() - t.getID() + 1);
255                     for(Transit o:scheduel.tranListForward){
256                         if(o.getStartTime() >= s.getArriveTime()){
257                             t.setN(o.getID() - t.getID());
258                             break;
259                         }
260                     }
261                     break;
262                 }
263             }
264         }
265         int size = scheduel.tranListBack.size();
266         for(Transit t:scheduel.tranListBack){
267             for(Transit s:scheduel.tranListForward){
268                 if(s.getStartTime() >= t.getArriveTime()){
269                     if(s.getArriveTime() >= scheduel.tranListBack.get(size-1).getStartTime())
270                         t.setN(scheduel.tranListBack.get(size-1).getID() - t.getID() + 1);
271                     for(Transit o:scheduel.tranListBack){
272                         if(o.getStartTime() >= s.getArriveTime()){
273                             t.setN(o.getID() - t.getID());
274                             break;
275                         }
276                     }
277                     break;
278                 }
279             }
280         }
281         int max = 0, maxID = 0;
282         for(Transit t:scheduel.tranListForward){
283             if(t.getN() > max){
284                 max = t.getN();
285                 maxID = t.getID();
286             }
287         }
288         for(Transit t:scheduel.tranListBack){
289             if(t.getN() > max){
290                 max = t.getN();
291                 maxID = t.getID();
292             }
293         }
294
295 //        System.out.println("********************** N值表 *******************************");
296 //        for(Transit t:scheduel.tranListForward)
297 //            System.out.println("ID:  " + t.getID() +  "   发车时间:" + t.getStartTime()+ "   N 值:" + t.getN() );
298 //        for(Transit t:scheduel.tranListBack)
299 //            System.out.println("ID:  " + t.getID() +  "   发车时间:" + t.getStartTime()+ "   N 值:" + t.getN() );
300
301 //        System.out.println("最大N值:" + max + " " + "最大N值点:" + maxID);
302         /** 调整发车时间 */
303         Transit first;
304         if(maxID < scheduel.tranListForward.size())
305             first = scheduel.tranListForward.get(maxID);
306         else
307             first = scheduel.tranListBack.get(maxID-scheduel.tranListForward.size());
308         Scheduel s = adjustScheduel(scheduel,first);
309         //System.out.println("*******************  " + s.tranListBack.get(14-s.tranListForward.size()).getArriveTime() + "*****************");
310
311         /** 搜索车次链 */
312         chain = creatFixedPlan(s);
313
314         /** 判断是否继续搜索 */
315 //        System.out.println(" ");
316 //        System.out.println("  可变行车计划:  ");
317 //        System.out.println("可变计划最小车队规模: " + chain.size());
318 //        System.out.println(" ");
319 //        System.out.println("可变行车计划:");
320         int n = chain.size();
321         int i;
322         for( i=0;i<n;i++)
323         {
324             int m = chain.get(i).theChain.size();
325 //            System.out.println("车次链:"+ (i+1) +"的组成:");
326 //            System.out.println();
327             for(int j=0;j<m;j++)
328             {
329                 //System.out.print(chain.get(i).theChain.get(j).getStartTime()+"("+chain.get(i).theChain.get(j).getIsForward()+")"+" , ");
330             }
331             //System.out.println();
332         }
333
334         /** 再求解一次调整之后的计算n值,找到最大点 */
335         int last1 = scheduel.tranListForward.size();
336         for(Transit t:scheduel.tranListForward){
337             for(Transit s1:scheduel.tranListBack){
338                 if(s1.getStartTime() >= t.getArriveTime()){
339                     if(s1.getArriveTime() >= scheduel.tranListForward.get(last1-1).getStartTime())
340                         t.setN(scheduel.tranListForward.get(last1-1).getID() - t.getID() + 1);
341                     for(Transit o:scheduel.tranListForward){
342                         if(o.getStartTime() >= s1.getArriveTime()){
343                             t.setN(o.getID() - t.getID());
344                             break;
345                         }
346                     }
347                     break;
348                 }
349             }
350         }
351         int size1 = scheduel.tranListBack.size();
352         for(Transit t:scheduel.tranListBack){
353             for(Transit s1:scheduel.tranListForward){
354                 if(s1.getStartTime() >= t.getArriveTime()){
355                     if(s1.getArriveTime() >= scheduel.tranListBack.get(size1-1).getStartTime())
356                         t.setN(scheduel.tranListBack.get(size1-1).getID() - t.getID() + 1);
357                     for(Transit o:scheduel.tranListBack){
358                         if(o.getStartTime() >= s1.getArriveTime()){
359                             t.setN(o.getID() - t.getID());
360                             break;
361                         }
362                     }
363                     break;
364                 }
365             }
366         }
367         int max1 = 0;
368         int maxID1 = 0;
369         for(Transit t:scheduel.tranListForward){
370             if(t.getN() > max1){
371                 max1 = t.getN();
372                 maxID1 = t.getID();
373             }
374         }
375         for(Transit t:scheduel.tranListBack){
376             if(t.getN() > max1){
377                 max1 = t.getN();
378                 maxID1 = t.getID();
379             }
380         }
381 ////        System.out.println("调整之后最大N:" + max1);
382 ////        System.out.println("********************** 调整之后的N值表 *******************************");
383 //        for(Transit t:s.tranListForward)
384 //            System.out.println("ID:  " + t.getID() +  "   发车时间:" + t.getStartTime()+ "   N 值:" + t.getN() );
385 //        for(Transit t:s.tranListBack)
386 //            System.out.println("ID:  " + t.getID() +  "   发车时间:" + t.getStartTime()+ "   N 值:" + t.getN() );
387         int newN = 0;
388         if(maxID >= scheduel.tranListForward.size())
389             newN = scheduel.tranListBack.get(maxID-s.tranListForward.size()).getN();
390         else
391             newN = scheduel.tranListForward.get(maxID).getN();
392         System.out.println("调整之后原最大N——new:" + newN);
393         if(max1 > newN ){
394             chain = creatVariablePlan(s,chain);
395         }
396         else{
397             System.out.println("求解结束!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
398         }
399         return chain;
400     }
401
402     /**
403      * 允许范围内调整时刻表缩减单条线路最小车队规模
404      *
405      * @param scheduel 初始时刻表
406      * @param plan 固定行车计划
407      * @param t 开始调整的初始车次
408      * @return adj_scheduel 调整后的时刻表
409      */
410     public static Scheduel adjustScheduel(Scheduel scheduel, Transit t){
411
412         final int RUNTIME_FORWARD = Transit.RUN_FOWARD_TIME;
413         final int RUNTIME_BACK = Transit.RUN_BACK_TIME;
414
415         /** 获取初始车次的ID */
416         int id = t.getID();
417 //        System.out.println("查找到的初始车次序号:" + t.getID() +"发车时间:"+ t.getStartTime());
418
419         int a = t.getArriveTime() - t.adjust;
420 //        System.out.println("初始车次的最早发车后到达末站的时刻:" + a);
421         int b = 0;
422         if(id >= scheduel.tranListForward.size()){//初始车次位于下行方向
423 //            System.out.println("初始值位于上行方向,T(j-1)位于下行方向");
424             id = id - scheduel.tranListForward.size();
425
426             /** 寻找初始车次的第一个可行车次链上的下一个车次 */
427             int num = 0;
428             for(Transit e: scheduel.tranListForward){
429                 if((e.getStartTime()+e.getAdjust()) >= a){
430 //                    System.out.println("下一个可行车次:" + e.getArriveTime());
431                     num = e.getID();
432                     b = e.getStartTime();
433                     if(b >= a){
434                         t.setStartTime(t.getStartTime()-t.getAdjust());
435                         t.setArriveTime(t.getStartTime() + 15);
436                         for(Transit o: scheduel.tranListBack){
437                             if(o.getStartTime()+o.getAdjust() >= e.getArriveTime()){
438                                 if(o.getStartTime() < e.getArriveTime()){
439                                     o.setStartTime(o.getStartTime()+o.getAdjust());
440                                     o.setArriveTime(o.getStartTime() + 15);
441                                     o.adjust = 0;
442 //                                    System.out.println("调整 ID:" + o.getID() + "的值为: " + o.getStartTime() );
443                                 }
444                             }
445                         }
446                     }
447                     else{
448                         e.setStartTime(e.getStartTime()+e.getAdjust());
449                         e.setArriveTime(e.getStartTime() + 15);
450                         e.adjust = 0;
451 //                        System.out.println("调整 ID:" + e.getID() + "的值为: " + e.getStartTime() );
452                         if(t.getArriveTime() < e.getStartTime()){
453                             t.setStartTime(t.getStartTime()-t.getAdjust());
454                             t.setArriveTime(t.getStartTime() + 15);
455 //                            System.out.println("调整 ID:" + t.getID() + "的值为: " + t.getStartTime() );
456                         }
457                     }
458                     break;
459                 }
460             }
461         }
462         else{//初始车次位于上行方向
463             /** 寻找初始车次的第一个可行车次链上的下一个车次 */
464             int num = 0;
465             for(Transit e: scheduel.tranListForward){
466                 if((e.getStartTime()+e.getAdjust()) >= a){
467                     num = e.getID();
468                     b = e.getStartTime();
469                     if(b >= a){
470                         t.setStartTime(t.getStartTime()-t.getAdjust());
471                         t.setArriveTime(t.getStartTime() + 15);
472                         for(Transit o: scheduel.tranListBack){
473                             if(o.getStartTime()+o.getAdjust() >= e.getArriveTime()){
474                                 if(o.getStartTime() < e.getArriveTime()){
475                                     o.setStartTime(o.getStartTime()+o.getAdjust());
476                                     o.setArriveTime(o.getStartTime() + 15);
477                                     o.adjust = 0;
478                                 }
479                             }
480                         }
481                     }
482                     else{
483                         e.setStartTime(e.getStartTime()+e.getAdjust());
484                         e.setArriveTime(e.getStartTime() + 15);
485                         e.adjust = 0;
486                         if(t.getArriveTime() < e.getStartTime()){
487                             t.setStartTime(t.getStartTime()-t.getAdjust());
488                             t.setArriveTime(t.getStartTime() + 15);
489                         }
490                     }
491                     break;
492                 }
493             }
494         }
495         return scheduel;
496     }
497 }
498
499 /**
500  * TrainsitChain类
501  *
502  * @author Karel Zuo
503  * @time 2015.6.7
504  * @version 1.0
505  * @description 该类是车次链类,一个车次链由可以被同一辆车执行的所有车次组成
506  */
507 public class TrainsitChain {
508
509     /** 车次链上第一个车次的发车时刻 */
510     float first = 0;
511     /** 车次链上最后一辆车到站时间 */
512     float end = 0;
513     /** 车次链上每一个车次的集合 */
514     ArrayList<Transit> theChain = new ArrayList<>();
515
516     /**
517      * 添加车次到车次链
518      * @param transit 车次
519      */
520     public void addTransit(Transit transit){
521         if(first == 0){
522             first = transit.startTime;
523             end = transit.arriveTime;
524             theChain.add(transit);
525         }
526         else{
527             end = transit.arriveTime;
528             theChain.add(transit);
529         }
530     }
531 }
532
533 public class Scheduel {
534
535     /** 上行时刻表的所有车次集合 */
536     ArrayList<Transit> tranListForward = new ArrayList<Transit>();
537     /** 下行行时刻表的所有车次集合 */
538     ArrayList<Transit> tranListBack = new ArrayList<Transit>();
539
540     /**
541      * @param trainsit 车次对象
542      */
543     public void addTransitForward(Transit tansit){
544         this.tranListForward.add(tansit);
545     }
546
547     /**
548      * @param trainsit 车次对象
549      */
550     public void addTransitBack(Transit tansit){
551         this.tranListBack.add(tansit);
552     }
553
554     /**
555      * @return tranListForward 上行车次集合
556      */
557     public List<Transit> getTranListForeard(){
558         return this.tranListForward;
559     }
560
561     /**
562      * @return tranListBack 下行车次集合
563      */
564     public List<Transit> getTranListBack(){
565         return this.tranListBack;
566     }
567 }
568
569 /**
570  * 车次类
571  *
572  * @author Karel Zuo
573  * @time 2015.6.4
574  * @version 1.0
575  * @description 该类用于表示一个车次的全部信息
576  */
577 public class Transit {
578     /** 上行方向运行时间 */
579     public final static int RUN_FOWARD_TIME = 59;//65;
580     /** 下行方向运行时间 */
581     public final static int RUN_BACK_TIME = 62;//58;
582     /** 车辆运行方向 */
583     boolean isForward;
584     /** 发车时间 */
585     int startTime;
586     /** 到站时间 */
587     int arriveTime;
588     /** 车次ID */
589     int id;
590     /** 发车时间允许调整范围 */
591     int adjust = 0;
592     /** 车次的n值 */
593     int N = 0;
594
595     /**
596      * @return startTime 发车时间
597      */
598     public int getStartTime(){
599         return this.startTime;
600     }
601
602     /**
603      * @return arriveTime 到站时间
604      */
605     public int getArriveTime(){
606         return this.arriveTime;
607     }
608
609     /**
610      * @return id 车次id
611      */
612     public int getID(){
613         return this.id;
614     }
615
616     /**
617      * @return isForward 车辆运行方向
618      */
619     public boolean getIsForward(){
620         return this.isForward;
621     }
622
623     /**
624      * @param adjust 发车时刻允许调整范围
625      */
626     public int getAdjust(){
627         return this.adjust;
628     }
629
630     /**
631      * @param N 该车次的N值
632      */
633     public int getN(){
634         return this.N;
635     }
636
637     /**
638      * @param time 设置的发车时间
639      */
640     public void setStartTime(int time){
641         this.startTime = time;
642     }
643
644     /**
645      * @param time 设置的到站时间
646      */
647     public void setArriveTime(int time){
648         this.arriveTime = time;
649     }
650
651     /**
652      * @param id 车次序号
653      */
654     public void setID(int id){
655         this.id = id;
656     }
657
658     /**
659      * @param isForward 车次运行方向
660      */
661     public void setForward(boolean isForward){
662         this.isForward = isForward;
663     }
664
665     /**
666      * @param t 车次链上相连的前一个车次
667      */
668     public void setAdjust(Transit t){
669         int adjust = 0;//this.startTime - t.getStartTime();
670         if(adjust < 10)
671             adjust = (int)(0.7*adjust);
672         else if(adjust < 20)
673             adjust = (int)(0.5*adjust);
674         else if(adjust < 40)
675             adjust = (int)(0.4*adjust);
676         else
677             adjust = (int)(0.3*adjust);
678         this.adjust = adjust;
679     }
680
681     /**
682      * @param time 设置的发车时间
683      */
684     public void setN(int N){
685         this.N = N;
686     }
687 }

---恢复内容结束---

时间: 2024-10-12 12:13:14

公交调度-车次链编制贪心算法的相关文章

算法导论——lec 13 贪心算法与图上算法

之前我们介绍了用动态规划的方法来解决一些最优化的问题.但对于有些最优化问题来说,用动态规划就是"高射炮打蚊子",采用一些更加简单有效的方法就可以解决.贪心算法就是其中之一.贪心算法是使所做的选择看起来是当前最佳的,期望通过所做的局部最优选择来产生一个全局最优解. 一. 活动选择问题 [问题]对几个互相竞争的活动进行调度:活动集合S = {a1, a2, ..., an},它们都要求以独占的方式使用某一公共资源(如教室),每个活动ai有一个开始时间si和结束时间fi ,且0 ≤ si &

区间图着色问题(贪心算法的解法)

问题描述:假设要用很多个教室对一组活动进行调度.我们希望使用尽可能少的教室来调度所有活动.请给出一个算法,来确定哪一个活动使用哪一间教室.这个问题也被称为区间图着色问题,即相容的活动着同色,不相容的着不同颜色,使得所用颜色数最少. 解法思想: 其实我们知道,对于单个教室我们可以用贪心算法进行求解,但是对于这个区间图的问题,我们采用的方法是多次的贪心.其实你想想看,你无非就是要使那些活动 全部被安排完吧,当然这样安排的方法很多,如何使得安排后的教室最小呢???? 这明显也是个贪心的问题.聪明的人很

贪心算法-----单线程:活动安排问题 多线程:多机调度问题

一.贪心算法的特点 顾名思义,贪心算法总是做出在当前看来是最好的选择.虽然贪心算法并不从整体最优上加以考虑,它所做出的选择只是在某种意义上的局部最优选择. 贪心算法的优点是更简单,更直接且解题效率更高,即使贪心算法不能得到整体最优解,但其最终结果却是最优解的很好的近似解. 二.贪心算法的理解 由于涉及到在做出在当前看来最好的选择,所以会经常采用排序算法,推荐使用快速排序算法,复杂度是O(nlgn),且在同等复杂度算法中效率是最高的, 本文涉及的排序都采用冒泡排序,只是注明需要排序而已. 贪心算法

【算法导论】贪心算法之活动选择问题

动态规划总是在追求全局最优的解,但是有时候,这样有点费时.贪心算法,在求解过程中,并不追求全局最优解,而是追求每一步的最优,所以贪心算法也不保证一定能够获得全局最优解,但是贪心算法在很多问题却额可以求得最优解. 一.问题概述 活动选择问题: 假定一个有n个活动(activity)的集合S={a1,a2,....,an},这些活动使用同一个资源(例如同一个阶梯教室),而这个资源在某个时刻只能供一个活动使用.每个活动ai都有一个开始时间si和一个结束时间fi,其中0<=si<fi<正无穷.如

贪心算法正确性证明(转载from刘子韬)

这里主要是介绍一种证明贪心算法是最优的一种方法:Exchange Argument (不知道应该怎么翻译到中文,交换参数?感觉听起来挺别扭的,不像是一个方法的名字~o(╯□╰)o) Exchange Argument的主要的思想也就是 先假设 存在一个最优的算法和我们的贪心算法最接近,然后通过交换两个算法里的一个步骤(或元素),得到一个新的最优的算法,同时这个算法比前一个最优算法更接近于我们的贪心算法,从而得到矛盾,原命题成立. 下面来看一个更为formal的解释: 步骤: Step0: 给出贪

POJ1017 Packets(贪心算法训练)

Time Limit: 1000MS          Memory Limit: 10000K          Total Submissions: 51306          Accepted: 17391 Description A factory produces products packed in square packets of the same height h and of the sizes 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. These pro

贪心算法的简述与示例

贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯.能够用贪心算法求解的问题一般具有两个重要特性:贪心选择性质和最优子结构性质. 参考:http://babybandf.blog.163.com/blog/static/61993532010112923767/ [例1]删数问题[B][/B] 试题描

五大常用算法之三贪心算法

贪心算法 贪心算法简介: 贪心算法是指:在每一步求解的步骤中,它要求"贪婪"的选择最佳操作,并希望通过一系列的最优选择,能够产生一个问题的(全局的)最优解. 贪心算法每一步必须满足一下条件: 1.可行的:即它必须满足问题的约束. 2.局部最优:他是当前步骤中所有可行选择中最佳的局部选择. 3.不可取消:即选择一旦做出,在算法的后面步骤就不可改变了. 贪心算法案例: 1.活动选择问题  这是<算法导论>上的例子,也是一个非常经典的问题.有n个需要在同一天使用同一个教室的活动a

零基础学贪心算法

本文在写作过程中参考了大量资料,不能一一列举,还请见谅.贪心算法的定义:贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解.贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关.解题的一般步骤是:1.建立数学模型来描述问题:2.把求解的问题分成若干个子问题:3.对每一子问题求解,得到子问题的局部最优解:4.把子问题的局部最优