78
CLEVERSON AFONSO BOFF CLEVERTON APARECIDO KRENSKI JULIANO LORENZET MODELAGEM DE FLUXOS DE TRABALHO UTILIZANDO HIPERGRAFOS DIRECIONADOS CURITIBA 2009

MODELAGEM DE FLUXOS DE TRABALHO UTILIZANDO ... - … · diagrama de modo a facilitar a visualizac¸ao do problema.˜ O exemplo abaixo representa um fluxo de tarefas onde cada tarefa

  • Upload
    lyduong

  • View
    221

  • Download
    0

Embed Size (px)

Citation preview

CLEVERSON AFONSO BOFFCLEVERTON APARECIDO KRENSKI

JULIANO LORENZET

MODELAGEM DE FLUXOS DE TRABALHO UTILIZANDOHIPERGRAFOS DIRECIONADOS

CURITIBA

2009

CLEVERSON AFONSO BOFFCLEVERTON APARECIDO KRENSKI

JULIANO LORENZET

MODELAGEM DE FLUXOS DE TRABALHO UTILIZANDOHIPERGRAFOS DIRECIONADOS

Trabalho de Conclusao de Curso apresentado abanca examinadora da Universidade Federal doParana, como exigencia para obtencao do tıtulode Bacharel em Ciencia da Computacao.

Orientador: Prof. Dr. Andre Luiz Pires Gue-des

CURITIBA

2009

Sumario

Lista de Figuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v

Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii

Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii

1 Introducao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 Fluxo de Tarefas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.1 Paralelismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3 Conceitos e Fundamentacao Teorica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.1 Hipergrafo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.2 Hipergrafo Direcionado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.3 Hiper-Caminho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.4 Conexao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.5 Propriedades sobre conjuntos de hiper-arcos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.5.1 Propriedade B. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.5.2 Propriedade F . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.5.3 Propriedade S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.5.4 Ciclos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

ii

iii

3.6 HSPD - Hipergrafos Serial-Paralelo-Disjuncao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.7 Modelagem de fluxos de tarefas com Hipergrafos Direcionados . . . . . . . . . . . . . . . 12

3.8 Informacoes pre-existentes na estrutura de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.8.1 OU-F-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.8.2 OU-B-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.8.3 E-F-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.8.4 E-B-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.9 Detalhamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.10 Trechos de execucao opcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4 Definicoes Adotadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5 Execucao do fluxo sobre Hipergrafos Direcionados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.1 Um algoritmo para execucao de fluxo de tarefas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.1.1 Funcao Execucao (Principal) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.1.2 Funcao realizaTrabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.1.3 Funcao verificaDependencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

6 Paralelismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

6.1 Grau de paralelismo da execucao em um instante t . . . . . . . . . . . . . . . . . . . . . . . . . . 28

6.2 Grau de paralelismo maximo em um instante t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

6.3 Grau de paralelismo maximo do hipergrafo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

6.4 Grau maximo medio de paralelismo do hipergrafo . . . . . . . . . . . . . . . . . . . . . . . . . . 30

7 Algoritmos para Calculo do Maior Paralelismo em Hipergrafos Direcionados . . . . 31

iv

7.1 Algoritmo A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

7.1.1 Consideracoes iniciais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

7.1.2 Funcionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

7.1.3 Pseudocodigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

7.2 Algoritmo B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

7.2.1 Consideracoes iniciais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

7.2.2 Funcionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

7.2.3 Pseudocodigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

8 Conclusao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Referencias Bibliograficas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

Anexo A -- Algoritmo (A) para calculo do maior paralelismo . . . . . . . . . . . . . . . . . . . . . . . . 51

Anexo B -- Algoritmo (B) para calculo do maior paralelismo . . . . . . . . . . . . . . . . . . . . . . . . 58

Anexo C -- Estrutura de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

Lista de Figuras

Figura 1.1 Um exemplo de workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

Figura 3.1 Hipergrafo Direcionado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Figura 3.2 Hiper-caminho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Figura 3.3 Fluxo de controle modelado atraves de um Hipergrafo Direcionado . . . . . . . . 11

Figura 3.4 Um exemplo de fluxo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Figura 3.5 Um exemplo de OU-F-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Figura 3.6 Um exemplo de OU-B-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

Figura 3.7 Um exemplo de E-F-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

Figura 3.8 Um exemplo de E-B-Condicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Figura 3.9 Um hipergrafo direcionado incompatıvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Figura 3.10 Um exemplo de modelagem de fluxo com trecho de execucao opcional . . . . . 19

Figura 6.1 Um Hipergrafo Direcionado com trechos de execucao paralela . . . . . . . . . . . . 27

Figura 6.2 Destaque das tarefas que podem ser executadas paralelamente . . . . . . . . . . . . . 27

Figura 6.3 Calculo do grau de paralelismo em cada instante da execucao . . . . . . . . . . . . . 29

Figura 6.4 Grau medio de paralelismo do hipergrafo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

Figura 7.1 Hipergrafo Direcionado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

v

vi

Figura 7.2 Fluxo de Tarefas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

Figura 7.3 Um exemplo de lista de tempos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Figura 7.4 Criacao dos itens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

Resumo

Este trabalho tem como objetivo estudar a modelagem de problemas relacionados a fluxos de

atividades atraves de hipergrafos direcionados. Realizando alguns calculos e tirando proveito

das vantagens deste modelo de representacao, buscamos otimizar os recursos disponıveis, en-

contrando no hipergrafo direcionado possıveis tarefas que podem ser realizadas simultanea-

mente. Assim, conseguimos determinar o numero maximo de execucoes paralelas em um de-

terminado fluxo de atividades.

Palavras chave: Hipergrafos, Fluxo, Paralelismo, Fluxo de Atividades.

vii

Abstract

This paper’s goal is to study the modeling of problems related to workflows through directed

hypergraphs. Performing some calculations and taking advantages of this representation model,

we sought to optimize the availables resources, finding on directed hypergraph possible tasks

that could be simultaneously performed. Therefore, we could determine the maximum number

of parallels executions in a determined workflow.

Keywords: Hypergraphs, flow, parallelism, workflow.

viii

1

1 Introducao

E muito comum nos depararmos com determinadas situacoes onde eventos devem

acontecer obedecendo a uma certa ordem, pois existe uma relacao de dependencia a aconte-

cimentos anteriores. Este conjunto de eventos nada mais e do que um fluxo de tarefas, que pode

ser modelado de diversas formas.

Neste trabalho sera apresentado um estudo sobre a modelagem de problemas relaci-

onados a fluxos de atividades atraves de hipergrafos direcionados. Com a analise desta estru-

tura, busca-se determinar o numero maximo de execucoes paralelas em um determinado fluxo,

numero esse utilizado para auxiliar em um melhor dimensionamento dos recursos disponıveis.

Temos como exemplo os processos de negocios, em que algo ou alguem executa um

trabalho que e pre-requisito para o inıcio de algum outro trabalho, ou seja, a execucao e termino

de determinada tarefa permite o inıcio de uma ou mais tarefas seguintes. Uma possıvel situacao

para este exemplo seria em construcao civil. Nas construcoes, as paredes so podem ser ergui-

das depois que o alicerce foi construıdo, a estrutura do telhado so pode ser iniciada depois das

paredes terem sido erguidas, e assim por diante. Na computacao tambem existe esta relacao de

dependencia, pois determinadas instrucoes ou procedimentos devem ser executados em deter-

minada ordem para que o resultado apresentado seja correto. Nos casos apresentados acima,

alem de muitos outros que se encaixam neste perfil de problema, e necessario que as tarefas

sejam executadas no menor tempo possıvel.

Poderıamos pensar entao em executar cada tarefa do conjunto separadamente e parale-

lamente, visando um melhor desempenho, ou mesmo a minimizacao do custo e otimizacao de

tempo e recursos. Mas nem sempre isso e tao simples, pois podem existir dependencias entre

2

determinadas tarefas, o que significa que tarefas que dependam de resultados ou dados gerados

por outras tarefas so podem ser executadas depois que as tarefas responsaveis por gerar os dados

ou os resultados tenham sido finalizadas.

Para representar este fluxo de tarefas e as dependencias entre elas podemos usar um

diagrama de modo a facilitar a visualizacao do problema.

O exemplo abaixo representa um fluxo de tarefas onde cada tarefa e representada por

um cırculo e as setas representam as dependencias.

Figura 1.1: Um exemplo de workflow

Nesta figura esta representado um exemplo de sequencia de passos para lavagem de

roupas. Primeiramente as roupas sao lavadas e posteriormente centrifugadas para acelerar o

processo de secagem, que e feito logo em seguida. Quando o processo de secagem termina as

roupas sao entao passadas e finalmente guardadas.

Em alguns casos, nao temos um fluxo tao linear como o exemplo acima, no qual podem

3

existir tarefas simultaneas ou tomadas de decisoes que resultam em tarefas excludentes, ou seja,

momentos nos quais uma tarefa deve ser executada juntamente com outra ou em outros casos,

deve ser tomada uma decisao que escolhera apenas uma tarefa para execucao. Com isso caımos

em condicoes E e condicoes OU, respectivamente, que discutiremos no momento apropriado.

Computacionalmente, podemos utilizar um hipergrafo direcionado, definido mais adi-

ante, para modelar um fluxo como o do exemplo, ou um fluxo mais complexo contendo condicoes

E e OU. No hipergrafo direcionado cada tarefa e representada por um vertice e os hiper-arcos

representam as dependencias[STIVANIN, 2006].

Para que os recursos sejam utilizados da melhor forma e auxiliem na melhoria do

desempenho do processo, e necessario algum tipo de analise, pois caso contrario, e possıvel que

se aumente o desperdıcio em decorrencia da sobrecarga de alguns componentes.

A otimizacao do tempo e dos recursos disponıveis de modo que permanecam ociosos

pelo menor tempo possıvel auxilia na diminuicao dos custos e em contrapartida aumenta a

produtividade.

Encontrar o maior grau de paralelismo com o intuito de otimizar os recursos e acelerar

a resolucao dos problemas e o nosso objeto de estudo.

4

2 Fluxo de Tarefas

Fluxo de tarefas e uma sequencia de passos necessarios para que se possa atingir um

objetivo, de acordo com um conjunto de regras definidas, envolvendo a nocao de processos e

permitindo que estes possam ser transmitidos de uma entidade para outra obedecendo a algumas

regras.

Um processo de work f low, fluxo de trabalho ou de tarefas pode ser entendido como

um conjunto de atividades interligadas por transicoes, que deve ser executado em uma or-

dem de tal forma que alcance um objetivo. Assim podemos ter diversos processos, tais como:

solicitacao de servicos, reserva de recursos, prestacao de contas.

Podemos representar um fluxo de tarefas atraves de fluxogramas, que e um tipo de

diagrama que pode ser entendido como uma representacao esquematica de um processo, mui-

tas vezes construıdo atraves de graficos que ilustram de forma descomplicada a transicao de

informacoes entre os elementos que o compoem [SERRALHEIRO, 2008]. Podemos entender

os fluxogramas na pratica, como a documentacao dos passos necessarios para a execucao de um

processo qualquer. O fluxograma e uma das Sete Ferramentas da Qualidade, muito utilizada em

fabricas e industrias para a organizacao de produtos e processos.

Assim, alguns conceitos basicos envolvendo o fluxograma podem ser definidos:

• Processo: e o mapeamento do fluxo;

• Atividades, tarefas, trabalhos: sao procedimentos a serem executados;

• Transicoes: sao elementos de ligacao entre as atividades que determinam o caminho que

5

o fluxo seguira; [PARANA, 2008]

