You are on page 1of 71

ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Техники за креирање
алгоритми

Алгоритми и податочни структури


Аудиториска вежба 3
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Архетипи на алгоритми
• Архетипите на алгоритми се однесуваат на
одредена категорија на проблеми и опишуваат
стратегија за решавање на главниот проблем за
таа категорија
• За даден проблем, може да постојат неколку
стратегии за негово решавање
• Добар програмер е оној кој знае добро да го
проучи проблемот што треба да се реши и кој
знае да препознае која алгоритамска техника е
најсоодветна за да се примени
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Архетипи на алгоритми
• Техники на груба сила
• Алчни алгоритми
• Раздели и владеј
• Динамичко програмирање
• Алгоритми кои се враќаат наназад од резултатот
• Алгоритми со случајни броеви

3
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Техника на груба сила (brute force)


• Техниката на груба сила го решава проблемот на
наједноставниот, најдиректниот или
најочигледниот начин
• Како резултат, на ваков тип на алгоритам му треба
многу повеќе работа за да реши одреден проблем
од некој попаметен или пософистициран
алгоритам
• Од друга страна, алгоритмите базирани на груба
сила често се поедноставни за имплементација
отколку пософистицираните
• Се разгледуваат сите можности

4
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 1
• Дадени се N точки (N >= 2) во дводимензионален
простор. Пресметајте кое е најмалото растојание
помеѓу две точки.

5
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 1 - Java
class Point {
double x;
double y;

Point(double x, double y) {
this.x = x;
this.y = y;
}
}

class BruteForce {
int INF = 1000000;

double min(double a, double b) {


if (a < b) {
return a;
} else {
return b;
}
}

6
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 1 - Java
double rastojanie(Point a, Point b) {
return Math.sqrt((a.x - b.x) * (a.x - b.x) +
(a.y - b.y) * (a.y - b.y));
}

double najmalo_rastojanie(Point p[], int n) {


int i, j;
double best = INF;

for (i = 0; i < (n - 1); i++) {


for (j = i + 1; j < n; j++) {
best = Math.min(best, rastojanie(p[i], p[j]));
}
}

return best;
}
}

7
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 1 - C
#include<stdio.h>
#include<math.h>
#define INF 1000000.0

typedef struct {
double x;
double y;
} Point;

double min(double a, double b) {


if (a < b)
return a;
else
return b;
}

