学习日志---贪心算法

贪心算法:

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。
       简单来说就是从一点开始,以每一步最优的方式去寻求最优解,但不保证是全局最优,只保证是每步最优。

例子:

有十一个快件,每个快件有送货的起始时间,要求用最少的车,运送完所有的快件。
快件1:1:00-4:00
快件2:3:00-5:00
快件3:0:00-6:00
快件4:5:00-7:00
快件5:3:00-8:00
快件6:5:00-9:00
快件7:6:00-10:00
快件8:8:00-11:00
快件9:8:00-12:00
快件10:2:00-13:00
快件11:12:00-14:00

实现:

/**
 * 派送货件的小车
 * 
 * @author simoniu
 * 
 */
public class Car {
    private ArrayList<Things> thingsList = new ArrayList<Things>();// 车子一天跑的趟数

    public ArrayList<Things> getThingsList() {
        return thingsList;
    }

    public void setThingsList(ArrayList<Things> thingsList) {
        this.thingsList = thingsList;
    }

    public Integer addThing(Things thing) // 车子跑一趟, 返回跑了多少趟,包括此趟
    {
        thingsList.add(thing);
        return thingsList.size();
    }
}

/**
 * 快件类
 * 
 * @author simoniu
 * 
 */
public class Things {

    // 时间设置为24小时制,从0-23
    private String name; // 邮件的名字
    private Integer startTime; // 一批邮件过来的时间
    private Integer endTime; // 结束时间 (endTime - startTime
                                // 为送完这批快件所需时间,在endTime之前必须送完)

    public Things(Integer startTime, Integer endTime, String name) {
        this.endTime = endTime;
        this.startTime = startTime;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getStartTime() {
        return startTime;
    }

    public void setStartTime(Integer startTime) {
        this.startTime = startTime;
    }

    public Integer getEndTime() {
        return endTime;
    }

    public void setEndTime(Integer endTime) {
        this.endTime = endTime;
    }

}

/**
 * 快速排序 平均时间复杂度nlogn,最多n*n
 * 
 * @author simoniu
 * 
 */
public class Sort {
    public static void SortByendTime(ArrayList<Things> thingsSorted,
            Integer start, Integer end) {
        if (start >= end) // 递归结束的条件
        {
            return;
        }
        Things key = thingsSorted.get(start); // 关键数据
        Integer i = start; // 最左边的游标
        Integer j = end; // 最右边的游标
        while (i < j) {
            while (j > i
                    && thingsSorted.get(j).getEndTime() >= key.getEndTime())// 当后面的值大于key时,不交换,继续向前走
            {
                j--;
            }
            if (j > i) {
                Things t = thingsSorted.get(i);
                thingsSorted.set(i, thingsSorted.get(j));
                thingsSorted.set(j, t);
            }
            while (i < j
                    && thingsSorted.get(i).getEndTime() <= key.getEndTime()) // 当前面的值小于等于key时,不交换,继续向后走
            {
                i++;
            }
            if (i < j) {
                Things t = thingsSorted.get(j);
                thingsSorted.set(j, thingsSorted.get(i));
                thingsSorted.set(i, t);
            }
        }
        SortByendTime(thingsSorted, start, j - 1); // 对前半部分递归
        SortByendTime(thingsSorted, j + 1, end); // 对后半部分递归
    }
}

import java.util.ArrayList;
import java.util.Iterator;

public class GreedyTest {
    public static ArrayList<Car> cars = new ArrayList<Car>();

    public static void main(String[] args) {
        ArrayList<Things> thingsList = new ArrayList<Things>(); // 用来装快件的,无序
        /****** 输入了11批快件 ****/
        Things thing8 = new Things(8, 11, "派件8");
        thingsList.add(thing8);
        Things thing9 = new Things(8, 12, "派件9");
        thingsList.add(thing9);
        Things thing10 = new Things(2, 13, "派件10");
        thingsList.add(thing10);
        Things thing11 = new Things(12, 14, "派件11");
        thingsList.add(thing11);
        Things thing1 = new Things(1, 4, "派件1");
        thingsList.add(thing1);
        Things thing2 = new Things(3, 5, "派件2");
        thingsList.add(thing2);
        Things thing3 = new Things(0, 6, "派件3");
        thingsList.add(thing3);
        Things thing4 = new Things(5, 7, "派件4");
        thingsList.add(thing4);
        Things thing5 = new Things(3, 8, "派件5");
        thingsList.add(thing5);
        Things thing6 = new Things(5, 9, "派件6");
        thingsList.add(thing6);
        Things thing7 = new Things(6, 10, "派件7");
        thingsList.add(thing7);
        /*** 给所有派件按结束时间递增排好序 ***/
        System.out.print("排序前:");
        for (Things t : thingsList) {
            System.out.print(t.getName()+":"+t.getStartTime()+"-"+t.getEndTime() + ",");
        }
        Sort.SortByendTime(thingsList, 0, thingsList.size() - 1); // 排序算法
        System.out.print("\n排序后:");
        for (Things t : thingsList) {
            System.out.print(t.getName()+":"+t.getStartTime()+"-"+t.getEndTime() + ",");
        }
        GreedySelect(thingsList); // 进行贪心算法
        System.out.println("\n最少需要" + cars.size() + "辆车");
        int i = 1;
        for (Car car : cars) {
            System.out.println("第" + i + "辆车装的派件有:");
            for (Things t : car.getThingsList()) {
                System.out.print(t.getName() + ",");
            }
            System.out.println("\n");
            i++;
        }
    }