Temos tambem o conceito de instancias. Sempre que o fluxo for iniciado, uma instancia de

execucao sera gerada. As instancias representam as ocorrencias de execucao de um processo. A

execucao percorrera um determinado caminho no fluxo ate chegar na atividade final, o objetivo

da execucao do fluxo [PARANA, 2008].

2.1 Paralelismo

A execucao simultanea de tarefas pode ser a solucao para muitos problemas de otimizacao

em que deseja-se ganhar tempo realizando varias tarefas o mais rapido possıvel. Quando dispo-

mos de mais de um recurso, podendo ser esse recurso, mao de obra, processadores, maquinas

ou qualquer entidade que possa realizar uma tarefa, podemos ter execucoes paralelas.

Alem da diminuicao do tempo total de realizacao de uma sequencia de atividades,

o paralelismo permite que separemos o problema em varios pedacos, onde varias entidades

possam executar o trabalho simultaneamente. Ao final, juntamos os resultados de cada pedaco

e temos o resultado geral do problema. Por outro lado, criamos novos desafios e problemas que

as vezes sao tao complexos quanto os problemas originais [ROBERTO, 2008].

Para mapearmos um problema ou um processo qualquer que envolva execucoes para-

lelas, devemos observar que ao utilizarmos o paralelismo, temos a necessidade que as respostas

e as trocas de informacoes acontecam de forma correta [ROBERTO, 2008] e alem disso te-

mos que garantir que todas as dependencias estao satisfeitas e principalmente que as tarefas

executadas paralelamente nao dependam umas das outras.

Quando temos processos e fluxos de trabalho que possibilitam a execucao paralela de

tarefas, as vezes nao dispomos de recursos suficientes para tal, como por exemplo, em uma em-

presa em que um determinado processo, cinco tarefas podem perfeitamente serem executadas

em paralelo, mas a empresa dispoe de apenas tres funcionarios para a equipe responsavel pelo

processo. Neste caso, duas tarefas que poderiam ser executadas em conjunto, economizando

6

tempo, ficam pendentes, esperando o termino de alguma, por falta de mao de obra. Este pro-

blema ocorre frequentemente, pois o gestor responsavel pela gerencia dos recursos nao soube,

ou nao teve, como dimensionar sua equipe ou a quantidade de maquinas para a realizacao das

atividades. Em muitos casos, nao e possıvel o dimensionamento dos recursos, simplesmente

porque o gestor nao sabe quantas tarefas podem ser executadas paralelamente em determinado

fluxo de atividades. Tal resposta, que pode ser simples em fluxos pequenos, pode ser bastante

complexa em fluxos grandes. Uma ferramenta que faz justamente o calculo de quantas ativida-

des podem ser executadas paralelemante em um fluxo sera discutida mais adiante.

7

3 Conceitos e Fundamentacao Teorica

3.1 Hipergrafo

Um Hipergrafo e uma generalizacao de um grafo. Um grafo e um par ordenado de

conjuntos finitos (V,E) tal que E ⊆ C2V onde V e um conjunto de vertices e E e um conjunto

de arestas [DONADELLI, 2008]. O hipergrafo, por sua vez, e um par ordenado de conjuntos

finitos (V,E), porem temos E ⊆ 2V onde V e um conjunto de vertices e E e um conjunto de

hiper-arcos tal que a cardinalidade do hiper-arco pode ser diferente de 2 [GUEDES, 2001].

3.2 Hipergrafo Direcionado

Um hipergrafo direcionado H = (V,E) e uma dupla, onde V e um conjunto finito de

vertices e E e um conjunto de hiper-arcos. Um hiper-arco e pertencente a E e um par ordenado

(X ,Y ) tais que X e Y sao subconjuntos disjuntos de V . Dado um hipergrafo direcionado H =

(V,E), e um hiper-arco e = (X ,Y ) pertencente a E, chamamos X de origem e Y de destino,

respectivamente denotamos por Org(e) e Dest(e). Podemos usar esta notacao tambem para

conjuntos de hiper-arcos. Assim, se A e um conjunto de hiper-arcos, entao:

Org(A) = ∪e∈A Org(e);

Dest(A) =∪e∈A Dest(e). Tambem podemos definir os conjuntos que representam as relacoes de

incidencia em um hipergrafo direcionado, que sao BS(v) e FS(v), chamados de hiper-arcos de

entrada e hiper-arcos de saıda de v, respectivamente, onde v ∈V de um hipergrafo direcionado

H = (V,E). As letras B e F representam as expressoes backward e forward, respectivamente.

BS(v) = {e|v ∈ Dest(e)} (Entrada);

8

FS(v) = {e|v ∈ Org(e)} (Saıda); [GUEDES, 2001]

Na figura 3.1 podemos ver o hipergrafo direcionado H =(V,E), onde V = {1,2,3,4,5,6,7},

e E = {a,b,c,d,e}. Como exemplo de hiper-arco temos a = ({1,2},{4,5}).

Figura 3.1: Hipergrafo Direcionado

3.3 Hiper-Caminho

Dado um Hipergrafo direcionado H = (V,E), e dois vertices s e t, um hiper-caminho

de s a t, de tamanho k, e uma sequencia de hiper-arcos C = (ei1,ei2, ...,eik) onde s pertence a

Org(ei1) e t pertence a Dest(eik), e para cada hiper-arco eip de C com 1≤ p≤ k temos que:

Org(eip)∩ (Dest(ei1,ei2, ...,eip−1)∪{s}) 6= {};

Dest(eip)∩ (Org({eip+1,eip+2, ...,eik})∪{t}) 6= {}.

Onde Org(ei1) e Dest(eik) sao Org(C) e Dest(C), respectivamente [GUEDES, 2001].

Na figura 3.2 podemos ver um exemplo de hiper-caminho no hipergrafo da figura 3.1.

O hiper-caminho C = {a,c,d}, de 1 a 7, tem origem {1,2} e destino {7}.

9

Figura 3.2: Hiper-caminho

3.4 Conexao

Dizemos que um vertice x esta hiper-conectado ou simplesmente conectado ao vertice

y se existe um hiper-caminho de x a y.

3.5 Propriedades sobre conjuntos de hiper-arcos

3.5.1 Propriedade B

Seja C um conjunto de hiper-arcos, um hiper-caminho de C, de s a t, de tamanho k,

tem a propriedade B se, para cada hiper-arco eip de C, com 1 ≤ p ≤ k, temos que: Org(eip) ⊆

(Dest({ei1,ei2, ...,eip−1})∪{s}) [GUEDES, 2001].

Um hiper-caminho com esta propriedade e um B-caminho.

3.5.2 Propriedade F

Um hiper-caminho de C, de s a t, de tamanho k, tem a propriedade F se, para cada

hiper-arco eip de C, com 1 ≤ p ≤ k, temos que: Dest(eip) ⊆ (Org({eip+1,eip+2,...,eik}) ∪ {t})

[GUEDES, 2001].

Um hiper-caminho com esta propriedade e um F-caminho.

10

3.5.3 Propriedade S

Seja Hc o hipergrafo direcionado induzido por C. O conjunto C tera a propriedade S se,

para todo vertice x de Hc, |FS(x)| ≤ 1 e |BS(x)| ≤ 1, ou seja, cada vertice aparece no maximo

em um conjunto origem e um conjunto destino de C. Assim podemos definir um outro tipo de

hiper-caminho [GUEDES, 2001].

Um hiper-caminho com esta propriedade e um S-caminho.

A letra S utilizada aqui representa a expressao star.

Um hipergrafo pode conter as tres propriedades simultaneamente B, F e S. E este tipo

de hiper-caminho que sera utilizado.

3.5.4 Ciclos

Um ciclo e um hiper-caminho C onde Org(C)∩Dest(C) 6= {} [GUEDES, 2001].

3.6 HSPD - Hipergrafos Serial-Paralelo-Disjuncao

Da mesma maneira como os fluxos de tarefas sequenciais podem ser modelados utilizando-

se dos grafos direcionados, como na figura 1.1, seria interessante que problemas que contenham

paralelismo tambem pudessem ser modelados. Para isso utilizamos os Hipergrafos Direciona-

dos. Para apresentar os problemas que possuem paralelismos de uma maneira estruturada po-

demos utilizar a classe dos Hipergrafos Serial-Paralelo-Disjuncao (HSPD), que sera definida a

seguir.

Um hipergrafo de controle Hp = (V,E,s, t) associado a um programa paralelo P e uma

quadrupla onde (V,E) e um hipergrafo direcionado, s ∈ V e o vertice origem, em que neste hi-

pergrafo existe um B-caminho de s para qualquer outro vertice em V , e um vertice t pertencente

a V , onde:

1. cada instrucao (ou conjunto de instrucoes elementar) de P e um vertice de V ;

11

2. cada dependencia de execucao entre instrucoes de P e um hiper-arco de E;

3. s e o vertice inıcio e t o vertice final. [GUEDES, 2001]

Abaixo temos um hipergrafo direcionado que modela o seguinte fluxo de controle:

int a = 0, b = 0; (P1)

if (a < 10){ (P2)

a++; (P3)

b–; (P4)

}

else{ (P5)

a–; (P6)

b++; (P7)

}

Figura 3.3: Fluxo de controle modelado atraves de um Hipergrafo Direcionado

Com base na figura 3.3 acima podemos descrever como ocorre a execucao do fluxo

sobre o hipergrafo apresentado. A execucao inicia-se pelo passo 1 (P1). Quando a execucao

chega em P2 uma decisao deve ser tomada. Executam-se, entao, os passos 3 e 4 OU os passos 6

e 7. Se a condicao do passo 2 for satisfeita entao, P3 e P4 devem ser executados, e esta execucao

pode ser feita em paralelo, pois uma nao depende da outra. Caso a condicao seja falsa, entao,

os passos 6 e 7 devem ser executados. Note que a condicao em P2 gera um OU-Exclusivo, se

P3 e P4 forem executados, P5 nao sera executada, e vice-versa.

12

Finalmente podemos definir os hipergrafos Serial-Paralelo-Disjuncao. Esta famılia de

hipergrafos se faz bastante util para representarmos fluxos de controle de programas escritos em

linguagens que suportam estruturas do tipo if-then-else, case, while, etc.

Um hipergrafo Serial-Paralelo-Disjuncao (HSPD) H = (V,E,s, t) e um hipergrafo di-

recionado e os dois vertices, s e t, satisfazem uma das condicoes abaixo:

• Trivial: V = s.E = 0 e t = s.

• Serial: V = V1 ∪ V2, E = E1 ∪ E2 ∪ {({t1},{s2})}, s = s1 e t = t2, onde H1 = (V1, E1, s1,

t1) e H2 = (V2, E2, s2, t2) sao HSPDs (nao necessariamente distintos).

• Paralelo: V = ∪ki=1Vi ∪

{s, t},E = ∪ki=1Ei∪ {({s},{s1,...,sk}), ({t1,...,tk},{t})}, onde Hi = (V,Ei, si, ti). com i =

1...k, sao HSPDs distintos, e s e t sao vertices novos.

• Disjuncao: V = ∪ki=1Vi

∪ {s,t}, E = ∪ki=1

(Ei ∪{({s},{Si}),({ti},{t})}), onde Hi = (vi, Ei, si, ti), com i = 1...k, sao HSPDs distintos,

e s e t sao vertices novos.

Em todas estas condicoes, quando os HSPDs Hi forem distintos tambem devem ser disjuntos

[GUEDES, 2001].

3.7 Modelagem de fluxos de tarefas com Hipergrafos Direci-onados

O objeto de estudo deste trabalho e a modelagem de um fluxo de atividades ou tarefas,

