Sunteți pe pagina 1din 28

UNIVERSITATEA DIN CRAIOVA

FACULTATEA DE INFORMATICĂ MATEMATICĂ

METODA BACKTRACKING

PROFESOR: Student:
Băzăvan Petre Ștefan Cristian

2009
TEMA LUCRĂRII:

COLORAREA HĂRŢILOR FOLOSIND METODA BACKTRACKING

Motivul alegerii acestei teme este:


Studierea si aprofundarea rezolvarii problemelor prin
metoda backtracking.
CUPRINS:

1. METODA BACKTRACKING …… 3
2. APLICAŢII REZOLVATE …… 5
METODA BACKTRACKING
NOŢIUNI GENERALE

La dispoziţia celor care rezolvă probleme cu ajutorul calculatorului


există mai multe metode . Dintre acestea cel mai des utilizate sunt:

- metoda Greedy;
- metoda Divide et impera;
- metoda Branch and Bound;
- metoda Backtracking;

Metoda Backtracking se aplică problemelor în care soluţia poate fi


reprezentată sub forma unui vector – x = (x1, x2, x3, …xk,… xn) € S, unde S
este mulţimea soluţiilor problemei şi S = S1 x S2 x… x Sn, şi Si sunt mulţimi
finite având s elemente si xi € si , (¥)i = 1..n.
Pentru fiecare problemă se dau relaţii între componentele vectorului x,
care sunt numite condiţii interne; soluţiile posibile care satisfac condiţiile
interne se numesc soluţii rezultat. Metoda de generare a tuturor soluţiilor
posibile si apoi de determinare a soluţiilor rezultat prin verificarea îndeplinirii
condiţiilor interne necesită foarte mult timp.
Metoda backtracking evită această generare şi este mai eficientă.
Elementele vectorului x, primesc pe rând valori în ordinea crescătoare a
indicilor, x[k] va primi o valoare numai daca au fost atribuite valori
elementelor x1.. x[k-1]. La atribuirea valorii lui x[k] se verifica îndeplinirea
unor condiţii de continuare referitoare la x1…x[k-1]. Daca aceste condiţii nu
sunt îndeplinite, la pasul k, acest lucru înseamnă ca orice valori i-am atribui
lui x[k+1], x[k+1], .. x[n] nu se va ajunge la o soluţie rezultat.
Metoda backtracking construieşte un vector soluţie în mod progresiv
începând cu prima componentă a vectorului şi mergând spre ultima cu
eventuale reveniri asupra atribuirilor anterioare.
Metoda se aplica astfel :
1) se alege prima valoare sin S1 si I se atribuie lui x1 ;
2) se presupun generate elementele x1…x[k-1], cu valori din S1..S[k-1];
pentru generarea lui x[k] se alege primul element din S[k] disponibil si
pentru valoarea aleasa se testează îndeplinirea condiţiilor de continuare.
Pot apărea următoarele situaţii :
a) x[k] îndeplineşte condiţiile de continuare. Daca s-a ajuns la
soluţia finală (k = n) atunci se afişează soluţia obţinută. Daca nu
s-a ajuns la soluţia finală se trece la generarea elementului
următor – x [k-1];
b) x[k] nu îndeplineşte condiţiile de continuare. Se încearcă
următoarea valoare disponibila din S[k]. Daca nu se găseşte nici
o valoare în S[k] care să îndeplinească condiţiile de continuare,
se revine la elementul x[k-1] şi se reia algoritmul pentru o nouă
valoare a acestuia. Algoritmul se încheie când au fost luate in
considerare toate elementele lui S1.
Problemele rezolvate prin această metodă necesită timp mare de
execuţie, de aceea este indicat sa se folosească metoda numai daca nu avem
alt algoritm de rezolvare.
Dacă mulţimile S1,S2,…Sn au acelaşi număr k de elemente, timpul
necesar de execuţie al algoritmului este k la n. Dacă mulţimile S1, S2.. Sn nu
au acelaşi număr de elemente, atunci se notează cu „m” minimul cardinalelor
mulţimilor S1…Sn si cu „M”, maximul. Timpul de execuţie este situat în
intervalul [m la n .. M la n]. Metoda backtracking are complexitatea
exponenţială, in cele mai multe cazuri fiind ineficientă. Ea insa nu poate fi
înlocuită cu alte variante de rezolvare mai rapide în situaţia în care se cere
determinarea tuturor soluţiilor unei probleme.
APLICAŢII REZOLVATE

