탐욕 알고리즘에 대한 기사

계속 만들고 성장을 가속화하십시오! "너겟 데일리 뉴플랜 · 6월 업데이트 챌린지" 참여 2일차 입니다 . 이벤트 상세보기 클릭

소개

인간은 태생적으로 선하지만 자신의 경험, 생활 환경 및 기타 요인의 영향으로 점차 탐욕, 미움, 망상이 발달합니다. 사실 사람에게도 욕심이 있는 것이 아니라 우리의 알고리즘에도 욕심이 있기 마련인데, 오늘은 욕심이 있는 다음 알고리즘 모델인 욕심이 생기는 알고리즘을 소개하여 알고리즘이 욕심을 어떻게 낳는지 알아보도록 하겠습니다.

탐욕 알고리즘이란

문제를 분석하고 해결할 때 각 단계의 계산 선택이 최적 또는 최선이며, 이러한 방식으로 최종 계산 결과가 최적이 될 것으로 기대됩니다. 즉, 알고리즘은 먼저 국소 최적해를 구함으로써 전체 최적해를 구한다.

탐욕 알고리즘의 기본 단계:

1. 먼저 문제를 정의하고 문제 모델이 greedy 알고리즘을 사용하는 데, 즉 최대값 문제를 해결하는 데 적합한지 여부를 결정합니다.

2. 극단값을 찾는 문제를 분해하고, 분해 후 각 하위 문제를 해결하여 현재 하위 문제의 로컬 최적 솔루션을 얻으려고 시도합니다.

3. 모든 하위 문제의 로컬 최적 솔루션이 해결된 후 이러한 로컬 최적 솔루션을 집계 및 병합하여 최종 글로벌 최적 솔루션을 얻으면 이 최적 솔루션이 전체 문제의 최적 솔루션입니다.

이미지.png

장면 이해 알고리즘을 통해

개념적 알고리즘 설명은 모든 사람이 잘 이해하지 못할 수 있으므로 일부 실제 시나리오와 함께 설명해야 합니다. 여기에서 우리는 어린 시절에 변화를 발견하는 예를 들어보겠습니다. 지금은 모두가 휴대폰으로 스캔하고 결제하지만, 돈을 만진 지 오랜 시간이 흘렀지만 변화의 문제를 방해하지 않아 욕심 많은 알고리즘의 구현 과정을 이해하는 데 도움이 될 수 있습니다.

당신이 작은 소매점의 주인이고 1위안, 3위안, 5위안과 같은 다양한 액면가의 거스름돈이 있다고 가정합니다. 이때 한 아이가 물건을 사러 와서 주머니에 들어갈 수 있도록 가장 적은 양의 거스름돈을 찾아달라고 했습니다. 변화를 c[0], c[1], c[2]... 로 기록하고 아이들이 간식을 사는 데 사용하는 돈을 총계로 기록한다고 가정합니다. 그런 다음 우리는 어린이가 최소한의 변경을 원한다고 언급했습니다. 최적의 솔루션을 찾기 위해 프로그래밍 문제로 변환할 수 있습니다. 주어진 총계와 같아야 합니다.

예 1:

찾을 변경 사항이 11이고 현재 변경 사항이 1, 3, 5라고 가정합니다.

입력: 총계=11, c[0]=1, c[1]=3, c[2]=5

출력: 3

문제 분석

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

이미지.png

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

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

이미지.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也是满足条件的,但是上述代码却没有找到。

그래서 위 코드에는 여전히 문제가 있습니다.핵심 포인트는 1위안 변경이 없음을 발견했을 때 다시 돌아가서 두 번째 단계에서 5위안 변경을 3위안 변경으로 변경할 수 있는지 확인해야 한다는 것입니다. 그런 다음 후속 반복을 수행합니다.이러한 단계를 수행하면 5,3,3과 같은 조합을 찾을 수 있습니다.

이미지.png

요약 이 글에서는 탐욕 알고리즘의 구체적인 구현 과정을 화폐를 바꾸는 실제 사례와 결합하여 탐욕 알고리즘에 대한 설명을 통해 주로 분석한다. 동시에 greedy 알고리즘의 단점, 즉 국부 최적성의 함정에 빠지기 쉽고 스스로 빠져나오지 못하여 조건을 만족하는 최종 결과를 얻을 수 없다는 단점을 분석한다.


만들기가 쉽지 않습니다 글이 나쁘지 않다고 생각되시면 좋아요+좋아요+댓글로 교환해주세요. 여느 때와 같이 기사 말미에 시를 공유하겠습니다.

Ding Fengbo·왕딩궈의 수행원 Yu Niang에게 남중국해 반환

창은 세상 Zhuo Yulang을 부러워하고 신들은 구걸하고 케이크를 주문해야 합니다. 칭거가 하얀 이빨을 넘겼지만 바람이 거세게 불어 눈이 휘날리며 불바다가 시원해졌다.

수천 마일에서 돌아와서 얼굴은 점점 작아지고 미소는 여전히 Lingmei의 향기로 가득합니다. 그는 링난이 좋은지 물었지만 그는 이렇게 말했습니다.

рекомендация

отjuejin.im/post/7102976328516763679