atraves de um hipergrafo direcionado no qual os vertices representam as atividades [STIVANIN,

2006] e os hiper-arcos representam dependencias e tarefas que precisam ser cumpridas para

que as atividades sejam concluıdas; Cada atividade possui caracterısticas proprias como por

exemplo, o tempo para ser executada.

13

Figura 3.4: Um exemplo de fluxo

No exemplo da figura 3.4, as tarefas sao representadas pelos vertices e sao nomeadas de

“A”ate “K”. Para cada tarefa existem hiper-arcos que saem e que chegam aos vertices. Os hiper-

arcos que saem indicam as proximas tarefas que necessitam ser realizadas apos a conclusao da

tarefa atual. Os que chegam indicam dependencias para o inıcio da realizacao da nova tarefa

gerada.

3.8 Informacoes pre-existentes na estrutura de dados

Com os hipergrafos direcionados, e possıvel modelar e visualizar no nıvel de estrutura

de dados, uma serie de informacoes relevantes sem a necessidade de anexos, como variaveis

auxiliares que nao pertencem a estrutura basica. Assim e possıvel visualizar e modelar com

facilidade as dependencias entre as tarefas. Podemos descrever e obter varios tipos de condicoes

e dependencias atraves da estrutura basica do hipergrafo-direcionado, sendo possıvel verifcar

14

as condicoes definidas adiante:

3.8.1 OU-F-Condicao

Sejam u, v e w vertices distintos de um hipergrafo, e E1,E2,...,En conjuntos distintos

de hiper-arcos que partem de u, formando hiper-caminhos entre u e v e entre u e w. Assim,

podemos definir uma OU-F-Condicao como sendo duas ou mais sequencias de hiper-arcos dis-

tintas que ligam os dois extremos de um hiper-caminho, porem somente um dos hiper-caminhos

possıveis precisa ser percorrido para que uma determinada condicao seja satisfeita. Tendo

u como o extremo inicial v e w como opcoes de destino, sendo que somente um dos hiper-

caminhos deve ser tomado. Por questoes de nomenclatura chamaremos de OU-F-Condicao,

mas o mais correto seria XOR-F-Condicao, por se tratar de um OU exclusivo.

Figura 3.5: Um exemplo de OU-F-Condicao

3.8.2 OU-B-Condicao

Sejam u, v e w vertices distintos de um hipergrafo, e E1,E2,...,En conjuntos distintos

de hiper-arcos que chegam em u, formando hiper-caminhos entre v e u e entre w e u. Assim,

podemos definir uma OU-B-Condicao como sendo duas ou mais sequencias de hiper-arcos dis-

tintas que ligam os dois extremos de um hiper-caminho, porem somente um dos hiper-caminhos

possıveis precisa ser percorrido para que uma determinada condicao seja satisfeita. Tendo v e

w como extremo inicial u como destino, sendo que somente um dos hiper-caminhos deve ser

tomado. Por questoes de nomenclatura chamaremos de OU-B-Condicao, mas o mais correto

seria XOR-B-Condicao, por se tratar de um OU exclusivo.

15

Figura 3.6: Um exemplo de OU-B-Condicao

3.8.3 E-F-Condicao

Sejam u, v e w vertices distintos de um hipergrafo, e E1,E2,...,En conjuntos distintos

de hiper-arcos que partem de u, formando hiper-caminhos entre u e v e entre u e w. Assim, po-

demos definir uma E-F-Condicao como sendo duas ou mais sequencias de hiper-arcos distintas

que ligam os dois extremos de um hiper-caminho, sendo que todos os hiper-caminhos possıveis

precisam ser percorridos para que uma determinada condicao seja satisfeita. Considerando u

como o extremo inicial v e w como destinos. Obrigatoriamente todos os hiper-caminhos que sa-

tisfazem a E-F-Condicao precisam ser percorridos para que v e w sejam alcancados e visitados.

Figura 3.7: Um exemplo de E-F-Condicao

3.8.4 E-B-Condicao

Sejam u, v e w vertices distintos de um hipergrafo, e E1,E2,...,En conjuntos distintos de

hiper-arcos que chegam em u, formando hiper-caminhos entre v e u e entre w e u. Assim, po-

demos definir uma E-B-Condicao como sendo duas ou mais sequencias de hiper-arcos distintas

que ligam os dois extremos de um hiper-caminho, sendo que todos os hiper-caminhos possıveis

precisam ser percorridos para que uma determinada condicao seja satisfeita. Considerando v

16

e w como o extremo inicial e u como destino. Obrigatoriamente todos os hiper-caminhos que

satisfazem a E-B-Condicao precisam ser percorridos para que u seja alcancado e visitado.

Figura 3.8: Um exemplo de E-B-Condicao

3.9 Detalhamento

Voltando ao exemplo da figura 3.4. O ponto de inıcio da execucao do fluxo e a tarefa

nomeada por “A”. “A” nao tem pai, portanto, e a tarefa inicial.

Proposicao: Seja o vertice v, se BS(v) = {}, entao v e o vertice inicial do fluxo.

Dizemos que o fluxo F e inicializavel, se para todo vertice v pertencente a F , existe

somente um vertice v, onde BS(v) = {}. Se existir mais de um vertice que satisfaca esta condicao

(BS(v) = {}), entao o fluxo e denotado multi-inicializavel. Se nao existir nenhum vertice tal que

BS(v) = {}, o fluxo e denominado nao-inicializavel.

Imediatamente apos a conclusao da Tarefa “A”, e gerada a Tarefa “B” (utilizaremos o

verbo “gerar” para indicar que uma tarefa pode e deve ser executada). Neste momento inicia-se

a execucao de “B”, verificando-se ao mesmo tempo se as dependencias de “B” foram atendidas,

neste caso a execucao da Tarefa “B”. Cada tarefa necessita de um tempo para ser executada e

apos o seu termino novas tarefas sao iniciadas e geradas. Concluindo-se a Tarefa “B”, inicia-se a

tarefa subsequente, no exemplo a Tarefa “C”. Ao termino da execucao de “C” uma decisao deve

ser tomada, pois temos mais de um hiper-arco partindo do vertice correspondente a Tarefa “C”.

Neste caso apenas um dos caminhos deve ser tomado, pois se trata de uma OU-F-Condicao. Se

escolhermos a Tarefa “H” como a proxima tarefa, o fluxo seguira normalmente ate a conclusao

da Tarefa “J”, havendo, entao, a tentativa de gerar a Tarefa “K”. Como existe mais de um

hiper-arco chegando em “K”, ou seja, temos uma OU-B-Condicao, algumas condicoes devem

17

ser verificadas. Neste caso, “K” podera ser gerada, pois apenas um dos pre-requisitos precisam

ser satisfeitos, neste caso a execucao de “J”. Voltando a Tarefa “C”, toma-se agora o caminho

indicado pela Tarefa “D”. O fluxo sera percorrido normalmente ate a finalizacao da execucao

de “E”, onde temos uma ramificacao no hiper-arco de saıda. Esta ramificacao significa que

todas as tarefas indicadas por esse hiper-arco como proximas deverao ser geradas. Neste caso

temos uma E-F-Condicao. Assim, as Tarefas “F”e “G”sao geradas e percorridas em paralelo.

Portanto, sao nestes casos, onde temos E-F-Condicoes, que ocorre o paralelismo de execucao

de tarefas. Ao termino da execucao de “F” e “G” as proximas tarefas convergem para uma so,

a Tarefa “K”. “K”so pode ser gerada se, e somente se, “F”e “G” tiverem sido executadas.

Esta condicao pode ser verificada atraves do hiper-arco {{F,G},{K}} onde temos uma E-B-

Condicao. Como “F”e “G” ja foram finalizadas, a Tarefa “K” e gerada e executada. Assim, a

execucao do fluxo finaliza com a conclusao da execucao de “K”.

Considere a situacao na qual sai-se de um vertice “A” atraves de um hiper-arco e, por

dois hiper-caminhos p1 e p2, onde p1 e p2 possuem uma ou mais atividades, e ambos os hiper-

caminhos convergem para um vertice “B”atraves de um hiper-arco OU. Neste caso a execucao

do fluxo segue a partir de “B” no momento em que o primeiro hiper-caminho chegar em “B”,

marcando o vertice “B”como “executado” para nao executar novamente quando o outro hiper-

caminho chegar em “B”.

Considere a situacao onde saımos de um vertice “A” atraves de um hiper-arco OU,

por dois hiper-caminhos p1 e p2, onde p1 e p2 possuem uma ou mais atividades, e ambos os

hiper-caminhos convergem para um vertice “B” atraves de um hiper-arco “E”. O hipergrafo e

considerado inconsistente, pois em “A”ele possibilitou uma escolha onde apenas um dos hiper-

caminhos sera executado, mas em “B” e exigido que os dois hiper-caminhos, p1 e p2, tenham

sido percorridos.

No exemplo da figura 3.9, “D” requer a execucao de “B” e “C”, porem nunca podera

ser alcancada, pois apenas “B” ou “C” sera executada. Assim, um fluxo pode ser qualificado da

seguinte forma:

18

Figura 3.9: Um hipergrafo direcionado incompatıvel

Quanto a inicializacao:

• mono-inicializavel (para simplificar, chamaremos apenas de inicializavel);

• multi-inicializavel;

• nao-inicializavel.

Quanto ao seu percurso:

• compatıvel;

• incompatıvel.

Dizemos que um fluxo nao-inicializavel ou incompatıvel e intratavel.

19

3.10 Trechos de execucao opcionais

Com hipergrafos direcionados podemos modelar tarefas que nao necessariamente pre-

cisam ser executadas para a conclusao do fluxo. Para isto, utilizamos uma combinacao especial

de hiper-arcos e vertices. Esta combincao consiste em uma condicao OU onde um dos hiper-

arcos tem seu conjunto |Origens| > 1 (hiper-arcos b e c do diagrama abaixo). Na execucao do

fluxo, as tarefas pertencentes ao conjunto destino do hiper-arco no qual o tamanho do conjunto

Origens e maior do que 1 ficarao pendentes ate que todas as tarefas do conjunto Origens sejam

finalizadas. Assim, todas as tarefas pertencentes ao conjunto destino deste hiper-arco serao exe-

cutadas obrigatoriamente, mesmo que uma das origens da aresta pertenca a uma condicao OU.

Neste caso as outras hiper-arestas que pertercam ao OU podem ser percorridas opcionalmente,

visto que umas das condicoes ja esta satisfeita.

Para demonstrar um desses casos, podemos utilizar o exemplo abaixo.

Figura 3.10: Um exemplo de modelagem de fluxo com trecho de execucao opcional

Perceba o retangulo na figura composto pelos vertices e hiper-arcos ditos opcionais.

Nos hiper-arcos de saıda do vertice B temos dois hiper-arcos formando um OU, note que o

hiper-arco c tem seu conjunto |Origens| > 1. O vertice G sempre sera executado, (salvo a

20

excecao de B, C ou D, nunca terminarem). Neste caso, a opcao de se executar a tarefa G

nao ocorreu em consequencia da escolha realizada da OU-F-Condicao em B, mas sim da E-B-

Condicao em B,C e D. O hiper-arco b ainda pode ser escolhido para execucao, porem ja temos

o hiper-arco c pertencente ao hiper-caminho da execucao do fluxo. Sendo assim, a execucao de

E, F e H nao precisa acontecer obrigatoriamente para a finalizacao do fluxo, enquanto que os

vertices G e I serao sempre executados, independente da escolha em B.

21

4 Definicoes Adotadas

Para efeito deste estudo consideraremos apenas fluxos trataveis, ou seja, fluxos inicia-

lizaveis e compatıveis. Sendo que os hipergrafos da classe hipergrafo Serial-Paralelo-Disjuncao