Exemple:
Generarea permutărilor. Se citeşte un număr natural n. Să se
genereze toate permutările mulţimii {1, 2, 3, …,n}.
Generarea permutărilor se va face ţinând cont că orice permutare va fi
alcătuită din elemente distincte ale mulţimii A. Din acest motiv, la generarea
unei permutări, vom urmări ca numerele să fie distincte.
Prezentăm algoritmul corespunzător cazului n=3:
1 2 3
1 2 2 2 2
1 1 1 1 1 1

1 2 3
3 3 3 3 1
1 1 1 1 2 2

1 2 3 1
1 1 1 2 3 3
2 2 2 2 2 2

• se încarcă în stivă pe nivelul 1 valoarea 1;


• încărcarea valorii 1 pe nivelul al 2-lea nu este posibilă, întrucât
această valoare se găseşte şi pe nivelul 1 al stivei;
• încărcarea valorii 2 pe nivelul al 2-lea este posibilă, deoarece această
valoare nu mai este întâlnită;
• valoarea 1 din nivelul al 3-lea se regăseşte pe nivelul 1;
• valoarea 2 din nivelul al 3-lea se regăseşte pe nivelul al 2-lea;
• valoarea 3 pe nivelul al 3-lea nu e întâlnită pe nivelurile anterioare;
întrucât nivelul 3 este completat corect. Tipărim: 1 2 3
……
Algoritmul continuă până când stiva devine vidă.
Problema celor n dame. Fiind dată o tablă de şah n× n se cer toate
soluţiile de aranjare a n dame, astfel încât să nu se afle două dame pe aceeaşi
linie, coloană sau diagonală (damele să nu se atace reciproc).
Exemplu: Presupunând că dispunem de o tablă de dimensiune 4× 4, o
soluţie ar fi următoarea:

Cum procedăm? Observăm că o damă trebuie să fie plasată singură pe


linie. Plasăm prima damă pe linia 1 coloana 1.

A doua damă nu poate fi aşezată decât pe coloana a 3-a.

Observăm că a treia damă nu poate fi plasată în linia a 3-a. Încercăm


atunci plasarea celei de-a doua dame în coloana a 4-a.

D
A treia damă nu poate fi plasată decât pe coloana a 2-a.

În această situaţie dama a patra nu mai poate fi aşezată. Încercând să


avansăm cu dama a treia, observăm că nu este posibil să o plasăm nici în
coloana a treia, nici în coloana a patra, deci o vom scoate de pe tablă. Dama a
doua nu mai poate avansa, deci şi ea este scoasă de pe tablă. Avansăm cu
prima damă în coloana a doua.

A doua damă nu poate fi aşezată decât în coloana a patra.

Dama a treia se aşează în prima coloană.

D
Acum este posibil să plasăm a patra damă în coloana a treia şi astfel am
obţinut o soluţie a problemei.

Algoritmul continuă în acest mod până când trebuie scoasă de pe tablă


prima damă.
Pentru prezentarea unei soluţii putem folosi un vector cu n componente
(având în vedere că pe fiecare linie se găseşte o singură damă). Exemplu:
pentru soluţia găsită avem vectorul st ce poate fi asimilat unei stive.
Două dame se găsesc pe aceeaşi diagonală dacă şi numai dacă este
îndeplinită condiţia. |st (i) – st (j)| = |i-j| : (diferenţa, în modul, între linii şi
coloane este aceeaşi).

