Problemas de fluxo numa rede
Modelar fluxos conservativos entre dois pontos através de canais com capacidade limitada
1
2
s
Fluxo num arco não pode
ultrapassar a capacidade
Soma das entradas num nó
igual à soma das saídas
Exemplos
• abastecimento de líquido
ponto a ponto
• tráfego entre dois pontos
- s: fonte; t: poço
- distribuição de fluxo pelos
arcos arbitrária, desde que
respeite as setas
s
3
2
1
a
3
b
4
3
c
d
2
3
t
0
a
2
2
b
1
2
2
c
d
2
3
t
Grafos - 1
Fluxo máximo: 1ª abordagem
 algoritmo simples de aproximações sucessivas baseado em
• G  grafo base de capacidades
• Gf  grafo auxiliar de fluxos
- inicialmente fluxos iguais a 0
- no fim, fluxo máximo
• Gr  grafo residual (auxiliar)
- capacidade disponível em cada arco (= capacidade - fluxo)
- capacidade disponível = 0 — eliminar arco saturado
 método de calcular o fluxo máximo entre s e t
• em cada iteração, selecciona-se um caminho em Gr entre s e t (de acréscimo) —
algoritmo não determinístico
• valor mínimo nos arcos desse caminho = quantidade a aumentar a cada um dos
arcos respectivos em Gf
• recalcular Gr
• termina quando não houver caminho de s para t
Grafos - 2
Exemplo: estado inicial
s
s
3
2
1
a
0
b
4
3
d
2
3
t
G
0
0
a
2
c
s
3
b
0
0
c
d
0
0
1
a
0
2
b
4
3
2
c
d
2
3
t
t
Gf
Gr
Grafos - 3
Exemplo: 1ª iteração
s
s
3
2
1
a
0
b
4
3
d
2
3
t
G
2
0
a
2
c
s
3
b
0
0
2
c
d
0
2
1
a
b
4
3
c
d
2
1
t
t
Gf
Gr
Grafos - 4
Exemplo: 2ª iteração
s
s
3
2
1
a
2
b
4
3
d
2
3
t
G
2
0
a
2
c
s
1
b
0
2
2
c
d
2
a
1
b
4
1
c
d
2
1
t
t
Gf
Gr
Grafos - 5
Exemplo: 3ª iteração
s
s
3
2
1
a
3
b
4
3
d
2
3
t
G
2
0
a
2
c
s
b
1
2
2
c
d
2
a
1
b
3
1
c
d
3
t
t
Gf
Gr
Grafos - 6
Algoritmo não garante fluxo óptimo
 critério ganancioso de selecção do caminho: escolher o que dê maior fluxo
- caminho s, a, d, t (3 unidades de fluxo)  algoritmo termina sem obter o máximo
- exemplo de algoritmo ganancioso que falha
s
s
3
2
1
a
3
b
4
3
d
2
3
t
0
0
a
2
c
s
2
b
3
0
d
0
3
t
a
0
c
1
b
1
3
c
2
d
2
t
Grafos - 7
Algoritmo determinístico
permitir que o algoritmo mude de ideias
•
•
•
•
para cada arco (v,w) com fluxo f(v,w) no grafo de fluxos acrescenta-se um arco (w,v) no
grafo residual com capacidade f(v,w)
- corresponde a deixar devolver fluxo para trás (nunca fica globalmente negativo, contra o
arco)
- podem existir arcos em sentidos opostos; podem existir ciclos
se as capacidades forem números racionais, o algoritmo termina com máximo
se as capacidades forem inteiros e o fluxo máximo f
- bastam f estádios (fluxo aumenta pelo menos 1 por estádio)
- tempo de execução ( caminho mais curto não pesado ) é O(f. |E| )  mau
evitar o problema
- escolher caminho que dá maior aumento de fluxo
- semelhante ao problema do caminho pesado mais curto (pequena alteração a Dijkstra)
- fluxo máximo em O(|E| log capMax)
(capMax = capacidade máxima de um arco)
- cada cálculo de um aumento em O(|E| log |V|) (Dijkstra)
- global: O(|E|^2 log |V| log capMax)
Grafos - 8
Solução óptima - 1ª iteração
s
s
3
2
1
a
3
b
4
3
s
0
a
2
0
3
b
3
0
2
1
a
0
b
1
3
2
3
c
d
2
3
t
G
c
d
0
3
c
d
2
3
t
t
Gf
Gr
3 unidades de fluxo no caminho sadt
Grafos - 9
Solução óptima - 2ª iteração
s
s
3
2
1
a
3
b
4
3
s
0
a
2
2
3
b
1
2
2
1
a
2
2
b
3
1
2
1
c
d
2
3
t
G
c
d
2
c
3
d
2
3
t
t
Gf
Gr
2 unidades de fluxo no caminho s,b,d,a,c, t
Grafos - 10
Caso difícil
1 000 000
a
1 000 000
s
1
t
- se se escolher passar sempre por a e por b…
1 000 000
b
1 000 000
s
1
999 999
1
a
b
1
1
t
999 999
1
0
a
… temos 2 000 000 de iterações,
em vez de 2!
s
b
1
1 000 000
1 1
1
a
1 000 000
1
t
s
a
999 999
b
999 999
t
s
1 1
1
1 1
t
999 999
b
999 999
Grafos - 11
Árvores de expansão mínimas
Árvore que liga todos os vértices do grafo usando arestas com um custo total mínimo
•
caso do grafo não dirigido
•
grafo tem que ser conexo
•
árvore  acíclico
•
número de arestas = |V| - 1
 exemplo de aplicação: cablamento de uma casa