(HSPD), sao os que melhor atendem a estes requisitos.

Dependencia: definimos como dependencia a relacao entre os vertices de destino e os vertices

de origem de um hiper-arco. Para a execucao dos vertices do conjunto de vertices de destino de

um hiper-arco e necessario que todos os vertices do conjunto de origem estejam finalizados.

Utilizacao de vertices dependentes: Nos hipergrafos utilizados neste documento existem

varios exemplos onde ocorrem dependencias. As tarefas dependentes so podem ser executa-

dos depois que a dependencia foi resolvida. Assume-se que uma determinada tarefa que ja

tenha sido executada sera considerada finalizada durante a execucao de todo o fluxo, ou seja,

tarefas que dependam desta execucao nao precisam faze-la novamente. Assim, tarefas que ja

foram finalizadas podem ser usadas quantas vezes forem necessarias durante uma execucao. Ha

casos em que poderia ser interessante o vertice dependente ser usado apenas umas vez durante

a execucao, porem este caso nao sera abordado aqui.

22

5 Execucao do fluxo sobre Hipergrafos Direcionados

Este capıtulo apresenta o funcionamento de um algoritmo simples para execucao de

fluxos modelados com hipergrafos direcionados.

5.1 Um algoritmo para execucao de fluxo de tarefas

Genericamente a modelagem sobre um hipergrafo direcionado segue a seguinte logica:

a partir do vertice inicial I escolhe-se uma hiper-aresta pertencente ao conjunto de hiper-arestas

de saıda de I. Se nao houver nenhuma dependencia, o vertice em que a hiper-aresta corrente

incide e executado e posteriormente colocado em uma lista auxiliar L. Escolhe-se um vertice

pertencente a L e repete-se o procedimento de execucao ate que o vertice final do fluxo seja

alcancado e executado. Caso exista alguma dependencia, um vertice nao pode ser executado ate

que todas as dependencias tenham sido resolvidas.

Abaixo temos um algoritmo simples de execucao em hipergrafos direcionados mode-

lando um fluxo de tarefas. Nesta versao utilizamos quatro tipos de listas:

• lExecucao: Armazena os vertices que estao prontos para serem executados;

• lRecem Finalizados: Armazena os vertices que foram finalizados na ultima iteracao do algo-

ritmo;

• lFinalizados: Armazena os vertices que ja foram concluıdos;

• lPendentes: Armazena os vertices que ainda nao podem ser executados em razao de alguma

dependencia.

23

Ao longo da execucao do algoritmo as listas vao sendo atualizadas de modo que as de-

pendencias sejam respeitadas e todo o fluxo seja percorrido. No primeiro passo o vertice inicial

I e executado e os vertices pertencentes a FS(I) sao colocados na lista de tarefas pendentes. Em

seguida, executa-se um laco ate que a lista de tarefas que podem ser executadas esteja vazia.

Esta execucao consiste em percorrer a lista de tarefas pendentes, e para cada vertice v escolhe-

se uma hiper-aresta e pertencente a FS(v). Se nao houver dependencia, os vertices nos quais

a aresta e incide sao inseridos na lista de proximas tarefas que podem ser executadas. Apos

percorrer a lista de pendencias, a lista de tarefas que podem ser executadas e concatenada com

a lista de proximas tarefas que foi construıda durante a ultima iteracao. O algoritmo termina

quando a lista de tarefas que podem ser executadas estiver vazia.

24

5.1.1 Funcao Execucao (Principal)

Algoritmo 1: Execucao do FluxoDados: H = (V,E) e s ∈V

inıciolExecucao←− s

lRecem Finalizados←− /0

lFinalizados←− /0

lPendentes←− /0

enquanto lExecucao 6= /0 facalRecem Finalizados←− realizaTrabalho(lExecucao)

lProximas←− /0

lFinalizados←− lFinalizados∪ lRecem Finalizados

lPendentes←− lPendentes∪ lRecem Finalizados

para cada vertice ∈ (lPendentes) faca

se tamanho(FS(vertice)) = 1 entaotome a unica aresta ∈ FS(vertice) como e

senao escolha e ∈ FS(vertice)

se verificaDependencias(e, lFinalizados) = NAO entaolProximas←− lProximas∪Dest(e)

lPendentes←− lPendentes− vertice

lExecucao←− lExecucao∪ lProximas

fim

V contem a propriedade tarefa, e esta contem a propriedade tempo.

5.1.2 Funcao realizaTrabalho

A funcao realizaTrabalho recebe uma lista de tarefas (vertices), e diminui o tempo

em 1 a cada iteracao. Quando o tempo for igual a zero significa que a tarefa foi executada. A

tarefa e removida da lista de tarefas em execucao e incluıda na lista de tarefas finalizadas.

25

Funcao realizaTrabalho

Dados: lExecucao

inıciolRetorno←− /0

para cada Tarefa ∈ lExecucao facaDecremente seu Tempo em 1

se Tempo = 0 entaolRetorno = lRetorno∪ Tarefa

lExecucao = lExecucao−Tarefa

retorna lRetorno

fim

5.1.3 Funcao verificaDependencias

A funcao verificaDependencias verifica se todos os vertices de origem da aresta

pela qual o vertice foi alcancado foram finalizadas, verificando se estas tarefas pertencem a lista

de tarefas finalizadas. Se as tarefas foram finalizadas, inclui na lista de tarefas a gerar e retorna

esta lista.

Funcao verificaDependencias

Dados: e ∈ E, lFinalizados

inıcioTemDependencia = NAO

para cada vertice ∈ e.origens faca

se vertice /∈ lFinalizados entaoTemDependencia = SIM

retorna TemDependencia

fim

26

6 Paralelismo

Na execucao paralela varias tarefas sao realizadas simultaneamente. Com isso busca-se

a otimizacao de diversos fatores, entre eles recursos, tempo e lucro, minimizando o desperdıcio

dos mesmos. A paralelizacao vem sendo amplamente utilizada em diferentes meios, como por

exemplo processos em fluxo de trabalho dentro de empresas, onde equipes podem se dividir e

trabalhar paralelamente, buscando um objetivo em comum. Tem-se tambem, a paralelizacao de

processos computacionas, uma alternativa que a cada dia se difunde mais. Na execucao de um

hipergrafo direcionado o paralelismo ocorre durante uma execucao, quando uma ou mais tarefas

estiverem sendo executadas no mesmo momento, ou seja, determinado vertice e alcancado e

outros encontram-se na mesma situacao ou ja foram alcancados mas ainda estao em execucao,

porem atraves de outros hiper-caminhos. Para acontecer uma execucao paralela basta existir

uma E-F-Condicao. Havera paralelismo no fluxo se, e somente se, houver no mınimo uma E-

F-Condicao, pois esta proporciona a condicao necessaria que e a ramificacao em E, pela qual as

proximas tarefas geradas devem ser executadas. Este e o principal fator que modela a condicao

de paralelismo.

27

Figura 6.1: Um Hipergrafo Direcionado com trechos de execucao paralela

Na figura 6.1 temos uma representacao grafica de um hipergrafo direcionado. Este

hipergrafo pode modelar um fluxo qualquer no qual cada letra representa uma tarefa diferente.

No hiper-arco de saıda de A, tem-se uma bifurcacao apontando para dois destinos, originando

uma condicao E, logo, as tarefas B e C devem ser executadas. Neste caso a execucao pode se

dar de forma paralela.

Figura 6.2: Destaque das tarefas que podem ser executadas paralelamente

A figura 6.2 mostra o mesmo hipergrafo, na qual os retangulos indicam quais tarefas

podem ser executadas paralelamente, considerando que o tempo de execucao de cada uma de-

las e exatamente o mesmo. Na reprentacao grafica acima atribuımos cores diferenciadas aos

retangulos, indicando os possıveis hiper-caminhos seguidos nas diferentes execucoes do fluxo

que podem ocorrer. Durante a execucao, que inicia-se pela tarefa A, apenas uma tarefa e exe-

28

cutada simultaneamente, no caso a propria tarefa A. Apos seu termino, as tarefas B e C sao ini-

ciadas, pois trata-se de uma condicao E. Neste instante, B e C pertencem ao mesmo retangulo,

portanto duas tarefas podem ser executadas paralelamente. Apos o final da execucao destas

duas tarefas outras devem ser executadas. Partindo de B temos D,E e F, e partindo de C temos

duas opcoes de tarefas a executar. Ou executa-se a tarefa G, ou executam-se H e I, portanto,

tem-se dois hiper-caminhos diferentes a seguir, e duas possibilidades de tarefas que podem ser

executadas paralelamente, ou as taredas (D, E, F) e (G) indicadas pelos retangulos cinzas, ou

(D, E, F) e (H e I) indicadas pelos retangulos verdes. Na continuacao do fluxo seguimos a

mesma logica.

6.1 Grau de paralelismo da execucao em um instante t

Dado um hipergrafo-direcionado H que modela um fluxo de tarefas no qual acontece

uma execucao X , no instante t, definimos como p(H,X , t) o grau de paralelismo no momento

t da execucao. Por exemplo, existe um processo sendo executado que teve inıcio as 8 horas

da manha. Vamos calcular p(H,X , t) as 11 horas, momento em que existem 5 pessoas traba-

lhando e nao existe mais nenhuma tarefa que possa ser executada por outra pessoa, sendo que

algumas tarefas ja foram executadas e que o fluxo segue um certo caminho. Dizemos entao

que p(H,X , t) e igual a 5, independentemente de outros caminhos que possam ter um grau de

paralismo maior. Considera-se o grau do paralelismo no instante desejado no caminho que a

execucao vem seguindo.

6.2 Grau de paralelismo maximo em um instante t

Dado um hipergrafo-direcionado H que modela um fluxo de tarefas, definimos como

P(H, t) o grau maximo de paralelismo que o hipergrafo pode alcancar no instante t. Seguindo

o mesmo exemplo, porem supondo que hajam outros (um ou mais) caminhos nos quais mais

pessoas possam executar paralelamente, o valor de P(H, t) e o grau do paralelismo do caminho

em que o maior numero de pessoas estao trabalhando paralelamente. Na figura 6.3 tem-se o

29

grau de paralelismo calculado para cada instante considerando o tempo de execucao de cada

tarefa como sendo 1. Em cada linha este t e incrementado em um.

Figura 6.3: Calculo do grau de paralelismo em cada instante da execucao

6.3 Grau de paralelismo maximo do hipergrafo

Dado um hipergrafo-direcionado H que modela um fluxo de tarefas, definimos como

MP(H), o grau do paralelismo maximo do hipergrafo em qualquer instante da execucao do

fluxo. MP(H) = max[P(H, t)∀t ∈ N ≤ max[T ]] onde T e o conjunto de tempos t possıveis

discretizados, e max[T ] e o tempo maximo de execucao do fluxo.

30

6.4 Grau maximo medio de paralelismo do hipergrafo

Dado um hipergrafo-direcionado H que modela um fluxo de tarefas, definimos como

dP(H) a media de tarefas que podem ser executadas simultaneamente. Discretizando o valor

de t temos que dP(H) = ∑T1 P(H, t).

Figura 6.4: Grau medio de paralelismo do hipergrafo

No hipergrafo da figura 6.4 o grau medio e 2. Pois:

P(H,1) = 1

P(H,2) = 2

P(H,3) = 4

P(H,4) = 3

P(H,5) = 2

P(H,6) = 1

P(H,7) = 1

como ∑71 P(H, t) = 14 e 14/T = 2, portanto dP(H)= 2.

31

7 Algoritmos para Calculo do Maior Paralelismo emHipergrafos Direcionados