3 ST (4)

1 ST (3) În general ST(i) = k semnifică


faptul că pe linia i dama ocupă
4 ST (2) poziţia k.
2 ST (1)

Exemplu: În tabla 4× 4 avem situaţia:

D
St (1) = 1 i = 1;
St (3) = 1 j = 3;
D | St (1) – st (3) | = |1 – 3| = 2
|i – j| = |1 – 3| = 2

Sau situaţia:
D
St (1) = 3 i = 1;
St (3) = 1 j = 3;
D | St (i) – st (j) | = |3 – 1| = 2
|i – j| = |3 – 1| = 2

Întrucât două dame nu se pot găsi pe aceeaşi coloană, rezultă că o


soluţie este sub formă de permutare. O primă idee ne conduce la generarea
tuturor permutărilor şi la extragerea soluţiilor pentru problemă (ca două dame
să nu fie plasate în aceeaşi diagonală). A proceda astfel, înseamnă să lucră
conform strategiei backtracking. Aceasta presupune ca imediat ce am găsit
două dame care se atacă, să reluăm căutarea. Faţă de programul de generare a
tuturor soluţiilor problemei celor n dame, are o singură condiţie suplimentară,
în procedura valid.
Produsul cartezian a n mulţimi. Se dau mulţimile de mai jos şi se cere
produsul cartezian al lor.
A1 = {1, 2, 3, …, k1}
A2 = {1, 2, 3, …, k2}
………………………
An = {1, 2, 3, …, kn}
Exemplu: A1 = {1, 2}
A2 = {1, 2, 3}
A3 = {1, 2, 3}
A1 × A2 × A3 = {(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 1), (1, 2, 2), (1, 2, 3),
(1, 3, 1), (1, 3, 2), (1, 3, 3), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 2, 1), (2, 2, 2), (2, 2,
3), (2, 3, 1), (2, 3, 2), (2, 3, 3)}.
Pentru rezolvare, se folosesc stiva ST şi un vector A ce reţine numerele
k1, k2, …kn. Utilizăm metoda backtracking, uşor modificată din următoarele
motive:
a) Orice element aflat la nivelul k al stivei este valid, motiv pentru care

procedura valid nu face altceva decât să atribuie variabilei ev


valoarea TRUE.
b) Limita superioară pe nivelul k al stivei este dată de A(k).
Modul de concepere a algoritmului rezultă din cele ce urmează:

1 2 3 1

1 1 1 2 2

1 1 1 1 1 1

2 3 1 2 3

2 2 3 3 3 3

1 1 1 1 1 1
…………………………………………………………………………

Observaţii:
• Algoritmul prezentat aici este de tip backtracking? Întrebarea are
sens pentru că este absent mecanismul de întoarcere. Vom admite că
şi aceasta este backtracking, dar „degenerat”.
Generarea aranjamentelor. Se citesc n şi p. Să se genereze toate
aranjamentele de n luate câte p.
Din analiza problemei rezultă următoarele:
stiva are înălţimea p;
fiecare nivel ia valori între 1 şi n;
elementele plasate pe diverse niveluri trebuie să fie distincte.
Algoritmul este asemănător cu cel de la permutări, cu deosebirea că aici
stipa are înălţimea p.
Generarea combinărilor. Se citesc n şi p numere naturale, n≥ p. Se
cere să se genereze toate submulţimile cu p elemente ale mulţimii {1, 2, 3, …,
n}.
Pentru rezolvarea problemei trebuie ţinut cont de următoarele:
stiva are înălţimea p;
elementele aflate pe niveluri diferite ale stivei trebuie să fie distincte;
pentru a evita repetiţia elementele se aşează în ordine crescătoare: pe
nivelul k se va afla o valoare mai mare decât pe nivelul k-1 şi mai mică sau
egală cu n-p+k.
Problema comis-voiajorului. Un comis voiajor trebuie să viziteze un
număr n de oraşe. Iniţial, el se află într-unul dintre ele, notat 1. Comis –
voiajorul doreşte să nu treacă de două ori prin acelaşi oraş, iar la întoarcere să
revină în oraşul 1. Cunoscând legăturile existente între oraşe, se cere să se
tipărească toate drumurile posibile pe care le poate efectua comis – voiajorul.
Exemplu: În figura alăturată sunt simbolizate cele 6 oraşe, precum şi
drumurile existente între ele.