    //这个是贪婪算法的核心算法
    public static void GreedySelect(ArrayList<Things> thingsList) {
        //新建一个小车
        Car car = new Car();
        //获取该快件的最后时间
        Integer middleTime = thingsList.get(0).getEndTime();
        car.addThing(thingsList.get(0));
        thingsList.remove(0);
        cars.add(car);
        //循环快件的集合
        for (Iterator<Things> t = thingsList.iterator(); t.hasNext();) // 上面注释的for循环和这种迭代方法都行,动态删除容器中的元素
        {
            Things tt = t.next();
            if (middleTime <= tt.getStartTime()) {
                middleTime = tt.getEndTime();
                car.addThing(tt);
                //加到小车后就从几何删除
                t.remove();
            }
        }
        //如果快件集合中还有快件,则继续新建小车运快件
        if (thingsList.size() != 0) // 递归
        {
            GreedySelect(thingsList);
        }
    }
}
时间: 2024-08-24 09:59:31

学习日志---贪心算法的相关文章

经典算法学习之贪心算法

贪心算法也是用来求解最优化问题的,相比较动态规划很多问题使用贪心算法更为简单和高效,但是并不是所有的最优化问题都可以使用贪心算法来解决. 贪心算法就是在每个决策点都做出在当时看来最佳的选择. 贪心算法的设计步骤: 1.将最优化问题转换为:对其做出一次选择之后,只剩下一个问题需要求解的形式(动态规划会留下多个问题需要求解) 2.证明做出贪心选择之后,原问题总是存在最优解,即贪心算法总是安全的 3.证明做出贪心选择后,剩余的子问题满足性质:其最优解与贪心选择组合即可得到原问题的最优解,这样就得到了最

学习日志---Apriori算法发现频繁集

发现dataSet的频繁集: import numpy as np import pandas as pd def loadDataSet():     return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]] #提取数据集中所有的单独数据,参数是数据集 def createC1(dataSet):     C1 = []     for transaction in dataSet:         for item in transaction:

学习日志---knn算法实现

KNN算法实现: 提取文本: import numpy as np //提取文本 def loadDataSet(fileName):     numFeat = len(open(fileName).readline().split(','))     dataMat = []; labelMat = []     fr = open(fileName)     for line in fr.readlines():         lineArr=[]         line = line

学习日志---FP-growth算法发现频繁集

作者:peter harrington,确实牛B!!! 构建FP树,实现频繁集挖掘 class treeNode:     def __init__(self, nameValue, numOccur, parentNode):         self.name = nameValue         self.count = numOccur         self.nodeLink = None         self.parent = parentNode      #needs t

关于贪心算法和动态规划的学习 - 背包问题为例

说到背包问题,我看到了很多分类,不同的类似问题,有不一样的解法,看到的最多的两种方式是贪心算法和动态规划,于我来说,更迫切的应该是要认识一下,这些算法的区别和相同的地方,所以这节就来找资料学习一下贪心算法和动态规划的区别. 这是找到的一个对我帮助最大的,源地址:https://www.cnblogs.com/Renyi-Fan/p/7741089.html 看之前先摘一下这几个解决方案的区别:摘自网上 "所以一个问题,该用递推.贪心.搜索还是动态规划,完全是由这个问题本身阶段间状态的转移方式决定

数据结构与算法学习之路:背包问题的贪心算法和动态规划算法

一.背包问题描述: 有N种物品和一个重量为M的背包,第i种物品的重量是w[i],价值是p[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包重量,且价值总和最大. 二.解决方法: 1.贪心算法:贪心算法基于的思想是每一次选择都作当前最好的选择,这样最后的结果虽然不一定是最优解,但是也不会比最优解差很多. 举个例子说明可能好懂一些:一帮基友去聚餐,菜是一份一份上的,我每一次夹菜都只夹牛肉/海鲜吃,可能到最后我吃的牛肉/海鲜很多,但不一定代表我吃掉的东西的总价值最高,但是相对来说价值也很高

增强学习贪心算法与Softmax算法

(一) 这个算法是基于一个概率来对探索和利用进行折中:每次尝试时,以概率进行探索,即以均匀概率随机选取一个摇臂,以的概率进行利用,即以这个概率选择当前平均奖赏最高的摇臂(如有多个,则随机选取). 其中:小k表示第k个摇臂.因为大K表示摇臂总数:n表示尝试的次数,vn表示第n次尝试的奖赏. Qn的直观意思为:为前n-1次的平均奖赏.当其与n-1相乘所得是前n-1次总奖赏.再加上第n次的奖赏,处于n,则为n次的平均奖赏. 其中:argmax为选取最优的Q(i).count是从0开始的,故count(

算法学习——贪心算法之删数字(求最大值)

算法描述 在给定的n位数字,删除其中的k位数字( k < n),使得最后的n-k为数字为最大值(原次序不变) 算法思路 考虑到是要移出数字,我们使用链表设计此算法较为方便,链表可以直接移出某个位置的元素 使用贪心算法,每一步都要达到最优 从最高位开始,若是下一位比上一位大,则比上一位的数字移出,结束之后再次从最高位开始 例如 16489657 删除4个数字 首先比较1和6 删除1 得到 6489657 之后,再次比较 6和4 往后推 可得到 689657 以此类推 删除4个数字之后 可得到 96

算法学习——贪心算法之删数字(求最小值)

算法描述 在给定的n位数字,删除其中的k位数字( k < n),使得最后的n-k为数字为最小值(原次序不变) 算法思路 考虑到是要移出数字,我们使用链表设计此算法较为方便,链表可以直接移出某个位置的元素 使用贪心算法,每一步都要达到最优 从最高位开始,若下一位比上一位要小,则将上一位的数字移出,结束之后再次从最高位开始 这里需要注意,会有特例 当输入从小到大的的一个数的时候,上述算法将会无法运行,比如123456,删除1个数字变为最小,我们把6删去,这样才是最小的(即从末尾删除数字) 算法实现