Neste capıtulo sao apresentados dois algoritmos o para calculo do maior paralelismo

em fluxo de trabalhos modelados em hipergrafos direcionados. Estes algoritmos utilizam metodos

distintos para o calculo. Nomeados como algoritmo A e B apenas para fazer distincao entre eles.

7.1 Algoritmo A

7.1.1 Consideracoes iniciais

Neste algoritmo, nos referimos a VETOR DE LISTAS como sendo uma lista de listas.

O VETOR e a lista principal, onde cada nodo possui uma outra lista, que por sua vez possui

vertices.

7.1.2 Funcionamento

A ideia por tras do algoritmo e que dado um determinado vertice A do Hipergrafo

Direcionado (hgd), e analisado se os hiper-arcos que saem deste vertice formam uma hiper-arco

E ou um hiper-arco OU.

Seja H o hgd abaixo.

Considere o vertice B. Podemos observar que de B parte apenas um hiper-arco, cha-

mado a. Portanto trata-se de uma E-F-Condicao, que por definicao exige B e C para seguir

para D. Neste caso, devemos analisar se todas as origens do hiper-arco a estao marcadas como

PRONTO. Para tanto, marcamos B como pronto e verificamos se estao todos prontos. Se sim,

32

Figura 7.1: Hipergrafo Direcionado

removemos todos os vertices origem de a e colocamos no lugar de B todos os vertices desti-

nos de a. Senao, nao podemos seguir ate estarem todos prontos. Devemos partir entao para o

proximo vertice da lista.

Considere agora o vertice E. Podemos observar que de E partem mais de um hiper-

arco, no caso os hiper-arcos b e c. Portanto trata-se de uma OU-F-Condicao. Nesta situacao,

para cada hiper-arco verificamos se suas origens estao prontas. Se todas as origens de todas os

hiper-arcos estiverem prontas, entao criamos uma copia da lista em que estamos trabalhando

para cada hiper-arco, e em cada uma delas substituımos as origens por seus respectivos destinos.

Em seguida removemos a lista original. Assim teremos uma copia da lista para o hiper-arco b,

substituindo E por F e G; e outra copia para o hiper-arco c, substituindo E por H. Se alguma

das origens dos hiper-arcos que saem de E nao estiver pronta, entao apenas marcamos E como

pronto e seguimos para o proximo vertice da lista.

Esperamos todas as arestas estarem prontas mesmo quando se trata de um hiper-arco

OU, pois como consideramos todos os tempos igual a 1, se um caminho andar e o outro nao,

entao pode ocorrer de o calculo do paralelismo para aquele nıvel se dar de forma errada. O

maior paralelismo e determinado pelo tamanho da maior das listas do VETOR em qualquer

momento da execucao do algoritmo.

33

7.1.3 Pseudocodigo

O algoritmo segue o fluxo de execucao a partir do vertice dado como inıcio, criando

novos fluxos de execucao a medida que encontra hiper-arcos do tipo OU-F-CONDICAO, adi-

cionando e removendo vertices da estrutura de listas e monitorando a quantidade de vertices de

um mesmo nıvel para ao final da execucao ter determinado o maior paralelismo.

34

Algoritmo 4: Algoritmo Ainıcio

lVetor← /0 ; lLista← /0 ; lProntos← /0indiceVetor← 0 ; indiceLista← 0 ; maiorParalel← 0 ; nivel← 0primeiro← Nodo() ; primeiro.vertice← inicio ; primeiro.nivel← 1primeiro.pronto← False ; primeiro.origem← NulllLista← lLista∪ primeiro ; lVetor← lLista∪ lLista ; acabou← Falseenquanto ((lVetor 6= /0)) e (nao acabou) faca

nivel← nivel + 1 ; iv← 0 ; il← 0enquanto (iv < len(lVetor)) e (nao acabou) faca

enquanto (il < len(lVetor[iv])) e (nao acabou) facase lVetor[iv][il].nivel ≤ nivel entao

se lVetor[iv][il].vertice.fs = /0 entaolVetor[iv]← lVetor[iv] - {lVetor[iv][il]} ; il← il - 1se lVetor[iv] = /0 entao lVetor← lVetor - {lVetor.[iv]}

senaose tamanho(lVetor[iv][il].vertice.fs) ≤ 1 entao

se VerificaProntos(lVetor, lProntos, iv, il) entaoil← RemoveOrigens(lVetor, lProntos, iv, il,lVetor[iv][il].vertice.fs)nodo← lVetor[iv][il]lVetor[iv]← lVetor[iv] - {lVetor[iv][il]}para cada vert ∈ nodo.vertice.fs[0].destinos faca

lVetor[iv]← lVetor[iv] ∪ {vert} na posicao ilse (nodo.vertice.fs[0].destinos = /0) e (lVetor[iv] = /0)entao

lVetor← lVetor - {lVetor[iv]}

senaose VerificaProntos(lVetor, lProntos, iv, il) entao

indiceVerticeOriginal← ilpara cada aresta ∈ lVetor[iv][il].vertice.fs faca

ReplicaLista(lVetor, iv)il← RemoveOrigens(lVetor, lProntos, iv+1, il,lVetor[iv][il].vertice.fs)nodo← lVetor[iv+1][il] ; lVetor[iv+1]← lVetor[iv+1] -{lVetor[iv+1][il]}para cada vert ∈ aresta.destinos faca

lVetor[iv+1]← lVetor[iv+1] ∪ {vert} na posicao ilse (aresta.destinos = /0) e (lVetor[iv+1] = /0) entao

lVetor← lVetor− lVetor[iv+1]il← indiceVerticeOriginal

lVetor← lVetor− lVetor[iv]

il← il + 1 ; LimpaVetor(lVetor)se lVetor = /0 entao

acabou← True ; no← Nodo ; lLista← /0 ; lLista← lLista∪ {no}lVetor← lVetor∪ {lLista}

LimpaVetor(lVetor) ; iv← iv + 1se lVetor = /0 entao acabou← True

maiorParalel← VerificaMaiorParalel(lVetor, maiorParalel, nivel+1)retorna maiorParalel

fim

35

Rotinas auxiliares

Abaixo temos uma breve descricao das funcoes utilizadas pelo algoritmo.

• RemoveOrigens: Esta funcao faz um loop nas listas de origens das arestas que saem do

vertice atual. Para cada vertice origem procura em lVetor o vertice correspondente e

caso nao seja o vertice atual entao remove. Remove tambem de lProntos. O vertice

atual e removido manualmente.

• VerificaProntos: Esta funcao marca o vertice atual como pronto e varre lVetor em busca

dos vertices que fazem parte das listas de origens dos hiper-arcos que chegam no

vertice atual verificando se todos estao marcados como prontos. Retorna Verdadeiro

ou Falso.

• ReplicaLista: Esta funcao e utilizada para criar uma copia de uma determinada lista

dentro de lVetor. Ela cria uma nova lista e copia todos os itens da lista indicada.

• VerificaMaiorParalel: Esta funcao passa por lVetor contando quantos vertices pertencen-

tes ao nıvel atual de execucao estao presentes, determinando assim o paralelismo

neste dado momento da execucao do algoritmo.

• LimpaVetor: Esta funcao e chamada para retirar de lVetor listas vazias. Ela varre lVetor

removendo todas as listas que nao contem elementos.

36

7.2 Algoritmo B

7.2.1 Consideracoes iniciais

Este algoritmo tem seu funcionamento baseado no conceito de itens. Cada item carrega

varias informacoes uteis que sao usadas para o calculo do maior paralelismo. Durante a criacao

dos itens, o hipergrafo e simplificado, onde os vertices sao agrupados de tal maneira que cada

item ja detem o paralelismo pre-calculado. Para isso, uni-se os vertices que estao em E e agrupa-

se os itens com o mesmo pai. Os itens criados sao separados em uma lista de tempos, que e

uma lista de listas indexada pelo tempo discretizado. Ao fim da construcao desta lista, e feita

uma analise sobre estes itens. A analise consiste em escolher o maior paralelismo dos itens

com nıveis iguais e somar os paralelismos dos itens com nıveis diferentes. Ao final escolhe-se

o maior deles e obtemos o maior paralelismo.

Um item e um conjunto de nodos de destino de um hiper-arco. Basicamente e uma

quıntupla (t, p,n, id, pai), onde:

• t: e a unidade de tempo em que o item foi alcancado

• p: e o grau do paralelismo do item

• n: e o nıvel do item, em relacao a outros itens com o mesmo tempo, niveis iguais indicam

OU, e niveis diferentes indicam E

• id: e o identificador unico do item, quando o item e agrupado, todos ganham o mesmo id

• pai: e o id do item pai

Alem dessas propriedades temos outras que sao:

• Agrupamento: Agrupamento a qual o item pertence, no caso de pertencer a algum.

• Nıvel filho: Quando um dos hiper-arcos e visitado, a variavel nivel filho do item a qual

o vertice pertence e atualizada com o numero do nıvel do item de destino, esta variavel e

37

necessaria para atualizar corretamente o nıvel de um item, caso o item a ser criado tiver

um nıvel igual a outro dentro de um mesmo agrupamento.

• Nıvel de Referencia do Agrupamento: Esta variavel pertence ao agrupamento, ela indica

o nivel de referencia do agrupamento como um todo, e nao so de um unico item. Auxilia

no calculo de um novo valor do nıvel de um novo item a ser criado.

7.2.2 Funcionamento

Podemos visualizar melhor o funcionamento deste algoritmo atraves do exemplo da

figura 7.2.

Figura 7.2: Fluxo de Tarefas

Neste diagrama temos um fluxo de tarefas representado por um hipergrafo direcionado

38

H = ({A,B,C,E,F,G,H,I,J,K,L,M},{a,b,c,d,e, f ,g,h, i, j,k}), onde A e M sao os vertices ini-

cial (s) e final (t), respectivamente. Tendo este hipergrafo como entrada do algoritmo, o mesmo

e iniciado atraves do vertice A, sendo que para este primeiro vertice e criado um item automati-

camente. Feito isto, e tomado o hiper-arco a e deste todos os vertices de destino do mesmo sao

agrupados em um conjunto, um vertice somente e agrupado se o vertice nao pertencer a lista

de prontos. Em seguida um item e criado com os seus respectivos dados, relembrando que os

dados de um item sao: o momento em que o item e criado, o tamanho do conjunto do vertices

do destino do hiper-arco, a relacao deste item com algum outro item criado na mesma unidade

de tempo (trataremos melhor desta informacao adiante, onde chamaremos esta de nıvel), quem

e o item que deu origem a este novo item e um identificador unico para o item. Assim que um

item e criado, ele e inserido na lista de tempos, essa lista e basicamente uma lista de listas, ou

seja e uma lista principal indexada pelo tempo, onde cada tempo tem uma lista de itens, onde

estes itens tem o campo tempo, em seu respectivo item. Podemos ter uma melhor visualizacao

da lista de itens, na figura 7.3:

Figura 7.3: Um exemplo de lista de tempos

Apos a inclusao de um item na lista de tempos, os vertices deste item passam pela

realizacao de trabalho onde e simulada a execucao da tarefa. A realizacao do trabalho consiste

39

em diminuir o tempo executado em 1 cada vez que passar por essa funcao, em que cada vertice

tem um tempo de execucao, tempo este podendo ser qualquer numero pertencente ao conjunto

dos numeros naturais. Por exemplo, determinada tarefa representada por um vertice demora 10

unidades de tempo para ser concluıda, entao cada vez que este vertice passar por uma execucao

este tempo e subtraıdo em 1 ate chegar a zero, quando chegar a este valor, o vertice e dado como

executado.

O algoritmo apresentado aqui foi preparado para funcionar com tarefas tendo qualquer

