贪心算法
是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的[算法]比如在[旅行推销员问题]中,如果旅行员每次都选择最近的城市,那这就是一种贪心算法。
例题1
假设有如下课程表, 你希望讲尽可能多的课程安排在某间教室上.
最好的做法就是:
- 选出结束最早的课,它就是要在这间教室上的第一堂课。
- 接下来,必须选择第一堂课结束后才开始的课。同样,你选择结束最早的课,这将是要在这间教室上的第二堂课。
- 选择 结束最早的课程 , 那么就是 10点结束的 美术
2. 选择 第一堂课结束后才开始的课 并且 结束最早的课程, 那么就是 数学
3. 选择 第二堂课结束后才开始的课程 并且 结束最早的课程 , 那么就是 音乐
- 这样课程久安排好了
贪心算法: 每一步都选择 局部的最优解, 那么 最终得到的就是全局的最优解 (感觉就像哲学里的: 量变引起质变)
例题2
本例子的集合,使用 此文章写好的集合类: 使用Typescript实现集合的操作
假设你办了个广播节目,要让全美50个州的听众都收听得到。为此,你需要决定在哪些广播台播出。在每个广播台播出都需要支付费用,因此你力图在尽可能少的广播台播出。现有广播台名单如下。
- 创建一个 集合(CustomSet)对象, 其中包含需要覆盖的州
let states_needs = new CustomSet(['mt', 'wa', 'or', 'id',
'nv', 'ut', 'ca', 'az'])
- 创建一个可供选择的广播台的对象
const stations : {
[key: string]: any
} = {
"kone": new CustomSet(['id', 'nv', 'ut']),
"ktwo": new CustomSet(['wa', 'id', 'mt']),
"kthree": new CustomSet(['or', 'nv', 'ca']),
"kfour": new CustomSet(['nv', 'ut']),
"kfive": new CustomSet(['ca', 'az']),
}
- 保存最后选择的广播台
const final_stations = new CustomSet()
- 遍历 所有的可供选择的广播台的对象(
stations), 并且与 需要覆盖的州(states_needs),进行交集, 获取尽可能多的州,
let best_station = ''
let states_covered = new CustomSet()
for (const station of Object.keys(stations)) {
const states_for_station: CustomSet<any> = stations[station] // 获取 广播站的 覆盖的州
const coverd = states_needs.intersection(states_for_station) // 需要覆盖的州 与 广播站的 覆盖的州进行交集
const coverd_len = Array.from(coverd.keys()).length
const states_covered_len = Array.from(states_covered.keys()).length
if (coverd_len > states_covered_len) { // 获取 覆盖最高的 广播站
best_station = station
states_covered = coverd
}
}
- 将 选择出来的 广播站 添加到 final_stations, 并且 去掉 states_needs中已经从第4步选择的州
states_needs = states_needs.diff(states_covered)
final_stations.add(best_station)
- 如果
states_needs不为空, 那么 就 从第4第开始循环,直到states_needs为空
该部分的代码: CustomSet 的代码 在 使用Typescript实现集合的操作 提供
const stations : {
[key: string]: any
} = {
"kone": new CustomSet(['id', 'nv', 'ut']),
"ktwo": new CustomSet(['wa', 'id', 'mt']),
"kthree": new CustomSet(['or', 'nv', 'ca']),
"kfour": new CustomSet(['nv', 'ut']),
"kfive": new CustomSet(['ca', 'az']),
}
const final_stations = new CustomSet()
let states_needs = new CustomSet(['mt', 'wa', 'or', 'id',
'nv', 'ut', 'ca', 'az'])
while (Array.from(states_needs.keys()).length) {
let best_station = ''
let states_covered = new CustomSet()
for (const station of Object.keys(stations)) {
const states_for_station: CustomSet<any> = stations[station]
const coverd = states_needs.intersection(states_for_station)
const coverd_len = Array.from(coverd.keys()).length
const states_covered_len = Array.from(states_covered.keys()).length
if (coverd_len > states_covered_len) {
best_station = station
states_covered = coverd
}
}
states_needs = states_needs.diff(states_covered)
final_stations.add(best_station)
}
console.log(final_stations) // CustomSet { set: Set(4) { 'kone', 'ktwo', 'kthree', 'kfive' } }