double rastojanie(Point a, Point b) {


return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
8
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 1 - C
double najmalo_rastojanie(Point p[], int n) {
int i,j;
double tmp;
double best = INF;

for (i=0;i<(n-1);i++)
for (j=i+1;j<n;j++)
best = min(best, rastojanie(p[i], p[j]));

return best;
}

9
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 2
• Дадена е шаховска табла. Пресметајте на колку
различни начини можат да се постават две
“кралици” без да се напаѓаат една со друга. Две
“кралици” се напаѓаат ако се наоѓаат во ист ред,
колона или дијагонала.

10
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 2 - Java
class BruteForce {

int dali_se_napagaat(int i1, int j1, int i2, int j2) {


if (i1 == i2) // ista redica
return 1;
if (j1 == j2) // ista kolona
return 1;
if (Math.abs(i1 - i2) == Math.abs(j1 - j2)) // ista dijagonala
return 1;
return 0;
}

11
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 2 - Java
int broj_na_nacini() {
int i1, j1, i2, j2;
int rezultat = 0;

for (i1 = 0; i1 < 8; i1++) {


for (j1 = 0; j1 < 8; j1++) {
for (i2 = 0; i2 < 8; i2++) {
for (j2 = 0; j2 < 8; j2++) {
if (dali_se_napagaat(i1, j1, i2, j2) == 0) {
rezultat++;
}
}
}
}
}

return rezultat;
}
}

12
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 2 - C
int abs(int a) {
if (a < 0)
return -a;
return a;
}

int dali_se_napagaat(int i1, int j1, int i2, int j2) {


if (i1 == i2) // ista redica
return 1;
if (j1 == j2) // ista kolona
return 1;
if (abs(i1-i2) == abs(j1-j2)) // ista dijagonala
return 1;
return 0;
}

13
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 2 - C
int broj_na_nacini() {
int i1,j1,i2,j2;
int rezultat = 0;

for (i1=0;i1<8;i1++)
for (j1=0;j1<8;j1++)
for (i2=0;i2<8;i2++)
for (j2=0;j2<8;j2++)
if (dali_se_napagaat(i1, j1, i2, j2)==0)
rezultat++;

return rezultat;
}

14
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 3
• Дадени се парички со одредена вредност
(постојат парички од 50, 10, 5, 2 и 1 денар), и
притоа бројот на парички од секоја вредност е
неограничен. За дадена сума да се определи
најмалиот број на парички кои се потребни да се
формира таа сума.

15
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 3 - Java
class BruteForce {
int min_broj_moneti(int suma) {
int m1,m2,m3,m4,m5,tmp, rezultat = 1000000, br_paricki;
for (m1 = 0; m1 <= (suma / 50); m1++)
for (m2 = 0; m2 <= (suma / 10); m2++)
for (m3 = 0; m3 <= (suma / 5); m3++)
for (m4 = 0; m4 <= (suma / 2); m4++)
for (m5 = 0; m5 <= (suma / 1); m5++) {
tmp = m1*50+m2*10+m3*5+m4*2+m5*1;
if (tmp == suma) {
br_paricki = m1 + m2 + m3 + m4 + m5;
if (br_paricki < rezultat)
rezultat = br_paricki;
}
}

return rezultat;
}
}
16
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 3 - C
int min_broj_moneti(int suma) {
int m1,m2,m3,m4,m5,tmp, rezultat = 1000000, br_paricki;

for (m1=0;m1<=(suma/50);m1++)
for (m2=0;m2<=(suma/10);m2++)
for (m3=0;m3<=(suma/5);m3++)
for (m4=0;m4<=(suma/2);m4++)
for (m5=0;m5<=(suma/1);m5++)
tmp = m1*50+m2*10+m3*5+m4*2+m5*1;
if (tmp == suma) {
br_paricki = m1+m2+m3+m4+m5;
if (br_paricki < rezultat)
rezultat = br_paricki;
}
}

return rezultat;
}

17
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 3 (дополнување)
• ЗА ДОМА. Да се врати и бројот на парички од
секој тип што ја формираат бараната сума.

18
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Алчни алгоритми
• Архетипот "Алчен алгоритам" ("Greedy algorithm") е
алгоритам кој користи некоја хевристика за да најде
оптимално решение на некој проблем.
• Се базира на алгоритам кој се одвива во фази, притоа
земајќи во предвид само една влезна променлива во
даден момент. Во секоја фаза се одлучува за
локалниот оптимален избор надевајќи се дека така ќе
се најде глобалното оптимално решение.
• Алчните алгоритми најчесто се извршуваат многу
побрзо од техниките на груба сила.
• За жал, не секогаш алчната стратегија води до точното
rешение

19
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Алчни алгоритми
• Елементи на алчната стратегија:
– Алчен избор: "Локалниот оптимум" во алчниот избор
води кон оптимални решенија. Изборот при секој чекор
е независен од решенијата за идниот потпроблем.
Идејата е дека глобално оптимално решение може да
се постигне со избор на локален оптимум (алчен
избор). Кај алчниот алгоритам може да се направи
изборот кој изгледа како најдобар во моментот и потоа
да се реши потпроблемот кој се појавил по направенот
избор. Алчната стратегија обично се движи во top-down
форма, правејќи алчни избори еден по друг,
итеративно намалувајќи го секој проблем.

20
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Алчни алгоритми
• Елементи на алчната стратегија:
– Оптимална потструктура: оптималното решение може
да се добие со здружување на оптималните решенија
за потпроблемите. Даден проблем има оптимална
потструктура ако оптималното решение на проблемот
ги содржи оптималните решенија на потпроблемите.

21
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4
• Дадени се парички со одредена вредност
(постојат парички од 50, 10, 5, 2 и 1 денар), и
притоа бројот на парички од секоја вредност е
неограничен. За дадена сума да се определи
најмалиот број на парички кои се потребни да се
формира таа сума.

