JS基础--高级算法--贪心算法

高级算法–贪心算法

贪心算法总是会选择当下的最优解,而不去考虑这一次的选择会不会对未来的选择造成影响,目的是得到当前最优解。

使用贪心算法的经典案例

找零问题

从商店购买了一些商品,找零 63 美分,店员要 怎样给你这些零钱呢?如果店员根据贪心算法来找零的话,他会给你两个 25 美分、一个 10 美分和三个 1 美分。在没有使用 50 美分的情况下这是最少的硬币数量。

function makeChange(origAmt, coins) {
    var remainAmt = 0;

    if (origAmt % .25 < origAmt) {
       coins[3] = parseInt(origAmt / .25);
       remainAmt = origAmt % .25;
       origAmt = remainAmt;
    }

    if (origAmt % .1 < origAmt) {
       coins[2] = parseInt(origAmt / .1);
       remainAmt = origAmt % .1;
       origAmt = remainAmt;
    }

    if (origAmt % .05 < origAmt) {
       coins[1] = parseInt(origAmt / .05);
       remainAmt = origAmt % .05;
       origAmt = remainAmt;
    }

    coins[0] = parseInt(origAmt / .01);
}


function showChange(coins) {
    if (coins[3] > 0) {
        document.write("25 美分的数量 - " + coins[3] + " - " + coins[3] * .25); 
    }

    if (coins[2] > 0) {
        document.write("10 美分的数量 - " + coins[2] + " - " + coins[2] * .10);
    }

    if (coins[1] > 0) {
        document.write("5 美分的数量 - " + coins[1] + " - " + coins[1] * .05);
    }

    if (coins[0] > 0) {
        document.write("1 美分的数量 - " + coins[0] + " - " + coins[0] * .01);
    } 
}

var origAmt = .63;
var coins = [];
makeChange(origAmt, coins);
showChange(coins);

========================
结果如下:

25美分的数量 - 2 - 0.5 
10美分的数量 - 1 - 0.1 
1美分的数量 - 3 - 0.03

makeChange() 函数从面值最高的 25 美分硬币开始,一直尝试使用这个面值去找零。总共 用到的 25 美分硬币数量会存储在 coins 数组中。如果剩余金额不到 25 美分,算法将会尝 试使用 10 美分硬币去找零,用到的 10 美分硬币总总数也会存储在 coins 数组里。接下来 算法会以相同的方式使用 5 美分和 1 美分来找零。

在所有面额都可用且数量不限的情况下,这种方案总能找到最优解。如果某种面额不可用,比如 5 美分,则会得到一个次优解。

背包问题之贪心算法解决方案

如果用贪心算法处理背包问题,它有一个前提放入背包的物品从本质上说是连续的,那 么可以简单地通过物品的单价除以单位体积来确定物品的价值,先装价值最高的物品直到该物品装完或者将背包装满,接着装价值次高的物品,直到 这种物品也装完或将背包装满,以此类推。

思路是

  • (1) 背包的容量为 W,物品的价格为 v,重量为 w。
  • (2) 根据 v/w 的比率对物品排序。
  • (3) 按比率的降序方式来考虑物品。
  • (4) 尽可能多地放入每个物品。

如给出了四个物品的重量、价格和比率

物品 A B C D
价格 50 140 60 60
尺寸 5 20 10 12
比率 10 7 6 5
function ksack(values, weights, capacity) {
    var load = 0;
    var i = 0;
    var w = 0;
    while (load < capacity && i < 4) {
       if (weights[i] <= (capacity-load)) {
          w += values[i];
          load += weights[i];
       } else {
       
          var r = (capacity-load)/weights[i];
          w += r * values[i];
          load += weights[i];
       } 
       ++i;
    }
    return w;
}

var items = ["A", "B", "C", "D"];
var values = [50, 140, 60, 60];
var weights = [5, 20, 10, 12];
var capacity = 30;

document.write(ksack(values, weights, capacity)); // 显示 220