算法图解-Python(第八章:贪婪算法)

题目:

假设你办了个广播节目,要让全美50个州的听众都收听得到。为此,你需要决定在哪些广播台播出。在每个广播台播出都需要支付费用,因此你力图在尽可能少的广播台播出。现有广播台名单如下。

电台-州
每个广播台都覆盖特定的区域,不同广播台的覆盖区域可能重叠。
如何找出覆盖全美50个州的最小广播台集合呢?

贪婪算法解题方法如下(Python):

# 贪婪算法
'''
假如你办了个广播节目,要让全美50个州的听众都收听的到。为此,你需要决定在哪些广播台播出。在每个广播台播出都需要支付费用,因此你力图在尽可能少的广播台播出。
'''
# 如下为A-M13个广播公司,覆盖全部26个地方,目前需要尽可能少的选用其中部分的广播公司进行广播节目来缩小成本


class Greedy_Algrithm:
    # 定义大写字母为广播电台,小写字母为广播电台所覆盖的州。
    Broadcast_List = {
            'A' : {'a','b','c','l','o'},
            'B' : {'c','z','n','d','i'},
            'C' : {'b','l','k','a'},
            'D' : {'m','z','k','j'},
            'E' : {'r','e','s','b','m','z'},
            'F' : {'d','x','c','k'},
            'G' : {'y','t','f','x'},
            'H' : {'g','v','b'},
            'I' : {'n','u','h','v'},
            'J' : {'k','o','p','h'},
            'K' : {'w','m','l'},
            'L' : {'q','f','h'},
            'M' : {'z','a','v'}
        }
    
    def getTheAns(self, cover_needed:set):
        #cover_needed = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
        # 定义最终找到的所有局部最优解组成的集合(函数体内的变量)
        final_station = set()
        while cover_needed:
            best_station = None # 循环一轮找到的最优解
            state_coverd = set() # 定义每轮循环中最优解覆盖的州,最终取需要覆盖的州与该集合的差集
            for station, states in self.Broadcast_List.items():
                if station in final_station:
                    continue
                coverd = cover_needed&states # 遍历电台,得到当前遍历的电台覆盖的州
                if len(coverd) > len(state_coverd): # 与已经遍历过得电台中覆盖州数最多的电台所覆盖的州进行对比,若此时的电台能覆盖更多的州,则替换当前的州为当前的局部最优解
                    best_station = station
                    state_coverd = coverd
            cover_needed -= state_coverd # 每轮遍历后需要更新需要覆盖的州
            final_station.add(best_station) # 将当前的最优解添加到结果集合中
        return final_station # 最终返回得到的最优解集合

test_set = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
print(Greedy_Algrithm.getTheAns(Greedy_Algrithm, test_set))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值