22
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - решение
• При решението на овој проблем може да се примени
архетипот „Алчен алгоритам“, така што секогаш се зема
што поголем број од најголемите парички. На почетокот,
алчниот избор на парички се состои во земање на што
повеќе парички од најголемата паричка (локален
оптимум) за да се формира збир што поблизок до
дадената сума. Овој избор на парички во моментот
изгледа како најдобар и бројот на тие најголеми парички
се додава на решението. Понатаму, за остатокот од сумата
односно за потпроблемот повторно се продолжува со
следната по големина најголема паричка и повторно се
земаат што повеќе парички од дадената паричка. Така се
продолжува со паричките подредени според големината
се додека не се формира бараната сума со избраните
парички.
23
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - Java
class Greedy {

void sortiraj_paricki(int coins[], int n) {


int i, j, tmp;

for (i = 0; i < n; i++) {


for (j = i + 1; j < n; j++) {
if (coins[i] < coins[j]) {
tmp = coins[i];
coins[i] = coins[j];
coins[j] = tmp;
}
}
}
}

24
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - Java
// coins e niza so vrednostite na parickite koi se dadeni
// n e brojot na paricki
// sum e dadenata suma
// coinsNum e niza za resenieto so brojot na paricki od sekoja
// golemina na paricka
int greedyCoins(int coins[], int n, int sum, int coinsNum[]) {
sortiraj_paricki(coins, n);

int i = 0;
int br = 0; // vkupniot broj na paricki za da se formira
// dadenata suma

while (sum > 0) {


coinsNum[i] = sum / coins[i];
sum -= coinsNum[i] * coins[i];
br += coinsNum[i];
i++;
}

25
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - Java
while (i < n) {
coinsNum[i] = 0;
i++;
}

return br;
}
}

26
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - C
void sortiraj_paricki(int coins[], int n) {
int i,j,tmp;

for (i=0;i<n;i++)
for (j=i+1;j<n;j++)
if (coins[i] < coins[j]) {
tmp = coins[i];
coins[i] = coins[j];
coins[j] = tmp;
}
}

27
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - C
// coins e niza so vrednostite na parickite koi se dadeni
// n e brojot na paricki
// sum e dadenata suma
// coinsNum e niza za resenieto so brojot na paricki od sekoja
// golemina na paricka

int greedyCoins(int coins[], int n, int sum, int coinsNum[]) {


sortiraj_paricki(coins, n);

int i = 0;
int br = 0; // vkupniot broj na paricki za da se formira dadenata
//suma
while (sum > 0) {
coinsNum[i] = sum / coins[i];
sum -= coinsNum[i] * coins[i];
br += coinsNum[i];
i++;
}

28
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - C
while(i < n) {
coinsNum[i] = 0;
i++;
}

return br;
}

29
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 4 - дискусија
• Дали овој алгоритам секогаш ќе даде оптимално
решение? Колкав е минималниот број на монети
за да се добие сума 13, а на располагање имаме
монети од 1, 2, 5, 8, 10 денари?
• Дали решението добиено со примена на техника
на груба сила е оптимално решение (задача 3)?

30
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Проблем на пакување на ранец


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

(Knapsack problem)
• Математичка формулација
– Нека wi е тежина на i-тиот објект
– Нека pi е остварениот профит кога е земен i-
тиот објект
– Нека C е капацитетот на ранецот
– Нека xi е променлива чија вредност е
• 0 или 1 за “0/1 knapsack problem”. xi = 1 значи дека е
земен i–тиот објект
• 0 ≤ xi ≤ 1 за “fractional knapsack problem”. Може да се
земе и дел од објектот

31
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Проблем на пакување на ранец


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

(Knapsack problem)
• Цел и ограничувања

– При дадени {w1,w2,…,wn} и {p1, p2, … , pn}

– Цел: максимизирај

– Ограничување:

32
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5
• Студент се спрема да оди на патување. Дозволено
му е да носи еден куфер со максимална тежина
од 20 кг. Студентот се двоуми помеѓу облека,
книги и друштвени игри. Откако ги измерил и
оценил овие работи, студентот ја добил следната
табела:
# Објект Вредност Тежина
1 Облека 200 10
2 Книги 150 20
3 Монопол, карти… 5 0.5
4 CD player, MP3 player… 80 5