- vértices são as tomadas
- arestas são os comprimentos dos troços
Grafos - 12
Algoritmo de Prim
 expandir a árvore por adição sucessiva de arestas e respectivos vértices
•
critério de selecção: escolher a aresta (u,v) de menor custo tal que u já pertence à
árvore e v não (ganancioso)
•
início: um vértice qualquer
 idêntico ao algoritmo de Dijkstra para o caminho mais curto
•
informação para cada vértice
- dist(v) é o custo mínimo das arestas que ligam a um vértice já na árvore
- path(v) é o último vértice a alterar dist(v)
- known(v) indica se o vértice jé foi processado (isto é, se já pertence à árvore)
•
diferença na regra de actualização: após a selecção do vértice v, para cada w não
processado, adjacente a v, dist(w) = min{ dist(w), cost(w,v) }
•
tempo de execução
- O( |V|2 ) sem fila de prioridade
- O( |E| log |V| ) com fila de prioridade
Grafos - 13
Evolução do algoritmo de Prim
4
2
1
5
7
4
8
5
4
1
6

10
3
2
3
2
1
última
tabela
6
7


1
1
2
1

3
1
2
2
2
1
4

3
4
1
2
known
1
1
1
1
1
1
1

2
1
4
v
1
2
3
4
5
6
7
2
1
4
4

3
2
4
2
7
1
2
1
5
4
4
6
2
1
2
1
path
0
1
4
1
7
7
4
2
1
3
2
dist
0
2
2
1
6
1
4
4
7
6
1
7
6
Grafos - 14
Algoritmo de Kruskal
 analisar as arestas por ordem crescente de peso e aceitar as que não provocarem
ciclos (ganancioso)
 método
•
manter uma floresta, inicialmente com um vértice em cada árvore (há |V|)
•
adicionar uma aresta é fundir duas árvores
•
quando o algoritmo termina há só uma árvore (de expansão mínima)
 aceitação de arestas — algoritmo de Busca/União em conjuntos
•
representados como árvores
•
se dois vértices pertencem à mesma árvore/conjunto, mais uma aresta entre eles
provoca um ciclo (2 Buscas)
•
se são de conjuntos disjuntos, aceitar a aresta é aplicar-lhes uma União
 selecção de arestas: ordenar por peso ou, melhor, construir fila de prioridade em tempo
linear e usar Apaga_Min
•
tempo no pior caso O( |E| log |E| ), dominado pelas operações na fila
Grafos - 15
Pseudocódigo (Kruskal)
void kruskal()
{
DisjSet s;
PriorityQueue h;
Vertex u, v;
SetType uset, vset;
Edge e,
int edgesAccepted = 0;
h = readGraphIntoHeapArray();
h.buildHeap();
s = new DisjSet(NUM_VERTICES);
}}
while(edgesAccepted < NUM_VERTICES -1 )
{
e = h.deleteMin();
// e = (u,v)
uset = s.find(u);
vset = s.find(v);
if (uset != vset)
{
edgesAccepted++;
S.union(uset, vset);
}
Grafos - 16
Evolução do algoritmo de Kruskal
4
1
1
5
2
7
4
8
4
1
6
1
2
10
3
2
3

2
3
5
6
6
7
5
4

7

1
1
2
1
1
3
5
4
6
7
2
3
5
4
6
1
7
Grafos - 17
Evolução do algoritmo de Kruskal
4
2
1
2
3
5
2
1
7
4
8
4
1
6

10
3
7
2
1
5
3
6
2
5
4

2
1
7
2
1
1
3
2
1
6

2
1
2
1
5
4
3
2
5
4
4
6
1
7

1
3
2
2
6
2
1
7
1
4
5
4
6
1
7
6
Grafos - 18
Download

Grafos: fluxos e árvores de expansão