2 3

1 4

6 5

Comis – voiajorul are următoarele posibilităţi de parcurgere:


1, 2, 3, 4, 5, 6, 1;
1, 2, 5, 4, 3, 6, 1;
1, 6, 3, 4, 5, 2, 1;
1, 6, 5, 4, 3, 2, 1;
Legăturile existente între oraşe sunt date în matricea An,n. Elementele
matricei A pot fi 0 sau 1 (matricea este binară).
1, dacă există drum între oraşele i şi j;
A(i,j) =
0, altfel
Se observă că A(i,j) = A(j,i), oricare ar fi i,j ∈{1, 2, 3, …, n} – matricea
este simetrică.
Pentru rezolvarea problemei folosim stiva st. la baza stivei (nivelul 1)
se încarcă numărul 1. Prezentăm în continuare modul de rezolvare a
problemei.
2
De la oraşul 1 la oraşul 2 există drum, deci se va urca în stivă;
1

2
2 Oraşul 2 se mai găseşte în stivă, deci nu este acceptat;
1

3
De la oraşul 2 la oraşul 3 se găseşte drum; prin oraşul 3 nu s-a mai
2
trecut, deci oraşul 3 este acceptat.
1
Algoritmul continuă în acest mod până se ajunge din nou la nivelul 1,
caz în care algoritmul se încheie.
Un succesor, între 2 şi n, aflat pe nivelul k al stivei, este considerat
valid dacă sunt îndeplinite următoarele condiţii:
• nu s-a mai trecut prin oraşul simbolizat de succesor, deci acesta nu
se regăseşte în stivă;
• există drum între oraşul aflat la nivelul k-1 şi cel aflat la nivelul k;
• dacă succesorul se găseşte la nivelul n, să existe drum de la el la
oraşul 1.
Observaţii:
1. Problemele rezolvate prin această metodă necesită un timp
îndelungat de execuţie. Din acest motiv este bine să utilizăm
metoda atunci numai atunci când nu mai avem la dispoziţie un
alt algoritm mai eficient
2. Menţionăm că nu există probleme pentru care nu se cunosc
algoritmi eficienţi de rezolvare, deci backtracking este
indicată.
3. Rezolvarea iterativă încalcă principiul stivei atunci când
verificăm condiţiile de continuare, sau atunci când tipărim
soluţia găsită, pentru că accesăm orice nivel al stivei. Consider
că o structură trebuie folosită ca atare atunci când este strict
necesar. De exemplu, chiar şi segmentul de stivă al
calculatorului poate fi accesat oriunde. Asta nu înseamnă că
acolo nu se utilizează din plin „mecanismul” stivei.
PROBLEMA COLORĂRII HARŢILOR

Enunţ:
Fiind dată o hartă nu n ţări, se cer toate soluţiile de colorare a hărţii,
utilizând cel mult patru culori, astfel încât două ţări de frontieră comună să
fie colorate diferit. Este demonstrat faptul că sunt suficiente numai patru
culori pentru ca orice hartă să poată fi colorată.
Rezolvare:
Pentru exemplificare, vom considera următoarea hartă unde ţările sunt
numerotate cu cifre cuprinse între 1 şi 5:

1
4

2
3
5

O soluţie a acestei probleme este următoarea:


• ţara 1 – culoarea 1
• ţara 2 – culoarea 2
• ţara 3 – culoarea 1;
• ţara 4 – culoarea 3;
• ţara 5 – culoarea 4;
Harta este furnizată programului cu ajutorul unei matrice An,n
1, dacă ţara i se învecinează cu ţara j;
A(i,j) =
0, altfel
Matricea A este simetrică. Pentru rezolvarea problemei se utilizează
stiva st, unde nivelul k al stivei simbolizează ţara k, iar st[k] culoarea ataşată
ţării k. Stiva are înălţimea n şi pe fiecare nivel ia valori între 1 şi 4.

Rezolvare PASCAL:

Program colorarea_hartilor;
Type
stiva = array [1…100] of integer;
var
st : stiva;
i, j, n, k : integer;
as, ev : boolean;
a: array [1..20,1..20] of integer;

procedure init(k:integer; var st:stiva);


begin
st[k]:=0;
end;

procedure succesor(var as:boolean; var st:stiva; k:integer);


begin
if st[k] < 4
then
begin
st[k]:=st[k]+1;
as:true
end
else
as:false
end;

procedure valid (var ev:boolean; st:stiva; k:integer);


var
i:integer;
begin
ev:true;
for i:=1 to k-1 do
if (st[i]=st[k]) and (a[i,k]=1)
then
ev:false
end;

function solutie(k:integer):integer;
begin
solutie:=(k=n);
end;

procedure tipar;
var
i:integer;
begin
for i:= 1 to n do
writeln(’Tara =’, i,’; culoarea=’,st[i]);
writeln(’===================’);
end;

begin
write(’Numarul de tari = ’);
readln(n);
for i:= 1 to n do
for j:=1 to i-1 do
begin
write(’a[’,i,’,’,j,’]=’);
readln(a[i,j])
end;
k:=1;
init(k,st);
while k>0 do
begin
repeat
succesor(as,st,k);
if as
then
valid(ev,st,k);
until (not as) or (as and ev);
if as
then
if solutie (k)
then
tipar
else
begin
k:=k+1;
init(k,st)
end
else
k:=k-1
end
end.

Concepţia şi strategia metodei BACKTRACKING

Metoda a fost concepută pentru a evita generarea tuturor soluţiilor posibile.

În acest sens, metoda foloseşte un arbore virtual construit astfel:


 nivelul 0 conţine rădăcina virtuală r;
 nivelul 1 conţine ca noduri, elementele mulţimii S1, în care componenta
x1 ia valori, legăturile mulţimii etichetate cu1,2,…, s1;
 nivelul k≥ 2, conţine ca noduri elementele mulţimii Sk, astfel ca din orice
nod
de pe nivelul k-1 pleacă exact sk muchii; nivelul conţine s1,…sk noduri;
 nivelul n conţine s1 ... sn noduri terminale.
r

1 2.. … s1

x1 →
s1 noduri

1 2…s2 1 2 .. s2 1 2...s2 s1s2


x2 → noduri

. . .
. . .
. . .

s1…sn
1 2 ..sn 1 2. ….sn 1 2…sn noduri
xn →
Arborele ataşat spaţiului soluţiilor posibile.

Metoda Backtracking utilizează arborele ataşat soluţiilor posibile pentru


a
genera soluţiile rezultat, evitând generarea tuturor soluţiilor posibile prin
verificarea condiţiilor de continuitate ϕ k(x1,…,xk)

Exemplu: Arborele ataşat spaţiului soluţiilor posibile pentru


problema generării permutărilor mulţimii {1,2,…,n}:

1 2.. … n

x1 →
n noduri

1 2….n 1 2 .. n 1 2...n n2
x2 →
noduri

. . .
. . .
. . .

n
1 2 ..n 1 2. ….n 1 2…n n
xn →
noduri

S1={1,2,…n}; S2={1,2,…n}; … Sn={1,2,…n};|Sn|=n; Sn={1,2,…,n}.


Observaţie: Generarea elementelor produsului cartezian {1,…,n}x … x {1,
…,n}
presupune generarea întregului spaţiu al soluţiilor posibile.

Observaţie: O soluţie rezultat este un drum de la rădăcină la un nod terminal.