33
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5
• Што да понесе студентот, така што вредноста на
понесените работи да биде максимална?
• Постојат две верзии на овој проблем:
– Fractional knapsack проблем: Студентот може да земе
делови од објекти односно може да се одлучи да
понесе само еден дел xi од објектот оi, каде 0 ≤ xi ≤ 1.
– 0-1 knapsack проблем: проблемот е исто поставен, но
објектите не можат да се поделат на помали делови,
така што студентот ќе мора да се одлучи дали ќе го
земе објектот или не. Значи не може да земе само дел
од објектот (xi =0 или xi =1).

34
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Задача 5 (fractional knapsack) –


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

анализа
• За да се реши Fractional knapsack проблемот може
да го користиме архетипот "Алчен алгоритам".
• На пример, нека е даден следниот проблем:
бројот на објекти е 3 (n=3), капацитетот на
ранецот е C=20, профитот за секој од објектите е
даден со следниот вектор (p1, p2, p3) = (25, 24, 15)
и тежините на објектите изнесуваат (t1, t2, t3) =
(18, 15, 10). Да се пополни ранецот со објекти за
да се добие максимален профит.

35
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Задача 5 (fractional knapsack) –


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

анализа
• Во следната табела дадени се четири можни
решенија, при што во првата колона дадено е
колкав дел е земен од секој од објектите:
# (x1, x2, x3) Вкупна тежина = Вкупен профит
1 (1/2, 1/3, 1/4) 0.5*18+1/3*15+0.25*10=16.5 1/2*25+1/3*24+1/4*15=24.25
2 (1, 2/15, 0) 1*18+2/15*15+0*10=20 1*25+2/15*24+0*15=28.2
3 (0, 2/3, 1) 0*18+2/3*15+1*10=20 0*25+2/3*24+1*15=31
4 (0, 1, 1/2) 0*18+1*15+0.5*10=20 0*25+1*24+1/2*15=31.5

• Од понудените решенија се гледа дека решението


4 доведува до максимален профит.

36
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Задача 5 (fractional knapsack) –


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

анализа
• Ако сумата на тежините на сите објекти е помала
или еднаква на C, тогаш јасно е дека xi=1 за сите 1
≤ i ≤ n е оптимално решение. Нека важи
претпоставката дека збирот на тежините го
надминува капацитетот C, поради што јасно е
дека сите xi не можат да бидат 1. Друг очигледен
заклучок е дека за едно решение да е оптимално,
мора комплетно да го пополни ранецот. Оттука, за
секое оптимално решение ова е точно бидејќи
тежините на објектот во ранецот може да се
зголемуваат за децимална вредност додека не се
достигне капацитетот на ранецот C.
37
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Задача 5 (fractional knapsack) –


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

анализа
• Како да се одбере следниот предмет кој ќе се
стави во ранецот? Постојат повеќе можности:
1. Алчност според профитот: Може да се пополнува
ранецот со вклучување на следниот објект со најголем
профит. Ако објектот не се вклопува целиот во
ранецот, тогаш се вклучува дел од него. Значи секогаш
кога објект ќе се вклучи (постои исклучок за
последниот објект) во ранецот, се добива најголемото
можно зголемување на вредноста на профитот
(решение 2 од табелата). Што ако се останати две
единици за пополнување кои треба да се пополнат со
еден од објектите (pi =4, ti =4) и (pj =3, tj =2)? Решението
добиено со оваа стратегија не е оптимално.
38
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Задача 5 (fractional knapsack) –


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

анализа
2. Алчност според тежините: Нека објектите се
подредени во неопаѓачки редослед на тежините ti .
Решението 3 одговара на оваа статегија. Истото
повторно не е оптимално, бидејќи иако капацитетот
расте бавно, профитот не се зголемува доволно брзо.
3. Алчност според односот профит/тежина: Идејата е
да се избере алгоритам кој ќе обезбеди баланс меѓу
брзината на зголемување на профитот и брзината на
искористување на капацитетот. Во секој чекор нека се
вклучува објектот со максимален профит по единица
искористен капацитет, што практично значи дека
објектите се подредени според односот pi/ti.
Следното решение одговара на оваа стратегија.
39
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5 (fractional knapsack) -Java


