Жадібний алгоритм із прикладом: що таке, метод і підхід

Що таке жадібний алгоритм?

In Жадібний алгоритм набір ресурсів рекурсивно поділяється на основі максимальної, негайної доступності цього ресурсу на будь-якій даній стадії виконання.

Для вирішення проблеми, заснованої на жадібному підході, є два етапи

  1. Сканування списку предметів
  2. Оптимізація

Ці етапи розглядаються паралельно в цьому підручнику з алгоритму Greedy під час поділу масиву.

Щоб зрозуміти жадібний підхід, вам потрібно мати практичні знання про рекурсію та перемикання контексту. Це допоможе вам зрозуміти, як відстежити код. Ви можете визначити жадібну парадигму в термінах ваших власних необхідних і достатніх тверджень.

Парадигму жадібності визначають дві умови.

  • Кожне поетапне рішення має структурувати проблему в напрямку її найкраще прийнятного рішення.
  • Досить, якщо структурування проблеми може зупинитися на кінцевій кількості жадібних кроків.

Продовжуючи теоретизування, давайте опишемо історію, пов’язану з підходом Greedy Search.

Історія Greedy Algorithms

Ось важливий орієнтир жадібних алгоритмів:

  • Жадібні алгоритми були розроблені для багатьох алгоритмів блукання по графу в 1950-х роках.
  • Есджер Джікстра концептуалізував алгоритм для створення мінімальних остовних дерев. Він мав на меті скоротити проміжок маршрутів у столиці Нідерландів Амстердамі.
  • У тому ж десятилітті Прім і Крускал розробили стратегії оптимізації, які ґрунтувалися на мінімізації вартості шляху уздовж зважених маршрутів.
  • У 70-х роках американські дослідники Кормен, Рівест і Стайн запропонували рекурсивну підструктуру жадібних рішень у своїй класичній книзі «Вступ до алгоритмів».
  • Парадигма жадібного пошуку була зареєстрована як інший тип стратегії оптимізації в записах NIST у 2005 році.
  • До теперішнього часу протоколи, які запускають Інтернет, такі як відкритий найкоротший шлях спочатку (OSPF) і багато інших мережевих протоколів комутації пакетів, використовують жадібну стратегію для мінімізації часу, проведеного в мережі.

Жадібні стратегії та рішення

Логіка в її найлегшій формі зводилася до «жадібних» або «не жадібних». Ці твердження були визначені підходом, використаним для просування на кожному етапі алгоритму.

Наприклад, алгоритм Djikstra використовував покрокову жадібну стратегію ідентифікації хостів в Інтернеті шляхом обчислення функції вартості. Значення, яке повертає функція вартості, визначає, чи є наступний шлях «жадібним» чи «нежадібним».

Коротше кажучи, алгоритм перестає бути жадібним, якщо на будь-якому етапі він робить крок, який не є локально жадібним. Жадібні проблеми припиняються без подальшого прояву жадібності.

Характеристики жадібного алгоритму

Важливими характеристиками жадібного алгоритму є:

  • Існує впорядкований список ресурсів із розподілом витрат або цінностей. Вони кількісно визначають обмеження системи.
  • Ви отримаєте максимальну кількість ресурсів протягом часу, на який діє обмеження.
  • Наприклад, у задачі планування діяльності витрати на ресурси вказані в годинах, і дії потрібно виконувати в послідовному порядку.

Характеристики жадібного алгоритму

Навіщо використовувати жадібний підхід?

Ось причини використання жадібного підходу:

  • Жадібний підхід має кілька компромісів, які можуть зробити його придатним для оптимізації.
  • Однією з важливих причин є негайне досягнення найбільш прийнятного рішення. У задачі вибору діяльності (пояснення нижче), якщо до завершення поточної дії можна виконати більше дій, ці дії можна виконати протягом того самого часу.
  • Інша причина полягає в тому, щоб рекурсивно розділити задачу на основі умови, без необхідності комбінувати всі рішення.
  • У задачі вибору діяльності крок «рекурсивного поділу» досягається шляхом сканування списку елементів лише один раз і врахування певних дій.

Як вирішити проблему вибору діяльності

У прикладі планування діяльності для кожної дії є час «початку» та «закінчення». Кожна діяльність індексується номером для довідки. Є дві категорії діяльності.

  1. розглянута діяльність: це Діяльність, яка є посиланням, за яким аналізується здатність виконувати більше ніж одну дію, що залишилася.
  2. решта діяльності: діяльності на один або більше індексів, випереджаючи розглянуту діяльність.