Metoda va genera drumuri de la stânga la dreapta conform


parcurgerii DF(depth, first) a arborilor (în adâncime) şi anume va genera
vectorul (x1,x2,…,xn) astfel:
 componentele x1,x2,…,xn primesc pe rând valori, adică mai întâi x1, apoi
x 2,
…, deci xk vor primi valoare numai dacă au fost deja stabilite valori
pentru
x1,x2,…,xk-1;
 dacă xk a primit valoare, nu se trece la nivelul urmator ca să i se
atribuie
valori lui xk+1, fără să se testeze condiţiile de continuare ϕ k(x1,…,xk);
 dacă ϕ k(x1,…,xk)=true, atunci se încearcă să se dea valori pentru xk+1.
 dacă ϕ k(x1,…,xk)=false, atunci:
a) va trebui o altă alegere pentru xk, dacă Sk nu s-a epuizat sau
b) dacă Sk s-a epuizat, se revine la nivelul inferior (k-1) şi xk primeşte o
nouă alegere, abandonându-se un întreg arbore (de aici
denumirea
metodei).

x1 →

x2 → Observaţie:
ϕ n(x1,…,xn) ≡ ϕ
x3 →

xk-1 →
1 2 sk 1 2 sk 1 2 sk
xk →

Implementarea metodei
Procedura
nerecursivă

INPUT :

Sk = {α
k
1
k ,α
2
k ,α
,...
sk
}, k =
k 1, kn, s = s

k k
valorile k k

α 0
∉S
cu proprietatea ca
succ( α 0
)= α

ϕ k(x1,…,xk) condiţii de continuare

OUTPUT: (x1,…,xn) soluţii

rezultat. Procedure BACK;

k ←1 {reprezintă nivelul în arbore}


0
xk ← α k {valoare de start}
while k>0 do {se generează drumuri}
if k=k+1 then {s-a găsit o soluţie}
k ← k-1
write x1,x2,…,xn
else {altă soluţie}
sk
if xk< α k then {altă valoare pentru xk}
xk ←
succ(xk)
if ϕ k(x1,…,xk) then k ←
k+1
else {s-a epuizat sk}
xk ← α k 0 {valoare de start}
k ← k-1

Varianta recursivă:

Procedure BACK(k:integer);
if k=k+1 then
write (x1,x2,…,xn)
else {se caută altă soluţie}
0
xk ← α k {valoare de start}
sk
while xk< α k do {Sk nu s-a epuizat}}
xk ←
succ(xk)
if ϕ k(x1,…,xk) then back(k+1)
Utilizare:
BACK(1);

Exemplul 1: Generarea permutărilor mulţimii {1,2,….n}


program permutari;
var
x:array[1..200] of integer;
nr,i,n,k:integer;

function col(k:integer):boolean;
begin
col:=true;
for i:=1 to k-1 do
if x[i]=x[k] then
begin
col:=false;
exit;
end;
begin
write('n=');
readln(n);

nr:=0;
k:=1;
for i:=1 to n do
x[i]:=0;
while k>0 do
if k=n+1 then
begin
k:=k-1;
nr:=nr+1;
writeln(' solutia nr ',nr);
for i:=1 to n do
write(x[i]:2);
readln;
end
else
if x[k]<n then
begin
x[k]:=x[k]+1;
if col(k) then
k:=k+1;
end
else
begin
x[k]:=0;
k:=k-1;
end;
end.
Observaţii: pt. n=3 se obţin 6 soluţii:
1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1.
Exemplul 2: Problema celor n dame (regine). Să se aşeze cele 8 dame pe o
tablă de şah pătrată cu 8 linii şi 8 coloane, astfel ca să nu se atace reciproc,
adică să nu existe două dame pe aceeaşi linie, coloană sau diagonală. Orice
soluţie rezultat X=(x1,…,xn), xi=coloana pe care se află dama de pe linia „i”.

