Un artículo sobre el algoritmo codicioso

¡Continúe creando, acelere el crecimiento! Este es el segundo día de mi participación en el "Nuggets Daily New Plan · June Update Challenge", haz clic para ver los detalles del evento

Introducción

Los seres humanos son intrínsecamente buenos al principio, pero con la influencia de su propia experiencia, el entorno de vida y otros factores, las personas desarrollarán gradualmente la codicia, el odio y la ilusión. De hecho, no solo las personas tienen codicia, sino que nuestros algoritmos también tendrán codicia.Hoy, presentaré el siguiente modelo de algoritmo con codicia, el algoritmo codicioso, para ver cómo un algoritmo genera codicia.

¿Qué es el algoritmo codicioso?

Al analizar y resolver un problema, las opciones de cálculo de cada paso son óptimas o las mejores, y de esta manera, se espera que el resultado final del cálculo sea óptimo. Es decir, el algoritmo busca la solución óptima general buscando primero la solución óptima local.

Los pasos básicos del algoritmo codicioso:

1. Primero defina el problema y determine si el modelo del problema es adecuado para usar el algoritmo codicioso, es decir, para resolver el problema de valor máximo;

2. Desmonte el problema de encontrar el valor extremo y luego resuelva cada subproblema después del desmontaje, tratando de obtener la solución óptima local del subproblema actual;

3. Después de resolver las soluciones óptimas locales de todos los subproblemas, estas soluciones óptimas locales se agregan y fusionan para obtener la solución óptima global final, luego esta solución óptima es la solución óptima de todo el problema.

imagen.png

a través de algoritmos de comprensión de escenas

Es posible que no todos entiendan bien la descripción del algoritmo conceptual, por lo que debe explicarse en combinación con algunos escenarios reales. Aquí tomamos el ejemplo de encontrar cambios en nuestra infancia para intervenir. Aunque ahora todos escanean y pagan con teléfonos móviles, hace mucho tiempo que no tocan dinero, pero eso no impide el problema del cambio, lo que puede ayudarnos a comprender el proceso de implementación del algoritmo codicioso.

Suponga que usted es el propietario de una pequeña tienda minorista y tiene cambio en varias denominaciones, como 1 yuan, 3 yuan y 5 yuan. En ese momento, un niño vino a comprar algo, y te pidió que buscaras la menor cantidad de cambio, para que le cupiera en el bolsillo. Supongamos que registramos el cambio como c[0], c[1], c[2]... , y el dinero que usan los niños para comprar refrigerios se registra como total. Luego acabamos de mencionar que el niño quiere obtener la menor cantidad de cambio, podemos convertirlo en un problema de programación para encontrar la solución óptima, es decir, dado el número total, la solución requiere la suma del número mínimo de c ser igual al total dado total.

Ejemplo 1:

Suponga que el cambio a encontrar es 11 y el cambio actual es 1, 3 y 5.

Entrada: total=11, c[0]=1, c[1]=3, c[2]=5

salida: 3

análisis del problema

通过提取问题中的关键词“最少”,我们可以明确此问题的实际上就是一个求解最值的问题,只要找到满足条件的最小零钱张数就可以解决找回最少零钱的问题了。想要找到最小的零钱张数,我们最先想到的方法就是进行穷举,列举出来所有可能的满足总数为11的零钱组合。如下图所示,再在这些组合中找到使用零钱张数最少的组合再计算具体的张数,我们就可以获得最终的答案了。但是这显然不是一个好的解决思路。因为如果对应的total很大,我们穷举的结果将会爆发性增长。

imagen.png

那有没有更好的解决办法呢?这时候我们就可以考虑下贪心算法的实现了,找到满足要求的最小张数零钱。既然是找零钱,那么我们可以将问题转换为找到满足总数total的零钱最少需要几个步骤,实际上就是将问题拆分到每次找零钱的小步骤中,而贪心算法的核心就是需要在每个小步骤中贪心寻求局部最优解。因此在找零钱的每个步骤中,都需要找到该步骤中对应的最优解零钱大小,接下来我们来一起看下贪心算法执行过程。这里假设各个面值的零钱比较充足。

在寻找零钱的步骤中,首先获取最大面值为5的零钱(贪心,上来就找最大的),接着发现剩余待找零钱6=11-5,于是继续寻找最大的面值为5的零钱(继续贪心),待找零钱1=6-5。此时只要获取面值为1的零钱就可以完成任务了,再将之前步骤中的结果整合到一起,最终我们得出想要获取total为11的最少张数零钱的大小为3。通过这样的分析,贪心算法是不是也没有那么的复杂。

imagen.png

对应的代码实现如下所示:

 
/**
 * @Author: mufeng
 * @Date: 2022/5/15 15:33
 * @Version: V 1.0.0
 * @Description: 计算最小满足条件的零钱张数
 */
public class MinChangeCountSolution {
 
    public static void main(String[] args) {
        int values[] = {5,5,3,3,1};
        System.out.println(getMinChangeCount(11, values));
 
    }
 
    //假设values数组从大到小排列
    static int getMinChangeCount(int total, int[] values) {
        int rest = total;
        int result = 0;
        int count = values.length;
 
        // 从大到小遍历所有面值
        for (int i = 0; i < count; ++ i) {
            //计算需要几张这种面值的零钱
            int needCount = rest / values[i];
            //计算使用后的余额
            rest -= needCount * values[i];
            //计数增加
            result += needCount;
 
            if (rest == 0) {
                return result;
            }
        }
        //没有找到合适的面值
        return -1;
    }
 
}
复制代码

以上我们分析了贪心算法的大致实现过程,但是实际上还是有问题的。不知道大家有没有发现,由于贪心算法过于贪心,每一个步骤都想要找到局部最优解。那么假如在上面的例子中,我们没有1块钱的零钱,上述代码的返回结果是-1,即没有符合条件的答案。但是实际并非如此,也就是说5,3,3也是满足条件的,但是上述代码却没有找到。

Entonces, todavía hay un problema con el código anterior. El punto clave es que cuando descubre que no hay un cambio de 1 yuan, debe volver atrás y ver si puede cambiar el cambio de 5 yuanes en el segundo paso a un cambio de 3 yuanes. y luego llevar a cabo iteraciones posteriores Tales pasos, luego puede encontrar combinaciones como 5,3,3.

imagen.png

Resumen Este artículo analiza principalmente el proceso de implementación específico del algoritmo voraz a través de la descripción del algoritmo voraz, combinado con el ejemplo real de cambiar dinero. Al mismo tiempo, se analizan las deficiencias del algoritmo voraz, es decir, es fácil caer en la trampa de la optimización local y no puede salir, lo que da como resultado que no se pueda dar el resultado final que satisface las condiciones.


No es fácil de crear. Si cree que el artículo no es malo, haga clic en Me gusta + favorito + comentario para intercambiar. Como de costumbre, al final del artículo, compartiré un poema contigo.

Ding Fengbo · El regreso del Mar de China Meridional al asistente de Wang Dingguo, Yu Niang

Chang envidia el mundo Zhuo Yulang, los dioses deben rogar y pedir pasteles. Aunque el Qingge pasó sobre los dientes blancos, el viento se levantó, la nieve voló y el mar de llamas se enfrió.

Al regresar de miles de millas, la cara es cada vez menos y la sonrisa todavía tiene la fragancia de Lingmei. Preguntó si Lingnan debería ser bueno, pero dijo: Este lugar de paz mental es mi ciudad natal.

Supongo que te gusta

Origin juejin.im/post/7102976328516763679
Recomendado
Clasificación