Загальна тривалість дає вартість виконання діяльності. Тобто (фініш – початок) дає нам тривалість як вартість діяльності.

Ви дізнаєтесь, що жадібний екстент — це кількість дій, які ви можете виконати за час розглядуваної діяльності.

Archiструктура підходу Greedy

КРОК 1) Проскануйте список витрат на діяльність, починаючи з індексу 0 як розглянутого Індексу.

КРОК 2) Коли більше дій можна буде завершити до того часу, розглянута діяльність завершиться, почніть пошук однієї або кількох дій, що залишилися.

КРОК 3) Якщо дій, що залишилися, більше немає, поточна діяльність, що залишилася, стає наступною. Повторіть крок 1 і крок 2 з новою розглянутою діяльністю. Якщо не залишилося жодних дій, перейдіть до кроку 4.

КРОК 4) Повернути об'єднання розглянутих індексів. Це індекси активності, які будуть використовуватися для максимізації пропускної здатності.

Archiтектура жадібного підходу
Archiтектура жадібного підходу

Пояснення коду

#include<iostream>
#include<stdio.h>
#include<stdlib.h>

#define MAX_ACTIVITIES 12

Archiтектура жадібного підходу

Пояснення коду:

  1. Включені файли заголовків/класи
  2. Максимальна кількість дій, які надає користувач.
using namespace std;

class TIME
{
    public:
    int hours;

    public: TIME()
    {
   	 hours = 0;
    }
};

Archiтектура жадібного підходу

Пояснення коду:

  1. Простір імен для потокових операцій.
  2. Визначення класу для TIME
  3. Часова позначка години.
  4. Конструктор TIME за замовчуванням
  5. Години змінні.
class Activity
{
    public:
    int index;
    TIME start;
    TIME finish;

    public: Activity()
    {
   	 start = finish = TIME();
    }
};

Archiтектура жадібного підходу

Пояснення коду:

  1. Визначення класу з діяльності
  2. Мітки часу, що визначають тривалість
  3. Усі мітки часу ініціалізуються нулем у конструкторі за замовчуванням
class Scheduler
{
    public:
    int considered_index,init_index;
    Activity *current_activities = new    Activity[MAX_ACTIVITIES];
    Activity *scheduled;

Archiтектура жадібного підходу

Пояснення коду:

  1. Частина 1 визначення класу планувальника.
  2. Розглянутий індекс є відправною точкою для сканування масив.
  3. Індекс ініціалізації використовується для призначення випадкових позначок часу.
  4. Масив об’єктів діяльності динамічно розподіляється за допомогою оператора new.
  5. Запланований покажчик визначає поточне базове розташування для greed.
Scheduler()
{
   	 considered_index = 0;
   	 scheduled = NULL;
...
...

Archiтектура жадібного підходу

Пояснення коду:

  1. Конструктор планувальника – частина 2 визначення класу планувальника.
  2. Розглянутий індекс визначає поточний початок поточного сканування.
  3. Поточний greedy екстент не визначений на початку.
for(init_index = 0; init_index < MAX_ACTIVITIES; init_index++)
 {
   		 current_activities[init_index].start.hours =
   			 rand() % 12;

   		 current_activities[init_index].finish.hours =
   			 current_activities[init_index].start.hours +
   				 (rand() % 2);

   		 printf("\nSTART:%d END %d\n",
   		 current_activities[init_index].start.hours
   		 ,current_activities[init_index].finish.hours);
 }
…
…

Archiтектура жадібного підходу

Пояснення коду:

  1. Цикл for для ініціалізації годин початку та годин завершення кожної із запланованих на даний момент дій.
  2. Ініціалізація часу початку.
  3. Ініціалізація часу завершення завжди після або точно в годину початку.
  4. Оператор налагодження для друку виділених тривалостей.
	public:
   		 Activity * activity_select(int);
};

Archiтектура жадібного підходу

Пояснення коду:

  1. Частина 4 – остання частина визначення класу планувальника.
  2. Функція вибору активності бере за основу індекс початкової точки та розділяє жадібний квест на жадібні підпроблеми.
Activity * Scheduler :: activity_select(int considered_index)
{
    this->considered_index = considered_index;
    int greedy_extent = this->considered_index + 1;
…
… 

Archiтектура жадібного підходу

  1. За допомогою оператора дозволу області (::) надається визначення функції.
  2. Розглянутий Індекс є Індексом, який називається за значенням. Greedy_extent — це ініціалізований лише індекс після розглянутого індексу.
Activity * Scheduler :: activity_select(int considered_index)
{
    	while( (greedy_extent < MAX_ACTIVITIES ) &&
   	 ((this->current_activities[greedy_extent]).start.hours <
   		 (this->current_activities[considered_index]).finish.hours ))
    	{
   	 printf("\nSchedule start:%d \nfinish%d\n activity:%d\n",
   	 (this->current_activities[greedy_extent]).start.hours,
   	 (this->current_activities[greedy_extent]).finish.hours,
   	 greedy_extent + 1);
   	 greedy_extent++;
    	}
…
...

Archiтектура жадібного підходу

Пояснення коду:

  1. Основна логіка – жадібність обмежена кількістю видів діяльності.
  2. Початкові години поточної дії перевіряються як заплановані перед тим, як розглядувана діяльність (зазначена розглянутим індексом) завершиться.
  3. Поки це можливо, друкується необов’язковий оператор налагодження.
  4. Перехід до наступного індексу в масиві активності
...
if ( greedy_extent <= MAX_ACTIVITIES )
    {

   	 return activity_select(greedy_extent);
    }
    else
    {
   	 return NULL;
    }
}

Archiтектура жадібного підходу

Пояснення коду:

  1. Умовна функція перевіряє, чи виконано всі дії.
  2. Якщо ні, ви можете перезапустити greedy з розглянутим індексом як поточною точкою. Це рекурсивний крок, який жадібно розділяє формулювання проблеми.
  3. Якщо так, він повертається до абонента без можливості для розширення жадібності.
int main()
{
    Scheduler *activity_sched = new Scheduler();
    activity_sched->scheduled = activity_sched->activity_select(
   				activity_sched->considered_index);
    return 0;
}

Archiтектура жадібного підходу

Пояснення коду:

  1. Основна функція, яка використовується для виклику планувальника.
  2. Створено новий планувальник.
  3. Функція вибору активності, яка повертає покажчик типу активності, повертається до абонента після завершення жадібного квесту.

вихід:

START:7 END 7

START:9 END 10

START:5 END 6

START:10 END 10

START:9 END 10

Schedule start:5 
finish6
 activity:3

Schedule start:9 
finish10
 activity:5

Обмеження жадібної техніки

Він не підходить для жадібних проблем, де потрібне рішення для кожної підпроблеми, наприклад сортування.

У таких практичних задачах алгоритму Greedy метод Greedy може бути неправильним; у гіршому випадку навіть призведе до неоптимального рішення.

Тому недолік жадібних алгоритмів полягає в тому, що вони не знають, що попереду поточного жадібного стану.

Нижче наведено опис недоліків методу Greedy:

Обмеження жадібної техніки

У жадібному скануванні, показаному тут у вигляді дерева (вище значення, вище жадібність), стан алгоритму зі значенням: 40, ймовірно, прийме 29 як наступне значення. Крім того, його квест закінчується на 12. Це становить значення 41.

Однак, якщо алгоритм вибрав неоптимальний шлях або прийняв стратегію перемоги. тоді за 25 слідуватиме 40, а загальне покращення витрат становитиме 65, що оцінюється на 24 бали вище як неоптимальне рішення.

Приклади Greedy Algorithms

Більшість мережевих алгоритмів використовують жадібний підхід. Ось список кількох прикладів алгоритму Greedy:

  • Алгоритм мінімального остовного дерева Прима
  • Проблема продавця подорожі
  • Графік – розфарбовування карти
  • Алгоритм мінімального остовного дерева Крускала
  • Алгоритм мінімального остовного дерева Дейкстри
  • Граф – Вершинне покриття
  • Проблема з ранцем
  • Проблема планування роботи

Підсумки

Підводячи підсумок, у статті було визначено жадібну парадигму, показано, як жадібна оптимізація та рекурсія можуть допомогти вам отримати найкраще рішення до певної точки. Алгоритм Greedy широко використовується для вирішення проблем у багатьох мовах як алгоритм Greedy Python, C, C#, PHP, Javaі т.д. Вибір активності прикладу алгоритму Greedy описано як стратегічна проблема, яка може досягти максимальної пропускної здатності за допомогою жадібного підходу. Зрештою, були пояснені недоліки використання жадібного підходу.