tempo de execucao, por isso temos a lista de prontos, a lista de pendentes e os conceitos de

execucao e realizacao de trabalho, mas neste documento, trabalharemos apenas com tarefas

com tempo de execucao igual a uma unidade. E importante ressaltar que para que o algoritmo

funcione com tempos diferentes de 1, e necessario que se inclua uma nova entrada informando

quais os tempos de cada tarefa.

Voltando ao momento da execucao, ao final da realizacao do trabalho, os vertices fina-

lizados sao retirados da lista anterior e dispostos em uma nova lista, e para cada vertice desta

lista e incluıdo na lista geral de vertices prontos.

Para cada vertice recem finalizado, e calculado o valor do nıvel que ira ser repassado

para os filhos do item atual, pois apos isso, para cada vertice sao selecionados todos os hiper-

arcos do conjunto FS do vertice e a funcao de criacao de itens e chamada recursivamente para

cada hiper-arco, passando o nıvel calculado como sendo um dos parametros.

O calculo do nıvel consiste em verificar se o item atual, no caso o item pai do item que

ira receber o nıvel calculado, pertence a algum agrupamento de itens. Caso pertencer a algum

agrupamento, e verificado se algum item neste agrupamento tem o mesmo nıvel do item atual,

se tiver o novo valor e igual ao valor do nıvel filho do item com o mesmo nıvel, senao, e gerado

um novo valor para o nıvel. Este valor e o resultado da soma de tres valores distintos, que sao:

o nıvel de referencia, a posicao do vertice atual no grupo de vertices do item atual e a posicao

do item atual no agrupamento a qual ele pertence se ele pertencer a algum.

Ao fim, o dado calculado e salvo na variavel nıvel de referencia do agrupamento e o

40

item filho do item atual recebe o novo valor de nıvel recem calculado.

Com o nıvel calculado, e chamada a funcao de criacao de itens para cada hiper-arco.

Ao final da criacao de todos os itens estruturados na lista de tempos, temos uma saıda

como no exemplo da figura 7.4.

Figura 7.4: Criacao dos itens

No hipergrafo, a esquerda da figura 7.4, temos os retangulos azuis indicando os itens,

os retangulos vermelhos indicando os agrupamentos de itens, e os conjuntos a direita sao a lista

de tempos, com seus respectivos itens entre parenteses e seus atributos separados por vırgula,

que sao: Tempo, Paralelismo, Nıvel, ID do Item ou Agrupamento (quando um item pertence

a algum agrupamento, todos os itens desse agrupamento tem o mesmo ID) e ID do Item Pai.

41

Sendo que as chaves indicam o agrupamento.

Com esta estrutura montada, parte-se para a analise dos itens, onde cada lista de itens

em um determinado tempo e analisada calculando o maior paralelismo naquele tempo. Para

calcular o maior paralelismo em um determinado tempo, e seguido o seguinte lema: Escolhe-se

o maior valor do paralelismo de itens com o mesmo nıvel ou apenas um dos itens caso tenha o

mesmo valor, removendo do calculo os itens com valores menores e somando o paralelismo de

itens com nıveis diferentes. Sempre fazendo o calculo internamente aos agrupamentos primeiro

e depois para o restante, assim como calculos em algebra analogicamente.

Com os valores de cada tempo calculado, verifica-se qual dos tempos tem o maior

paralelismo, chegando entao ao resultado final.

42

7.2.3 Pseudocodigo

Criacao dos Itens

Abaixo temos o pseudo-codigo para o algoritmo de criacao dos itens, sendo o passo

fundamental para o calculo do paralelismo.

43

Algoritmo 5: CriaItens()Entrada: H = (V,E), ltempos, lprontos, lpendencias, itempai, hiper arco s ∈ E,

t ∈ N,nivel ∈ N, contadorid item ∈ NSaıda: Lista de Itens indexado por tempoinıcio

lnodos← /0 l f inalizados← /0se hiper arco = Nulo entao

tome v sendo Vertice Inicial ∈ Hlnodos← lnodos∪ Nodo(v,v.tempo)

senaolnodos←DST(hiper arco)−lprontos

repitalgrupo←CriaGrupo(lnodos)contadorid item←− contadorid item +1 item←Item(tempo, tamanho(lnodos),nivel,grupo, itempai,contadorid item)se item.paralelismo < 0 entao

lgrupo← InsereTempo(ltempos, item)lnodos, l f inalizados←− RealizaTrabalho(lnodos)l f inalizados← l f inalizados∪ lpendenciaslpendencias← /0para cada n ∈ l f inalizados faca

lprontos← lprontos∪{n}se n.item.lagrupamento 6= /0 entao

iditem igual ← VerificaSeHaNivelIgual(n.item, n.item.lagrupamento)se iditem igual 6=−1 entao

nivel← n.item.lagrupamento[iditem igual].nivel f ilho

senaonivel← RetornaNivelReferencia(item) + pos(n.item.lgrupo,n) +pos(n.item.lagrupamento, n.item)

senaose n ∈ n.item.grupo entao

nivel← pos(n.item.lgrupo,n)

SalvaNivelReferencia(item, nivel)n.item.nivel f ilho← nivelpara cada e ∈ n.vertice.fs faca

t← tempo+1se algum vertice ∈ ORG(e) /∈ lprontos entao

lpendencias← lpendencias∩{n}senao

ltempos = CriaItens(Nulo, ltempos,e, t,nivel, item)

tempo← tempo+1ate lnodos 6= /0retorna ltempos

fim

44

Rotinas Auxiliares

InsereTempo

Funcao InsereTempo

Entrada: ltempos, item

Saıda: Lista de Itens indexado por tempo atualizada

inıcio

se tamanho(lTempos) ≤ item.tempo entaolnova← /0

lnova← lnova∪{item}

lTempos← lTempos∪{lnova}

senao

para cada it ∈ lTempos[item.tempo] faca

se (it.nivel 6= item.nivel) e (it.itempai.id = item.itempai.id) entaoAgrupaItens(it, item)

lTempos[item.tempo]← lTempos[item.tempo] ∪{item}retorna lTempos

fim

45

Outras Rotinas Auxiliares

A seguir uma breve descricao de algumas rotinas ulizadas. Uma tentativa de implementacao

completa encontra-se nos Anexos.

• VerificaSeHaNivelIgual: Funcao que procura no agrupamento algum item com o mesmo

nıvel do item procurado e retorna este item.

• RealizaTarefa: Executa uma tarefa, retorna uma lista de tarefas finalizas e outra lista

de tarefas que nao foram completadas. Faz basicamente o trabalho do algoritmo

apresentado na secao 5.1.2.

• AgrupaItens: Esta funcao verifica se dois itens pertencem a algum agrupamento, o item

que nao pertencer a nenhum, e incluso no agrupamento existente. Se os dois itens

pertencerem a agrupamento distintos, e feita a uniao destes agrupamentos, caso

contrario um novo agrupamento e criado contendo os itens. Quando um item e

incluso em um agrupamento, o numero identificador do item passa a ser o numero

identificador do agrupamento.

• RetornaNivelReferencia: Funcao que retorna o Nıvel de referencia do Agrupamento ou

do Item. Se o item passado como parametro nao pertencer a algum agrupamento,

o valor retornado e o valor de referencia do item, senao, e retornado o valor do

primeiro item do agrupamento.

• SalvaNivelReferencia: Funcao que salva o valor do Nıvel de referencia do Agrupamento

ou do Item, se o item nao pertencer a nenhum agrupamento, o valor e salvo no

valor de referencia do item, se nao, o valor e sempre salvo no primeiro item do

agrupamento.

46

Analise dos Itens e Calculo do Maior Paralelismo

Tendo o algoritmo de criacao de itens pronto, pode-se usa-lo na funcao de calculo do

paralelismo. O algoritmo abaixo chama a funcao CriaItens que cria a lista de tempos e faz a

analise desta lista para calcular o valor do maior paralelismo do hipergrafo.

Algoritmo 7: CalculaParalelismoEntrada: H = (V,E)

Saıda: Valor do grau do maior paralelismo do Hipergrafo dado como entrada

inıcioltempos← CriaItens(H, /0, /0, /0,Nulo,Nulo,0,0,0)

lTempoFinal ← /0

lSomas← /0

para cada lItens ∈ lTempos facalgrupo← /0

para cada item ∈ lItens faca

se item percencer a algum agrupamento entaoQualifica(item.lagrupamento)

soma← SomaItens(item.lagrupamento)

lSomas← lSomas∪{soma}

item.lagrupamento← /0

senaolgrupo← lgrupo∪{item}

Qualifica(lgrupo)

soma← SomaItens(lgrupo)

lSomas← lSomas ∪{soma}

maiorSoma, k← max(lSomas)

lTempoFinal ← lTempoFinal ∪{maiorSoma}maior← max(lTempoFinal)

retorna maior

fim

47

Rotinas Auxiliares

Procedimento Qualifica

O procedimento Qualilifica, verifica na lista de itens quais possuem o mesmo valor

do nıvel. Quando dois itens estiverem nesta situacao, devemos escolher qual o maior valor do

paralelismo do item, aquele com o maior valor e indicado como maior.

Procedimento Qualifica

Entrada: litens = lista de itens

inıcio

para cada item1 ∈ litens faca

se item1.maior = Verdadeiro entao

para cada item2 ∈ litens faca

se item2.maior = Verdadeiro entao

se item1.nivel = item2.nivel entao

se item1.paralelismo < item2.paralelismo entaoitem1.maior← Falso

item2.maior← Verdadeiro

senaoitem2.maior← Falso

item1.maior← Verdadeiro

fim

48

Soma Itens

Esta funcao verifica na lista de itens dada como parametro e soma de todos os valo-

res do paralelismo dos itens marcados como maior, dados pelo procedimento de qualificacao.

Retornando o valor da soma.

Funcao SomaItens

Entrada: litens = lista de itens ja qualificada.

Saıda: Valor da soma.

inıciosoma← 0

para cada item ∈ litens faca

se item.maior == Verdadeiro entaosoma← soma + item.paralelismo

retorna soma

fim

49

8 Conclusao

Neste trabalho e possıvel concluir que o uso de hipergrafos direcionados na modela-

gem de fluxos de tarefas, sejam eles workflow, processos computacionais ou regras de negocio,

entre outros, e extremamente util para a resolucao de uma serie de problemas que utilizam este

tipo de estruturas. Com os hipergrafos direcionados e possıvel modelar e enxergar no nıvel

de estrutura de dados uma serie de informacoes relevantes sem a necessidade de anexos, como

variaveis auxiliares nao pertencentes a sua estrutura basica. Assim e possıvel visualizar e mode-

lar muito facilmente as dependencias entre as tarefas. Vimos que podemos modelar paralelismo

em OU e em E, e atraves deles podemos calcular onde temos possıveis momentos de execucoes

paralelas, e qual e o ponto com o maior grau de paralelismo. Informacao extremamente util

em muitas areas, mas principalmente para gestores e analistas de negocio e de sistemas, pois

com tais informacoes e criada uma base solida que auxilia a tomada de diversas decisoes, sa-

bendo exatamente o maximo de recursos a alocar sem ocorrer desperdıcio de recursos, alem

da otimizacao dos recursos existentes. Sem muita dificuldade e possıvel perceber que o para-

lelismo e uma das saıdas para a otimizacao de qualquer processo e o hipergrafo direcionado

e a ferramente adequada para a sua modelagem por guardar um serie de informacoes relevan-

tes. Enfim, e um assunto que merece muito estudo, apesar de ser pouco explorado atualmente,

tendera a um futuro promissor.

50

Referencias Bibliograficas