class Greedy {

void sortiraj(int p[], int t[], int n) {


int i, j, tmpP, tmpT;

for (i = 0; i < n; i++) {


for (j = i + 1; j < n; j++) {
if ((p[i]/(float)t[i])<(p[j]/(float) t[j])) {
tmpP = p[i];
tmpT = t[i];
p[i] = p[j];
t[i] = t[j];
p[j] = tmpP;
t[j] = tmpT;
}
}
}

}
40
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5 (fractional knapsack) -Java


// p i t gi sodrzat profitot i tezinata na objektite
// C e kapacitet na paketot, x e vektor na resenieto
float grFractKnp(int p[], int t[], float C, int n, float x[]) {

sortiraj(p, t, n);
// objektite se podredeni taka da bide zadovolen
// p[i]/t[i] >= p[i+1]/t[i+1]

int i;
float profit = 0;

for (i = 0; i < n; i++) {


x[i] = 0;
}

41
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5 (fractional knapsack) -Java


for (i = 0; i < n; i++) {
if (C > t[i]) { // objektot go stavame celosno
x[i] = 1;
C -= t[i];
profit += p[i];
} else { // objektot go stavame delumno
x[i] = (C / (float) t[i]);
profit += x[i] * (float) p[i];
C = 0;
break;
}
}

return profit;
}

42
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5 (fractional knapsack) -C


void sortiraj(int p[], int t[], int n) {
int i,j,tmpP,tmpT;

for (i=0;i<n;i++)
for (j=i+1;j<n;j++)
if (((float)p[i]/(float)t[i]) < ((float)p[j]/(float)t[j]))
{
tmpP = p[i];
tmpT = t[i];
p[i] = p[j];
t[i] = t[j];
p[j] = tmpP;
t[j] = tmpT;
}
}

43
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5 (fractional knapsack) -C


// p i t gi sodrzat profitot i tezinata na objektite
// C e kapacitet na paketot, x e vektor na resenieto
float greedyFractionalKnapsack(int p[], int t[], float C, int n, float
x[]) {

sortiraj(p, t, n);
// objektite se podredeni taka da bide zadovoleno
// p[i]/t[i] >= p[i+1]/t[i+1]

int i;
float profit = 0;

for(i=0;i<n;i++)
x[i] = 0;

44
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5 (fractional knapsack) -C


for (i=0;i<n;i++) {
if (C > t[i]) { // objektot go stavame celosno
x[i] = 1;
C -= t[i];
profit += p[i];
} else { // objektot go stavame delumno
x[i] = (C/(float)t[i]);
profit += x[i]*(float)p[i];
C = 0;
break;
}
}

return profit;
}

45
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 5 (0-1 knapsack) - дискусија


• Пред користење на алчниот алгоритам треба да
сме сигурни дека изборот на функцијата која го
избира елементот кој следно треба да се вклучи
на крај ќе доведе до оптимално решение. За
среќа, во многу случаи возможно е да се најде
оптималното решение со помош на алчен
алгоритам. Но, за 0-1 knapsack проблемот не
може да користи алчен алгоритам. Оптималното
решение се добива со друг алгоритам ☺.

46
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Раздели и владеј
• Архетипот алгоритам "Раздели и владеј" ("Divide and
conquеr") е една од најмоќните техники за решавање
на проблеми кои можат да се поделат на помали
едноставно решливи делови. Употребата на рекурзија
е очигледна и овозможува детализирање на
проблемот.
• "Раздели и владеј" алгоритмот го дели проблемот на
помали потпроблеми, посебно го решава секој од
овие потпроблеми и на крај ги спојува решенијата во
едно решение на почетниот проблем. Како примери
за алгоритми кои го користат архетипот "Раздели и
владеј" се алгоритмите за сортирање: брзо
сортирање (quicksort) и сортирање со спојување
(mergesort).
47
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Раздели и владеј
• Чекорите на алгоритмот се следниве:
– Подели: подели го проблемот на потпроблеми P1, P2, …
, Pn се додека не се дојде до основен случај
– Владеј: реши ги проблемите Pi (најчесто се користи
рекурзивна примена на истиот алгоритам), добивајќи
решенија Ri
– Слеј: комбинирај ги решенијата Ri на потпроблемите за
да го добиеш решението на почетниот проблем.

48
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Сортирање со спојување (merge sort)


• "Раздели и владеј" алгоритамот во три чекори за
mergesort сортирањето на некоја низа а[0 … n] е
следниот:
– Подели: низата a[0..n] се дели на половина на две
поднизи
– Владеј: секоја половина a[0 .. (n/2)] и a[(n/2) +1 .. n] се
сортира рекурзивно
– Слеј: двете сортирани половини се спојуваат во една
целина

49
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

- илустрација

50
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

- Java
class DivideAndConquer {
//spojuvanje na dve sortirani nizi [l, mid], [mid+1, r]
//rezultatot e nova sortirana niza
void merge(int a[], int l, int mid, int r) {
int numel = r - l + 1;
int temp[] = new int[100]; // nova niza za privremeno cuvanje
// na sortiranite elementi
int I = l, j = mid+1, k = 0;

while ((i <= mid) && (j <= r)) {


if (a[i] < a[j]) {
temp[k] = a[i];
i++;
} else {
temp[k] = a[j];
j++;
}
k++;
}
51
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

- Java
while (i <= mid) {
temp[k] = a[i];
i++;
k++;
}

while (j <= r) {
temp[k] = a[j];
j++;
k++;
}

for (k = 0; k < numel; k++) {


a[l + k] = temp[k];
}
}

52
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

- Java
void mergesort(int a[], int l, int r) {
if (l == r) {
return;
}

int mid = (l + r) / 2;
mergesort(a, l, mid);
mergesort(a, mid + 1, r);
merge(a, l, mid, r);
}
}

53
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

-C
//spojuvanje na dve sortirani nizi [l, mid], [mid+1, r]
//rezultatot e nova sortirana niza
void merge(elementType a[], int l, int mid, int r) {
int numel = r - l + 1;
elementType temp[100]; // nova niza za privremeno cuvanje na
// sortiranite elementi
int i, j, k = 0;

i = l;
j = mid + 1;

while ((i <= mid) && (j <= r)) {


if (a[i] < a[j]) {
temp[k] = a[i];
i++;
} else {
temp[k] = a[j];
j++;
}
k++;
}
54
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

-C
while(i <= mid) {
temp[k] = a[i];
i++;
k++;
}

while(j <= r) {
temp[k] = a[j];
j++;
k++;
}

for (k=0;k<numel;k++)
a[l + k] = temp[k];
}

55
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

-C
void mergesort(elementType a[], int l, int r) {
if (l == r)
return;

int mid = (l + r)/2;


mergesort(a, l, mid);
mergesort(a, mid + 1, r);
merge(a, l, mid, r);
}

56
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

- анализа

57
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И

Сортирање со спојување (merge sort)


КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

- анализа
• Анализа за комплексноста на алгоритамот:
T(n) = 2T(n/2)+n
2T(n/2) = 2(2(T(n/4))+n/2) = 4T(n/4)+n →
T(n) = 4T(n/4)+2n
4T(n/4) = 4(2T(n/8))+(n/4) = 8T(n/8)+n →
T(n) = 8T(n/8)+3n

T(n) = 2k T(n/ 2k)+kn и ако замениме k=log(n) се
добива: T(n) = nT(1)+n log(n) = n log(n) + n
Значи комплексноста е
58
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 6
• Да се напише функција која ќе го пресмета n-тиот
степен на некој број со примена на техниката
"Раздели и владеј".

59
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 6 - Java
class DivideAndConquer {

int pow(int x, int n) {


int r;

if(n == 0)
return(1);
else if(n % 2 == 0) {
r = pow(x, (n/2));
return r*r;
} else {
r = pow(x, (n/2));
return x*r*r;
}
}
}

60
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 6 - C
int pow(int x, int n) {
int r;

if(n == 0)
return(1);
else if(n % 2 == 0) {
r = pow(x, (n/2));
return r*r;
} else {
r = pow(x, (n/2));
return x*r*r;
}

61
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 6 - анализа
• Анализа за комплексноста на алгоритамот:
T(n) = T(n/2) + О(1)
T(n/2) = (T(n/4) + 1) →
T(n) = T(n/4) + 2
T(n/4) = T(n/8) + 1 →
T(n) = T(n/8) + 3

T(n) = T(n/2k)+k и ако замениме k=log(n) се добива:
T(n) = T(1)+log(n) = log(n)
Значи комплексноста е O(log n)
62
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 6 - анализа
• Решение 2:
int pow(int x, int n) {
int r;

if(n == 0)
return(1);
else if(n % 2 == 0) {
return pow(x, (n/2))*pow(x,
(n/2));
} else {
return x*pow(x, (n/2))*pow(x,
(n/2));
}
}

• Што може да се заклучи?


63
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 6 (решение 2)- анализа


• Анализа за комплексноста на алгоритамот:
T(n) = 2T(n/2)+О(1)
T(n/2) = 2(T(n/4) + 1) →
T(n) = 4T(n/4)+2
T(n/4) = 8Т(n/8) + 1 →
T(n) = 8T(n/8)+3

T(n) = 2kT(n/2k)+k и ако замениме k=log(n) се добива:
T(n) = nT(1)+log(n) = n + log(n)
Значи комплексноста е O(n)
64
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 7
• Пронајдете ги двата најмали елементи во дадена
низа со помош на техниката "раздели и владеј".

65
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 7 - Java
class DvaNajmali {
int a;
int b;
DvaNajmali() {

}
DvaNajmali(int a, int b) {
this.a = a;
this.b = b;
}
}

66
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 7 - Java
class DivideAndConquer {

int INF = 1000000;

DvaNajmali pronajdi(int a[], int l, int r) {


if (l == r) {
DvaNajmali dn = new DvaNajmali(a[l], INF);
return dn;
}

int mid = (l + r) / 2;

DvaNajmali r1 = pronajdi(a, l, mid);


DvaNajmali r2 = pronajdi(a, mid + 1, r);

DvaNajmali r3 = new DvaNajmali();

67
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 7 - Java
if (r1.a < r2.a) {
r3.a = r1.a;
if (r1.b < r2.a) {
r3.b = r1.b;
} else {
r3.b = r2.a;
}
} else {
r3.a = r2.a;
if (r1.a < r2.b) {
r3.b = r1.a;
} else {
r3.b = r2.b;
}
}

return r3;
}
}

68
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 7 - C
#define INF 1000000

typedef struct {
int a; // prviot najmal
int b; // vtoriot najmal
} DvaNajmali;

DvaNajmali* pronajdi(int a[], int l, int r) {


if (l == r) {
DvaNajmali *dn = (DvaNajmali*)malloc(sizeof(DvaNajmali));
dn->a = a[l];
dn->b = INF;
return dn;
}
int mid = (l+r)/2;

DvaNajmali *r1 = pronajdi(a, l, mid);


DvaNajmali *r2 = pronajdi(a, mid+1, r);
DvaNajmali *r3 = (DvaNajmali*)malloc(sizeof(DvaNajmali));

69
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 7 - C
if (r1->a < r2->a) {
r3->a = r1->a;
if (r1->b < r2->a)
r3->b = r1->b;
else
r3->b = r2->a;
} else {
r3->a = r2->a;
if (r1->a < r2->b)
r3->b = r1->a;
else
r3->b = r2->b;
}

return r3;
}

70
ФАКУЛТЕТ ЗА ИНФОРМАТИЧКИ НАУКИ И
КОМПЈУТЕРСКО ИНЖЕНЕРСТВО

Задача 7 - дискусија
• Која е комплексноста на решението со примена
на техниката "раздели и владеј"?
– O(n)
– Анализата е иста како и кај задача 6 – решение 2
• Кое е другото поедноставно решение на овој
проблем? Која е комплексноста на ова решение?
– O(n)
– Со изминување на низата и чување на два минимуми
во посебни променливи

71

You might also like