贪心算法-活动安排问题

来源:互联网 发布:地热模拟软件 编辑:程序博客网 时间:2024/04/30 04:07

贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解,如之前的Dijkstra算法,Prim算法,Kruskal算法。如果不要求绝对最佳答案,那么有时候我们使用简单的贪婪算法生成近似的答案.

贪心与动态规划
贪心算法和动态规划都需求最优子结构,但是贪心算法是自顶向下方式进行,就是每一步,根据策略得到一个当前最优解。传递到下一步,从而保证每一步都是选择当前最优的。最后得到结果.每一步的最优解都依赖上一部的最优解.你只考虑之前已做出的选择
而动态规划通常自底向上解各种子问题,每一步,根据策略得到一个更小规模的问题。最后解决最小规模的问题。得到整个问题最优解.全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解.你考虑的都是以后的子问题
经典的还是背包问题,之前的01背包问题我们采用动态规划解决而不能用贪心.但是如果改成部分背包问题呢:
假如有三件物品,背包可装50磅的物品,物品1重10磅,价值60元;物品2重20磅,价值100元;物品3重30磅,价值120元。你可以选择带走每个物品的全部或一部分,求如何选择可以使背包所装的价值最大?
注意到不同点是我们可以选择带走一部分,所以使用贪心算法十分自然地想到,先算含金量啊,先把含金量最高的都带完,再带含金量其次的…很容易得到解,带走一件1,一件2,2/3件3…比较简单代码不写.

活动安排问题
设有n个活动的集合E = {1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si < fi 。如果选择了活动i,则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当si >= fj或sj >= fi时,活动i与活动j相容.怎么尽可能地安排多的相容活动呢?
设待安排的11个活动的开始时间和结束时间按结束时间的非减序排列如下:
这里写图片描述
注意要按结束时间的早晚排列,没排好的话,你可以回去用各种方法自己排.既然贪心么就是越早结束越好,给后面留尽可能多的空间.其次”目光短浅”,从排列好的里一个个选,能选一个是一个,别管后面的…
显然,我们选择到了(1)1-4,(4)5-7,(8)8-11,(11)12-14
感觉不靠谱么,其实对于这个活动安排问题,贪心算法总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。

代码:

public class MArrange1 {    public static void main(String[] args) {        Scanner scanner=new Scanner(System.in);        int [] start=initArrange(scanner);        int [] end=initArrange(scanner);        int n=start.length;//        shows(start);//        shows(end);        selectSort(start,end,n);        greedyArrange(start,end,n);    }    private static void greedyArrange(int[] start, int[] end, int n) {        List<Integer> end1=new ArrayList<>();        List<Integer> start1=new ArrayList<>();        end1.add(end[0]);        start1.add(start[0]);        int startTime=end[0];//选择的所有活动的最末结束时间        for (int i = 1; i <n ; i++) {            if(start[i]>startTime)            {                end1.add(end[i]);                start1.add(start[i]);                startTime=end[i];            }        }        System.out.println("result:");//输出结果        for(int i:start1)            System.out.print(i+" ");        System.out.println();        for(int i:end1)            System.out.print(i+" ");    }    private static void selectSort(int[] start, int[] end, int n) {        int [] b=new int[n];        for (int i = 0; i <n ; i++) {            b[i]=i;        }        for (int i = 0; i <n-1 ; i++) {            for (int j = i+1; j <n ; j++) {                if(end[j]<end[i])                {                    int temp=end[j];                    end[j]=end[i];                    end[i]=temp;                    int temp1=b[j];                    b[j]=b[i];                    b[i]=temp1;                }            }        }//        shows(end);//        shows(b);        int c[]=new int[n];        for (int i = 0; i <n ; i++) {            c[i]=start[b[i]];        }        start=c;//        shows(start);    }    private static void shows(int[] start) {        for(int i:start)            System.out.print(i+" ");        System.out.println();    }    private static int[] initArrange(Scanner scanner) {        String string=scanner.nextLine();        String [] strings=string.split(",");        int [] temp=new  int[strings.length];        for (int i = 0; i <strings.length ; i++) {            temp[i]=Integer.parseInt(strings[i]);        }        return temp;    }}
0 0
原创粉丝点击