DONADELLI, J. Algoritmos e Teoria dos Grafos. Dezembro 2008. Disponıvel em:<http://www.inf.ufpr.br/jair/ci065>.

GUEDES, A. L. P. Hipergrafos Direcionados. Tese (Doutorado) — Universidade Federal doRio de Janeiro, 2001.

PARANA, C. I. do. Expresso Livre - Workflow. Dezembro 2008. Disponıvel em:<http://www.expressolivre.org/html/expressolivre/index.php?page=workflow>.

ROBERTO, M. e. Pargo - Paralelismo, Grafos e Otimizacao Combinatoria - Seminarios -Problema de ordenacao de mensagens em sistemas paralelos. Dezembro 2008. Disponıvel em:<http://www.lia.ufc.br/ pargo/index.php?n=Seminarios.MarcioRoberto>.

SERRALHEIRO, W. Estrutura Organizacional. Dezembro 2008. Disponıvel em:<http://wiki.cefetsc.edu.br/mediawiki/images/5/5a/Aru empreend cap3.pdf>.

STIVANIN, Z. Tracado Automatico de Hipergrafos Direcionados. Dissertacao (Mestrado) —Universidade Federal do Parana, 2006.

51

ANEXO A -- Algoritmo (A) para calculo do maior paralelismo

import sys

import os

import re

from hipergrafo import *

#—————————————————————————

#Classe para armazenar cada vertice

#—————————————————————————

class TNodo:

vertice = TVertice()

pronto = False

origem = TVertice()

nivel = 0

#—————————————————————————

#Remove todas as origens do hiper arco. Menos o vertice atual.

#—————————————————————————

def fnRemoveOrigens(vetor, prontos, indiceVetor, indiceLista, arestas):

quantRemovidos = 0

for aresta in arestas:

for vertice in aresta.origens:

indiceL = 0

#procura no vetor para remover.

while (indiceL < len(vetor[indiceVetor])):

#verifica se vertice e uma das origens que procuramos

if (vetor[indiceVetor][indiceL].vertice.rotulo == vertice.rotulo):

# Se e o vertice atual, pula

if (indiceL==indiceLista):

indiceL = indiceL + 1

else: # Se nao e o vertice atual, remove.

52

vetor[indiceVetor].pop(indiceL)

#Atualiza indice do vetor que e utilizado externamente a esta funcao

if (indiceL < indiceLista):

indiceLista = indiceLista - 1

#remove tambem da lista de prontos

indiceP = 0

tirou = False

while (indiceP < len(prontos)) and (not tirou):

#procura na lista de prontos

if (prontos[indiceP].vertice.rotulo == vertice.rotulo):

# Se achou, remove da lista de prontos

prontos.pop(indiceP)

tirou = True

else:

indiceP = indiceP + 1

quantRemovidos = quantRemovidos + 1

else:

#senao vai para o proximo elemento.

indiceL = indiceL + 1

return indiceLista

#—————————————————————————

#Marca vertice atual como pronto e verifica se todas as origns estao prontas.

#—————————————————————————

def fnVerificaProntos(vetor, prontos, indiceVetor, indiceLista):

#marca vertice como pronto

vetor[indiceVetor][indiceLista].pronto = True

#Adiciona como pronto

verticePronto = TNodo()

verticePronto.vertice = vetor[indiceVetor][indiceLista].vertice

verticePronto.nivel = vetor[indiceVetor][indiceLista].nivel

verticePronto.pronto = vetor[indiceVetor][indiceLista].pronto

verticePronto.origem = vetor[indiceVetor][indiceLista].origem

prontos.append(verticePronto)

#Verifica quantos estao prontos

todosProntos = True

idAresta = 0

53

while (idAresta < len(vetor[indiceVetor][indiceLista].vertice.fs)) and todosProntos:

aresta = vetor[indiceVetor][indiceLista].vertice.fs[idAresta]

idOrigem = 0

while (idOrigem < len(aresta.origens)) and todosProntos:

vert = aresta.origens[idOrigem]

achou = False

idProntos = 0

while (idProntos < len(prontos)) and (not achou):

if (vert.rotulo == prontos[idProntos].vertice.rotulo):

achou = True

else:

idProntos = idProntos+1

todosProntos = achou

#Se nao achou 1, entao nao estao todos prontos.

idOrigem = idOrigem+1

idAresta = idAresta+1

return todosProntos

#—————————————————————————

#Faz uma copia da lista no vetor.

#—————————————————————————

def fnReplicaLista(vetor, indiceVetor):

novaLista = []

for vert in vetor[indiceVetor]:

nodo = TNodo()

nodo.vertice = vert.vertice

nodo.origem = vert.origem

nodo.pronto = vert.pronto

nodo.nivel = vert.nivel

novaLista.append(nodo)

vetor.insert(indiceVetor+1, novaLista)

#—————————————————————————

#Verifica o maior paralelismo atual

#—————————————————————————

def fnVerificaMaiorParalel(vetor, maior, nivel):

indiceLista = 0

54

while (indiceLista < len(vetor)):

quant = 0

indiceItem = 0

while (indiceItem < len(vetor[indiceLista])):

quant = quant + 1

indiceItem = indiceItem + 1

if (quant > maior):

maior = quant

indiceLista = indiceLista + 1

return maior

#—————————————————————————

#Remove listas vazias do vetor

#—————————————————————————

def fnLimpaVetor(vetor):

i = 0

while (i < len(vetor)-1):

if (len(vetor[i]) == 0):

vetor.pop(i)

else:

i = i + 1

#—————————————————————————

#Funcao Principal

#—————————————————————————

def fnParalelismo(inicio):

vetor = []

lista = []

prontos = []

indiceVetor = 0

indiceLista = 0

maiorParalel = 0

nivel = 0

primeiro = TNodo()

primeiro.vertice = inicio

primeiro.nivel = 1

primeiro.pronto = False

primeiro.origem = None

55

# Adicionar 1o vertice no Vetor[0,0]

lista.append(primeiro)

vetor.append(lista)

acabou = False

#LOOP ate vetor ficar vazio.

while (vetor != []) and (not acabou):

nivel = nivel + 1

iv = 0

il = 0

#loop por todas as listas do vetor

while (iv < len(vetor)) and (not acabou):

#loop por todos os vertices da lista

while (il < len(vetor[iv])) and (not acabou):

#Verifica se o vertice e do nıvel atual ou menor

if (vetor[iv][il].nivel <= nivel):

#verifica se o vertice tem aresta fs (que saem).

if (len(vetor[iv][il].vertice.fs) == 0):

#Se nao tem, ele e o ultimo do caminho.

vetor[iv].pop(il)

il = il-1

#Se a lista ficou vazia, remove do vetor

if len(vetor[iv]) == 0:

vetor.pop(iv)

else:

#Verifica se sai em E, ou seja, se o nr. de arestas que saem do vertice e igual a 1

if(len(vetor[iv][il].vertice.fs)<=1):

#verificar se os vertices dependentes estao marcados como ”pronto”.

#Se sim, tira todos e coloca o destino.

if (fnVerificaProntos(vetor, prontos, iv, il)):

#Remover todas as origens das listas.

il = fnRemoveOrigens(vetor, prontos, iv, il, vetor[iv][il].vertice.fs)

#Remove vertice atual da lista atual

nodo = vetor[iv].pop(il)

#Adiciona vertices do destino na lista atual

for vert in nodo.vertice.fs[0].destinos:

56

novo = TNodo()

novo.vertice = vert

novo.origem = nodo.vertice

novo.nivel = nivel + 1

novo.pronto = False

#Insere na posicao atual

vetor[iv].insert(il, novo)

#Se nao tem nenhum destino entao nao adicionou ninguem.

#Neste caso se a lista ficou vazia, remove do vetor

if (len(nodo.vertice.fs[0].destinos) == 0) and (len(vetor[iv]) == 0):

vetor.pop(iv)

#fim if tipo E

else:

#Sai aresta do tipo OU

#Verifica se estao todos prontos

if (fnVerificaProntos(vetor, prontos, iv, il)):

indiceVerticeOriginal = il

for aresta in vetor[iv][il].vertice.fs:

#Duplica lista

fnReplicaLista(vetor, iv) #Nova lista esta em iv+1, lista original em iv

#Remove origens da aresta

il = fnRemoveOrigens(vetor, prontos, iv+1, il, vetor[iv][il].vertice.fs)

#Remove vertice atual da lista replica

nodo = vetor[iv+1].pop(il)

#Adiciona vertices do destino na lista replica

for vert in aresta.destinos:

novo = TNodo()

novo.vertice = vert

novo.origem = nodo.vertice

novo.nivel = nivel + 1

novo.pronto = False

#Insere na posicao atual

vetor[iv+1].insert(il, novo)

#Se nao tem nenhum destino entao nao adicionou ninguem.

#Neste caso se a lista ficou vazia, remove do vetor

if (len(aresta.destinos) == 0) and (len(vetor[iv+1]) == 0):

57

vetor.pop(iv+1)

il = indiceVerticeOriginal

#Remove a lista original

vetor.pop(iv)

#fim if E else OU

#fim if e ultimo no caminho

#fim if nıvel

il = il + 1

fnLimpaVetor(vetor)

if (vetor == []):

acabou = True

#Adiciona um nodo vazio para nao gerar erro ao analizar a condicao do loop, antes de sair dele.

no = TNodo

lista = []

lista.append(no)

vetor.append(lista)

#fim while il

fnLimpaVetor(vetor)

iv = iv + 1

if (vetor == []):

acabou = True

#fim while iv

maiorParalel = fnVerificaMaiorParalel(vetor, maiorParalel, nivel+1)

#fim while vetor != []

return maiorParalel

#fim fnParalelismo()

#——————————————————————————-

#Inıcio do Programa

#——————————————————————————-

hipergrafo = THipergrafo()

arquivo = raw input(”Digite o nome do arquivo que contem o hipergrafo a ser analisado:”)

hipergrafo.fnLeHiperGrafo(arquivo.strip())

maior = fnParalelismo(hipergrafo.lista vertices[0])

58

ANEXO B -- Algoritmo (B) para calculo do maior paralelismo

# coding: utf-8

import sys

import os

import re

from hipergrafo import *

#——————————————————————————-

# Classe TNodo

#——————————————————————————-

class TNodo:

vertice = None

tempo restante = 0

item = None

def init (self, vertice, tempo):

self.vertice = vertice

self.tempo restante = tempo

#——————————————————————————-

# Cada Item e um conjunto de nodos de destino de uma hiper arco.

#——————————————————————————-

class TItem:

id = 0

id original = 0

tempo = 0

paralelismo = 0

nivel = 0

grupo = None

item pai = None

agrupamento = None

59

ref = 0

nivel filho = -1

maior = True

#—————————————————————————

#Construtor da classe

#—————————————————————————

def init (self, tempo, paralel, nivel, grupo, item pai, id):

self.tempo = tempo

self.paralelismo = paralel

self.nivel = nivel

self.grupo = grupo

self.item pai = item pai

self.id = id

self.id original = id

self.referencia = nivel

for n in grupo:

n.item = self

#—————————————————————————

# Mostra um item na tela

#—————————————————————————

def mostrar(self):

if (self.item pai != None):

idPai = self.item pai.id

else:

idPai = 0

if (self.paralelismo > 0):

if (self.agrupamento == None):

print (”(”+ str(self.tempo) + ”,”+ str(self.paralelismo) + ”,”+ str(self.nivel) + ”,”+ str(self.id) +”,”+ str(idPai) +”) ”),

else:

if (self.agrupamento[0] == self):

