算法学习笔记(一)——贪心算法

  贪心算法

在对问题求解时,总是做出在当前看来是最好的选择,即不从整体最优上考虑问题,而是从局部做出最优解

 

因此,贪心算法不能够对所有问题得到最优解,选择的贪心策略必须具备无后效性,即某个状态之后的过程不会影响到以前的状态,而只与当前的状态有关

 

基本思路:1、建立数学模型描述问题;

                   2、把求解的问题分成若干子问题

                   3、把对每一个子问题求解,得到子问题的局部最优解

                   4、把子问题的局部最优解合成为原来问题的一个解

 

例子,最短路径问题

从 u 到 v 的最短路径权值,小于等于从 u 到 x 的最短路径权值加上从 x 到 v 的最短路径权值,即

# 图解算法——dijkstra算法

def find_lowest_cost_node(costs):
    lowest_cost = float('inf')
    lowest_cost_node = None
    for node in costs:
        cost = costs[node]
        if cost < lowest_cost and node not in processed:
            lowest_cost = cost
            lowest_cost_node = node
    return lowest_cost_node

graph = {}
graph['start'] = {}
graph['start']['a'] = 6
graph['start']['b'] = 2
graph['a'] = {}
graph['a']['fin'] = 1
graph['b'] = {}
graph['b']['a'] = 3
graph['b']['fin'] = 5
graph['fin'] = {}

infinity = float('inf')
costs = {}
costs['a'] = 6
costs['b'] = 2
costs['fin'] = infinity

parents = {}
parents['a'] = 'start'
parents['b'] = 'start'
parents['fin'] = None

processed = []

node = find_lowest_cost_node(costs)       # 在未处理的节点中,寻找开销最小的节点
while node is not None:
    cost = costs[node]
    neighbors = graph[node]
    for n in neighbors.keys():           # 遍历当前节点的所有邻居
        new_cost = cost + neighbors[n]
        if costs[n] > new_cost:        # 如果经当前节点前往该邻居更近,则更新
            costs[n] = new_cost
            parents[n] = node          # 同时更新父节点
    processed.append(node)             # 将当前节点标记为处理过
    node = find_lowest_cost_node(costs)  # 寻找下一个要处理的节点

print(costs)

例子,集合覆盖问题,这个例子来自《算法图解》一书

其背景是,不同的广播台可以在不同的州广播,如何选择最优或者次优的广播台集合使得可以覆盖所有的州

# 算法图解——集合覆盖问题

arr = ['mt','wa','or','id','nv','ut','ca','az']
states_needed = set(arr)
# 集合类似列表,但是同样的元素只能出现一次

stations = {}
stations['kone'] = set(['id','nv','ut'])
stations['ktwo'] = set(['wa','id','mt'])
stations['kthree'] = set(['or','nv','ca'])
stations['kfour'] = set(['nv','ut'])
stations['kfive'] = set(['ca','az'])

final_stations = set()

while states_needed:           # 不断循环,直到states_needed为空
    best_station = None        # 选择的广播台
    states_covered = set()     # 广播台覆盖的州
    for station, states_for_station in stations.items():
        covered = states_needed & states_for_station  # 交集
        if len(covered) > len(states_covered):
            best_station = station
            states_covered = covered
    states_needed -= states_covered      # 因为不需要重复覆盖,所以要更新
    final_stations.add(best_station)

print(final_stations)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值