Condiţii interne:
Fie i şi j două dame:
a) damele să nu se afle pe aceeaşi coloană xi≠ xj;
i≠ j b) să nu se afle pe diagonala xi , xj

(i,xi) (i,xi)

(j,xj) (j,xj)

j-i ≠ xj – xi i-j ≠ xi -xj

|i-j| ≠ |xi-
xj |
Program cele_8_regine;
var
x:array[1..200] of integer;
nr,i,n,k:integer;

function col(k:integer):boolean;
begin
col:=true;
for i:=1 to k-1 do
if (x[i]=x[k]) or (abs(i-k)=abs(x[i]-x[k])) then
begin
col:=false;
exit;
end;
end;
begin
write('n=');
readln(n);
nr:=0;
k:=1;
for i:=1 to n do
x[i]:=0;
while k>0 do
if k=n+1 then
begin
k:=k-1;
nr:=nr+1;
writeln(' solutia nr ',nr);
for i:=1 to n do
write(x[i]:2);
readln;
end
else
if x[k]<n then
begin
x[k]:=x[k]+1;
if col(k) then
k:=k+1;
end
else
begin
x[k]:=0;

k:=k-1;

end.
Exemplul 3: Colorarea grafurilor – hărţilor:
Fiecărei hărţi i se poate ataşa un graf planar.

G=(Vi,E), Vi=mulţimea nodurilor; E = mulţimea muchiilor;


n=nr. de ţări; n=|V| nr. de noduri;
c= nr. de culori; Sk={1,2,…,c}; k=1,…,n;
Soluţie: (x1,…,xn), xi∈{1,…,c}; xi = culoarea ataşată nodului i.
G poate fi reprezentat prin:

1 dac exista muchie


aij  a
0 altfe
l
• matricea de adiacenţă A = ||aij|| i=1,…,n; j=1,…,n;

• matricea muchiilor xi ≠ xj, i ≠ j

 dac ∀i, j ∈ {1,..., i≠ xi ≠ x tar vecine


ϕ ( x1 ,..., true a k}, j, i
xk )=  j

 altfel
false

Intrări: n = nr. de noduri


m = nr. de muchii
(i,j) = muchiile
c = nr. de
culori
Ieşiri: (x1,x2,…,xn), xi ∈ {1,…,c}, i = 1,…,n
Program colorare_harti;
var
a:array[1..30,1..30] of 0..1;
x:array[1..30] of integer;
nr,i,j,n,m,k,c:integer;

function cont(k:integer):boolean;
begin
cont:=true;
for i:=1 to k-1 do
for j:=i+1 to k do
if (a[i,j]=1) and (x[i]=x[j]) then
begin
cont:=false;

exit;
end;
end;

begin
write('nr de noduri (tari): n=');
readln(n);
write('nr.de muchii (vecini): m=');
readln(m);
nr:=0;
k:=1;
for i:=1 to n do
for j:=1 to n do
a[i,j]:=0;
writeln('introduceti muchiile (i j):');
for i:=1 to m do
begin
readln(k,c);
a[k,c]:=1;
a[c,k]:=1;
end;
write('nr. de culori c=');
readln(c);
k:=1;
for i:=1 to n do
x[i]:=0;
while k>0 do
if k=n+1 then
begin
k:=k-1;
nr:=nr+1;
writeln(' solutia nr ',nr);
for i:=1 to n do
write(x[i]:2);
readln;
end
else
if x[k]<c then
begin
x[k]:=x[k]+1;
if cont(k) then
k:=k+1;
end
else
begin
x[k]:=0;
k:=k-1;
end;
end.
Bibliografie

Cerchez, Emanuela, Programarea in limbajul C++ pentru liceu. Volumul al II-lea: Metode si
tehnici de programare, Editura POLIROM, Bucuresti, 2005
Socaciu, Tiberiu ; Backtracking. Teorie si exemple, Vol. 1 C, Editura InfoData, Bucuresti, 2005

S-ar putea să vă placă și