print (”*[”),

for i in self.agrupamento:

if (i.paralelismo > 0):

print (”(”+ str(i.tempo) + ”,”+ str(i.paralelismo) + ”,”+ str(i.nivel) + ”,”+ str(i.id) +”,”+ str(i.item pai.id) +”) ”),

print (”]*”),

60

#——————————————————————————-

# Classe para calculo do maior paralelismo

#——————————————————————————-

class TParalelismo:

listaTempos = []

listaProntos = []

listaPendencias = []

contador id item = 0

#—————————————————————————

# Retorna primeiro vertice do hipergrafo

#—————————————————————————

def fnRetornaPrimeiroVertice(self, hipergrafo):

return hipergrafo.lista vertices[0]

#—————————————————————————

# Retorna o nivel de referencia do agrupamento

#—————————————————————————

def fnRetornaNivelReferencia(self,item pai):

if (item pai != None):

if (item pai.agrupamento == None):

return item pai.referencia

else:

return item pai.agrupamento[0].referencia

else:

return 0

#—————————————————————————

# Altera o nivel de referencia do agrupamento

#—————————————————————————

def fnSalvaNivelReferencia(self,item pai, referencia):

if (item pai != None):

if (item pai.agrupamento == None):

item pai.referencia = referencia

else:

item pai.agrupamento[0].referencia = referencia

#—————————————————————————

# Retorna todo os vertices de destino do hiper arco

#—————————————————————————

61

def fnRetornaProximosVerticesDoHiperArco(self, hiper arco):

listaNodos = []

for vertice in hiper arco.destinos:

if (not self.fnBuscaVerticesNalistaNodos(self.listaProntos, vertice)):

nodo = TNodo(vertice, vertice.tempo)

listaNodos.append(nodo)

return listaNodos;

#—————————————————————————

# Procura vertice na lista de nodos

#—————————————————————————

def fnBuscaVerticesNalistaNodos(self, lista, vertice):

bAchou = False

i = 0

while ((not bAchou) and (i < len(lista))):

if (vertice.rotulo == lista[i].vertice.rotulo):

bAchou = True

else:

i = i + 1

return bAchou

#—————————————————————————

# Verifica se uma vertice de origem da hiper arco nao foi executado

#—————————————————————————

def fnVerificaSeTodoOsVerticesDepentendesEstaoProntos(self, hiper arco):

bSim = True

for vertice in hiper arco.origens:

if (not self.fnBuscaVerticesNalistaNodos(self.listaProntos, vertice)):

bSim = False

return bSim;

#—————————————————————————

# Executa a tarefa, diminuindo em um, cada vez que passa por essa funcao.

# Simula a execucao da tarefa

#—————————————————————————

def fnRealizaTrabalho(self, conjunto nodos):

finalizados = []

for n in conjunto nodos:

n.tempo restante = n.tempo restante - 1

62

if (n.tempo restante < 1):

finalizados.append(n)

for n in finalizados:

print(n.vertice.rotulo)

conjunto nodos.remove(n)

return conjunto nodos, finalizados

#—————————————————————————

# Verifica se ha alguem no agrupamento com o mesmo nıvel

#—————————————————————————

def fnVerificaSeHaNivelIgual(self, item, agrupamento):

iAchou = -1

i = 0

while ((iAchou == -1) and (i < len(agrupamento))):

if ((agrupamento[i].nivel == item.nivel) and (agrupamento[i].id original != item.id original)):

iAchou = i

else:

i = i + 1

return iAchou

#—————————————————————————

# Verifica se o item pertence ao grupo

#—————————————————————————

def fnPertenceA(self, item, grupo):

bAchou = False

i = 0

while ((bAchou == False) and (i < len(grupo))):

if (grupo[i].id original == item.id original):

bAchou = True

else:

i = i + 1

return bAchou

#—————————————————————————

# Unifica dois grupos

#—————————————————————————

def fnUnifica(self, grupo1, grupo2):

63

for item in grupo2:

if (not self.fnPertenceA(item, grupo1)):

grupo1.append(item)

grupo2 = grupo1

#—————————————————————————

# Agrupa itens

#—————————————————————————

def fnAgrupaItens(self, item1, item2):

if (item1.agrupamento != None):

if (item2.agrupamento == None):

item1.agrupamento.append(item2)

item2.agrupamento = item1.agrupamento

item2.id = item1.id

else:

self.fnUnifica(item1.agrupamento, item2.agrupamento)

item2.agrupamento = item1.agrupamento

item2.id = item1.id

else:

if (item2.agrupamento != None):

item2.agrupamento.append(item1)

item1.agrupamento = item2.agrupamento

item1.id = item2.id

else:

self.contador id item = self.contador id item + 1

item1.id = self.contador id item

item1.agrupamento = []

item1.agrupamento.append(item1)

item1.agrupamento.append(item2)

item2.agrupamento = item1.agrupamento

item2.id = item1.id

#—————————————————————————

# Insere um item no seu tempo correto, alem de agrupar os itens que tem

# mesmo pai e niveis diferentes

#—————————————————————————

64

def fnInsereTempo(self,item):

if (len(self.listaTempos) <= item.tempo):

l = []

l.append(item)

self.listaTempos.append(l)

else:

# Varre em busca de itens com nıvel diferente do que esta sendo inserido e com o mesmo pai,

for it in self.listaTempos[item.tempo]:

if ((it.nivel != item.nivel) and (it.item pai.id == item.item pai.id)):

# faz o agrupamento destes itens

self.fnAgrupaItens(it, item)

self.listaTempos[item.tempo].append(item)

return self.listaTempos

#—————————————————————————

# Cria um grupo

#—————————————————————————

def fnCriaGrupo(self, conjunto nodo):

l = []

for n in conjunto nodo:

l.append(n)

return l

#—————————————————————————

# Funcao principal do calculo, desce em recursao, fazendo busca em

# profundidade e calculando os itens.

# Itens esses, que sao usados para o calculo final

#—————————————————————————

def fnCriaItens( self, hipergrafo, hiper arco, tempo, nivel, item pai):

conjunto nodos = []

finalizados = []

# primeiro vertice

if (hiper arco == None):

v = self.fnRetornaPrimeiroVertice(hipergrafo)

conjunto nodos.append(TNodo(v,v.tempo))

else:# Cria um conjunto contendo todos o vertices do grupo de destino do hiper-arco atual

conjunto nodos = self.fnRetornaProximosVerticesDoHiperArco(hiper arco)

while(True):

65

grupo = self.fnCriaGrupo(conjunto nodos)

self.contador id item = self.contador id item + 1

item = TItem(tempo,len(conjunto nodos),nivel, grupo, item pai, self.contador id item)

if (item.paralelismo > 0):

grupo = self.fnInsereTempo(item)

conjunto nodos, finalizados = self.fnRealizaTrabalho(conjunto nodos)

finalizados.extend(self.listaPendencias)

self.listaPendencias = []

for n in finalizados:

self.listaProntos.append(n)

# calculo do nıvel

# Se o item do nodo atual pertencer a algum agrupamento

if (n.item.agrupamento != None):

# Verifica no agrupamento, se existe algum item com o mesmo nıvel do item procurado

id item igual = self.fnVerificaSeHaNivelIgual(n.item, n.item.agrupamento)

if (id item igual != -1):

# Recupera o nivel filho do item encontrado,

nivel = n.item.agrupamento[id item igual].nivel filho

else:

# Busca o nıvel de referencia do agrupamento de itens

nivel = self.fnRetornaNivelReferencia(item)

# Gera um numero novo para ser o nıvel

nivel = nivel + n.item.grupo.index(n) + n.item.agrupamento.index(n.item)

# Se o item do nodo atual NAO pertencer a algum agrupamento

else:

if (n.item.grupo. contains (n)):

# o valor do nivel e a posicao do vertice no grupo do item

nivel = n.item.grupo.index(n)

# Salva o nıvel de referencia do agrupamento

self.fnSalvaNivelReferencia(item, nivel)

# O item filho do item atual, recebera o novo valor de nıvel recem calculado, logo este e salvo

# na variavel nivel filho do item atual

n.item.nivel filho = nivel

# fim do calculo do nıvel

for e in n.vertice.fs:

66

t = tempo + 1

if (not self.fnVerificaSeTodoOsVerticesDepentendesEstaoProntos(e)):

self.listaPendencias.append(n)

else:

self.fnCriaItens(hipergrafo, e, t, nivel , item)

tempo = tempo + 1

if (conjunto nodos == []):

break

return self.listaTempos

#—————————————————————————

# Mostra os itens, o Resultado pode visualizado analisando os itens

#—————————————————————————

def fnMostrarItensResultado(self):

i = 0

for l in self.listaTempos:

print

print i

for item in l:

item.mostrar()

i = i + 1

#—————————————————————————

# Retorna o maior valor na lista

#—————————————————————————

def fnRetornaMaior(self, lista):

maior = 0

i = 0

iTempo = 0

for valor in lista:

if (valor > maior):

maior = valor

iTempo = i

i = i + 1

return maior, iTempo

#—————————————————————————

# Soma os paralelismos dentro de uma lista de itens

#—————————————————————————

67

def fnSomaItens(self,lista):

soma = 0

for item in lista:

if (item.maior == True):

soma = soma + it.paralelismo

return soma

#—————————————————————————

# Qualifica os itens indicando quais sao os que tem o maior paralelismo dentre

# aqueles que tem o mesmo valor do nıvel

#—————————————————————————

def fnQualifica(self, lista):

for item 1 in lista:

if (item 1.maior == True):

for item 2 in lista:

if (item 2.maior == True):

if(item 1.nivel == item 2.nivel):

if (item 1.paralelismo < item 2.paralelismo):

item 1.maior = False

item 2.maior = True

else:

item 2.maior = False

item 1.maior = True

#—————————————————————————

# Faz a analise sobre os itens o mostra o resultado final na tela

#—————————————————————————

def fnCalculaParalelismo(self, hipergrafo, bMostrarItens):

# Cria os itens, indexando por tempo

self.fnCriaItens(hipergrafo, None,0,0, None)

if (bMostrarItens): # Se desejado, mostra-se ou nao os itens criados na tela

self.fnMostrarItensResultado()

# Com a lista de tempos criada, faz a analise sobre ela retornando o valor final

listaTempoFinal = []

listaSomas = []

for l in self.listaTempos:

grupo = []

for item in l:

68

if (item.agrupamento != None):

if (item.agrupamento != []):

self.fnQualifica(item.agrupamento)

soma = self.fnSomaItens(item.agrupamento)

listaSomas.append(soma)

item.agrupamento = []

else:

grupo.append(item)

self.fnQualifica(grupo)

soma = self.fnSomaItens(grupo)

listaSomas.append(soma)

maiorSoma, k = self.fnRetornaMaior(listaSomas)

listaTempoFinal.append(maiorSoma)

maior, tempo = self.fnRetornaMaior(listaTempoFinal)

return maior, tempo

#——————————————————————————-

#Inıcio do Programa

#——————————————————————————-

hipergrafo = THipergrafo()

arquivo = raw input(”Digite o nome do arquivo que contem o hipergrafo a ser analisado:”)

hipergrafo.fnLeHiperGrafo(arquivo.strip())

p = TParalelismo()

p.fnCalculaParalelismo(hipergrafo, False)

69

ANEXO C -- Estrutura de Dados

class TVertice:

dado = None

visita = None

rotulo = “ ”

tempo = 1

fs = []

bs = []

b = None

f = None

def init (self):

self.fs = []

self.bs = []

class THiperArco:

rotulo = “ ”

origens = []

destinos = []

p = None

def init (self):

self.origens = []

self.destinos = []

class THipergrafo:

lista vertices = []

lista arestas = []

def init (self):

self.lista vertices = []

self.lista hiperarcos = []