Suporte a Adaptação Dinâmica de Aplicações usando Funções de Utilidade
Vinicius Petrucci, Orlando Loques
Instituto de Computação – Universidade Federal Fluminense (UFF)
Niterói, Brasil
{vpetrucci,loques}@ic.uff.br
Resumo
A demanda por aplicações adaptativas tem sido impulsionada por recentes avanços nas áreas de computação
distribuı́da, móvel e pervasiva (ou ubı́qua), caracterizadas
por terem ambientes de execução altamente dinâmicos, heterogêneos e distribuı́dos. As aplicações adaptativas levam em consideração o contexto de execução e se adaptam em relação a alterações no ambiente de forma a maximizar a satisfação do usuário. Neste artigo apresentamos uma proposta de seleção de adaptações, integrada ao
framework CR-RIO, que permite expressar, em alto nı́vel
de abstração, preferências sobre diferentes nı́veis de qualidade associadas a componentes e configurações da arquitetura da aplicação. O mecanismo de seleção é baseado na teoria da utilidade e permite tratar casos complexos de decisão, contemplando o balanceamento entre
múltiplos objetivos, muitas vezes conflitantes, que dependem da combinação de diversas variáveis do ambiente.
1. Introdução
A demanda por aplicações adaptativas tem sido impulsionada por recentes avanços nas áreas de computação distribuı́da, móvel e pervasiva (ou ubı́qua), caracterizadas por
terem ambientes de execução altamente dinâmicos, heterogêneos e distribuı́dos [5, 11, 1]. Além do comportamento
funcional, as aplicações adaptativas definem requisitos especı́ficos, denominados requisitos não-funcionais ou operacionais (e.g., ligados ao processamento, armazenamento ou
transporte de informação) e podem ser afetadas de forma
diferente pela carência ou abundância dos mesmos. As
aplicações têm de conviver com a “flutuação” da disponibilidade dos recursos, tais como componentes de software, dispositivos, largura de banda, capacidade de processamento e memória.
Neste contexto, novas abordagens estão sendo propostas para que as aplicações controlem seu próprio comportamento de acordo com objetivos descritos em alto nı́vel pe-
los projetistas ou usuários [10, 7]. Esta visão de aplicações
auto-gerenciáveis é referida às vezes como computação
autônoma (autonomic computing) [8]. O desafio é garantir que os requisitos essenciais para o funcionamento dos
serviços fornecidos pelas aplicações sejam satisfeitos de
forma transparente para o usuário final.
O CR-RIO (Contractual Reflective-Reconfigurable Objects) [9, 4] é uma abordagem centrada num modelo arquitetural e utiliza uma linguagem de descrição de contratos para expressar os requisitos não-funcionais das
aplicações. A abordagem inclui um framework de suporte
para a implantação, monitoramento e gerenciamento dessas
aplicações, e um mecanismo de suporte a reconfiguração
dinâmica. O suporte permite adaptar elementos da arquitetura da aplicação para manter as exigências do contrato, estabelecendo assim os fundamentos necessários para facilitar
a especificação, a implantação e a gerência de aplicações
como as discutidas anteriormente. As estratégias e mecanismos de adaptação do suporte podem ser reutilizados em
diferentes aplicações, o que diminui o custo de desenvolvimento e aumenta a confiabilidade dos sistemas resultantes.
Neste artigo apresentamos uma proposta, integrada ao
CR-RIO, para seleção e reconfiguração de elementos arquiteturais baseada na teoria da utilidade. Para isso, estendemos a linguagem de contratos a fim de permitir expressar
as preferências sobre diferentes nı́veis de qualidade associadas aos componentes e configurações da arquitetura em
alto nı́vel de abstração. As preferências são especificadas
formalmente através de funções de utilidade.
Em especial, o mecanismo de seleção de alternativas
de configuração (negociação) visa guiar o comportamento
autônomo da aplicação, desempenhanhando um papel fundamental no contexto dos sistemas adaptativos e reconfiguráveis. Nosso argumento é que as polı́ticas de adaptação
baseadas em funções de utilidade, orientadas por abstrações
arquiteturais, representam um formalismo bastante atrativo
para especificar as preferências em relação às adaptações
necessárias para uma aplicação.
A organização do artigo é descrita a seguir. Na Seção
2 apresentamos os conceitos básicos da abordagem CR-
RIO. Na Seção 3 descrevemos um modelo de seleção de
adaptações e o mapeamento no contexto do CR-RIO. Para
ilustrar nossa proposta, na Seção 4 apresentamos um exemplo de uma aplicação cliente-servidor em um cenário pervasivo, no qual descrevemos algumas adaptações interessantes. Os principais trabalhos relacionados a nossa proposta
são descritos na Seção 5, e as considerações finais e trabalho
futuro na Seção 6.
2. Abordagem CR-RIO
Arquiteturas de Software. A ADL (Architecture Description Language) CBabel [12] é uma linguagem utilizada para descrever os componentes da aplicação e a topologia de interconexão destes componentes. A linguagem é composta por módulos que encapsulam aspectos
funcionais da aplicação. Conectores são utilizados em
nı́vel arquitetural para definir as relações de interação entre módulos. Em nı́vel de operação, os conectores intermedeiam a interação entre módulos. Portas identificam
pontos de acesso através dos quais os módulos e conectores provêm ou requisitam serviços. Para especificar aspectos não-funcionais relacionados a requisitos operacionais
tais como capacidade de processamento, tolerância a falhas,
segurança ou comunicação, CBabel emprega o conceito de
contrato.
Contratos. Um contrato está ligado à arquitetura da
aplicação e descreve, em tempo de projeto, o uso a ser feito
dos recursos compartilhados e variações aceitáveis na disponibilidade destes recursos. Um contrato possui os elementos descritos a seguir. Categorias são associadas a
recursos ou aspectos não-funcionais especı́ficos, descritos
separadamente dos componentes. Para cada categoria devem ser providos componentes de suporte correspondentes
que vão alocar/reservar e monitorar as respectivas caracterı́sticas. Perfis quantificam ou valoram as propriedades
de uma categoria, funcionando como uma instância de valores aceitáveis para determinada categoria. Componentes
ou partes de arquitetura podem definir perfis restringindo
seu contexto de operação. Um conjunto de serviços representa as configurações possı́veis para a aplicação. Uma
configuração é diferenciada de outra pelos nı́veis desejados ou tolerados pela aplicação em determinados contextos de operação. A negociação é o processo de escolher a
configuração mais adequada para a aplicação diante de um
determinado contexto de execução.
Nossa proposta apresenta uma alternativa à polı́tica atual
de negociação, baseada explicitamente em máquinas de estados [4]. Para sistemas mais complexos, onde há um
número muito grande de estados alcançáveis, a definição
explı́cita do conjunto de regras de transição se torna inviável
e tediosa. No nosso caso, a escolha da melhor adaptação é
guiada pelo cálculo das funções de utilidade de cada opção
de configuração, e aquela que possuir o maior valor de utilidade (ou satisfação) será a escolhida. Dessa forma, a
negociação é facilitada pois as transições são dinâmicas,
sendo arbitrariamente escolhidas durante a execução da
aplicação, e permitindo tratar casos de decisão envolvendo
o balanceamento (trade-off ) entre múltiplos objetivos.
3. Proposta de Seleção de Adaptações
Processos de tomada de decisão caracterizam-se em
exercer uma escolha entre diversas possibilidades de ação,
denominadas alternativas, de forma que aquela considerada
a mais satisfatória seja selecionada [6]. Em nosso trabalho, o enfoque é descrever um modelo de decisão onde as
alternativas representam as possı́veis adaptações para uma
aplicacão: (a) seleção de componentes ou (b) alternativas
de configuração da arquitetura.
3.1. Conceitos Básicos
Para efetuar a escolha sobre um conjunto de alternativas potenciais, representando as adaptações, caracterı́sticas
como custo, qualidade, por exemplo, devem ser consideradas. Essas caracterı́sticas são denominadas atributos.
Uma função de utilidade designa um valor numérico
para expressar a preferência por uma determinada alternativa. A notação U (a) denota a utilidade da alternativa
a diante do processo de tomada de decisões. A função
de utilidade para uma determinada variável pode ser definida utilizando-se expressões analı́ticas, tais como função
de utilidade linear (e.g. normalização), exponencial ou logarı́tmica.
Nem todos os problemas de decisão são influenciados
por um único critério. Na maioria das decisões complexas, vários fatores precisam ser considerados, assim como
a combinação das preferências em torno de cada um destes
fatores. A teoria da utilidade multiatributo (MAUT, MultiAttribute Utility Theory) incorpora à teoria da utilidade a
questão do tratamento de problemas com múltiplos objetivos [6]. Para modelar as preferências que influenciam na
decisão, atribuimos “pesos” para os atributos das alternativas. Os pesos medem a importância de menos importante
para mais importante entre os atributos. Alguns autores se
referem a esta importância relativa de cada atributo pelo
conceito de “taxa de substituição” (trade-off ).
3.2. Modelo de Seleção
Definimos A como sendo o conjunto de alternativas disponı́veis a serem selecionadas. Para cada alternativa a ∈ A
associamos um vetor AV de atributos de tamanho n. Definimos a função aAV: a → AV que retorna o vetor de atributo AV relacionado a uma alternativa a. Assumimos que
as alternativas compartilham do mesmo formato de vetor
de atributos e que cada um destes atributos possui um valor escalar discreto ou contı́nuo. A função value: v → R
retorna o valor associado ao atributo v. Os valores podem
ser obtidos através de um suporte de monitoração ou então
especificados pelo projetista ou usuário.
Para toda alternativa a ∈ A e para cada atributo v ∈
aAV (a), designamos uma função w : v → [0, 1] para representar a importância dada a cada atributo da alternativa.
Os valores próximos a 1.0 são atribuı́dos ao melhor cenário
e valores próximos a 0.0 ao pior cenário. Assumimos que o
projetista ou usuário já possui um prévio conhecimento da
importância de cada um destes atributos.
Em seguida, associamos um vetor de utilidades a toda
alternativa a ∈ A, calculado a partir de uma função de utilidade para cada atributo. Formalmente, definimos a função
de utilidade u : v → [0, 1] como sendo o mapeamento que
associa cada atributo v de uma alternativa a, onde a ∈ A
e v ∈ aAV (a), a um valor de utilidade no intervalo [0, 1].
Também consideramos os valores próximos a 1.0 para os
melhores cenários e valores próximos a 0.0 para os piores cenários. Note que para o caso de um atributo (e.g.
tempo de resposta) em que quanto menor o valor associado, maior é a utilidade, podemos facilmente redefinir a
função de utilidade do atributo pelo inverso da anterior, i.e.,
u0 (v) = 1 − u(v).
A função de utilidade multiatributo para cada alternativa
a ∈ A pelo somatório da multiplicação da constante escalar (peso) w dada a cada
P atributo pelo respectivo valor de
sua utilidade u, onde v∈aAV (a) w(v) = 1. A função é
definida por:
U (a) =
X
@ref = select(<CompClass>, <UtilClass>);
CompClass se refere à classe do componente (instância)
a ser selecionado (i.e. módulos ou configurações da arquitetura). UtilClass representa a classe de utilidade com
informações sobre as preferências e utilidades relacionadas
aos atributos de qualidade (e.g. tempo de resposta, custo) do
componente. Após a seleção, a referência do componente é
retornada para @ref.
4. Exemplo de Aplicação
Para ilustrar nossa proposta, consideramos uma
aplicação cliente-servidor em um ambiente computacional
pervasivo. Neste ambiente existem clientes móveis que
acessam informações (e.g. notı́cias) fornecidas por servidores distribuı́dos. A arquitetura é constituı́da por um grupo
de servidores e por um front-end (Figura 1). O front-end
encaminha as requisições visando o balanceamento de
carga entre os servidores membros do grupo. Do ponto de
vista do cliente, que envia um pedido, o front-end é apenas
um servidor que irá manipular o pedido da mesma maneira
que qualquer outro servidor faz.
w(v).u(v)
v∈aAV (a)
Com base na teoria da utilidade, cada alternativa possui
um grau relativo de importância (utilidade) e o processo de
decisão irá preferir a alternativa com maior utilidade. Portanto, dado o conjunto de alternativas A, o problema da decisão é resolvido pela maximização da função de utilidade
multiatributo, dada pela equação abaixo:
arg max U (a)
a∈A
3.3. Função de Seleção
No contexto do framework CR-RIO, o modelo de
seleção proposto é mapeado em uma função de seleção denominada select. A função de seleção permite selecionar
dinamicamente um elemento da arquitetura e retorna uma
referência que pode ser utilizada na linguagem de contrato
da aplicação. A função geral de seleção possui o seguinte
formato:
Figura 1. Arquitetura da Aplicação.
A descrição arquitetural da aplicação é a estrutura formada pelos seus componentes e suas interações, assim
como algumas diretrizes com informações de projeto a fim
de guiar sua evolução durante a execução. A configuração
da arquitetura é composta por um módulo Client que representa a classe de clientes, um módulo Server representando a classe de servidores, e um módulo ServerGroup responsável pela ligação, o gerenciamento da comunicação e
balanceamento de carga (através de um front-end) entre os
clientes e os servidores membros do grupo. Os contratos
são responsáveis por descrever os aspectos de qualidade dos
elementos da arquitetura. Neste exemplo, descrevemos um
contrato para tratar da qualidade em relação à ligação do
cliente ao grupo de servidores e outro contrato tratando dos
aspectos de qualidade sobre o gerenciamento dos servidores
em cada grupo.
4.1. Exemplo de Contrato para um Cliente
Durante o funcionamento da aplicação, o cliente se
adapta a fim de manter-se conectado ao melhor grupo
de servidores (Server Group) disponivel no ambiente, de
acordo com suas preferências. No cenário em que o usuário
se move pelo ambiente, por exemplo usando um PDA
através de uma rede sem fio, diferentes configurações de
grupo de servidores estão disponı́veis. Assim, expressamos
no contrato a idéia de o cliente dinamicamente escolher (e
se manter ligado) a melhor instância de grupo de servidores.
O contrato do cliente é descrito abaixo:
contract {
service {
instantiate Client as client;
@sg = select*(ServerGroup, SGUtil) at uff;
link client to @sg;
} main;
} client;
No contrato temos uma única configuração de serviço
main. A operação instantiate assegura que temos uma
instância do cliente para se ligar ao grupo de servidores. A
configuração da ligação link informa que o cliente será ligado a um grupo “virtual”, representado pela variável @sg,
cuja instância será selecionada dinamicamente em tempo
de execução. O serviço de descoberta integrado ao CR-RIO
[2] se encarrega de retornar uma lista contendo uma ou mais
instâncias da do módulo ServerGroup, e a função irá selecionar a melhor instância com base nas preferências especificadas na classe de utilidade SGUtil. A variante da função
de seleção com asterisco select* foi utilizada para que
periodicamente a infra-estrutura de suporte reavalie o melhor grupo de servidores disponı́vel, localizado no domı́nio
uff, e retorne a referência para @sg. Um domı́nio pode
ter a abrangência de uma rede, um sistema, uma sala etc.
Caso nenhum domı́nio seja informado, o domı́nio local de
operação é considerado como default.
As preferências do usuário em relação aos atributos da
classe de grupo de servidores são definidas na classe de utilidade SGUtil abaixo:
Utility {
delay = pref(Transport.delay) weight 0.6;
bandwidth = pref(Transport.bandwidth) weight 0.4;
utility(ServerGroup) = [delay, bandwidth];
} SGUtil;
normaA função de utilidade pref (v) = value(v)−min
max−min
liza os valores monitorados pelo ambiente para os atributos delay e bandwidth, que estão relacionados, respectivamente, ao atraso e banda passante na comunicação entre
o cliente e os grupos de servidores. Os atributos são associados às propriedades da categoria T ransport. Para
cada categoria, definida para um contrato, devem ser providos componentes de suporte correspondentes que vão
alocar/reservar e monitorar as respectivas caracterı́sticas,
denominados Agentes de Recurso no CR-RIO. Em seguida, designamos pesos relativos para os atributos. Neste
exempo, consideramos o delay o mais importante, seguido
de bandwidth. Isso foi especificado através de um peso
relativo de 0.6 para a dimensão de qualidade delay e 0.4
para bandwidth. Por fim, associamos o vetor de utilidades ao módulo ServerGroup. Dessa forma, a seleção
será feita através de uma função de utilidade que tenha
a melhor combinação dos critérios delay e bandwidth na
comunicação entre o cliente e o grupo.
4.2. Exemplo de Contrato para um Grupo
de Servidores
No contrato do grupo dos servidores, estamos interessados no tempo de resposta em relação ao processamento das
requisições pelos servidores pertencentes ao grupo. Assumimos que a sobrecarga se deve ao aumento do fluxo de
requisições e o tempo de resposta do grupo varia dinamicamente de acordo com a carga dos servidores. Em outros
casos, a sobrecarga poderia ser causada por problemas de
segurança, ou por algum outro fator especı́fico.
O contrato considera três situações em que o grupo de
servidores pode se encontrar: o tempo de resposta está
dentro de uma faixa aceitável (representado pelo perfil
respNormal), ou o tempo de resposta encontra-se alto, e
nessa situação o perfil respHigh se torna válido, ou então
o tempo de resposta está muito baixo, validando o perfil
respLow. O contrato é descrito abaixo:
contract {
service {} main with respNormal;
service {
instantiate Server as server;
ServerGroup.insert(server);
} addServer with respHigh;
service {
for server in ServerGroup.items()
server.setTextualMode()
} textualMode with respHigh;
service {
server = ServerGroup.remove();
remove server;
} removeServer with respLow;
service {
for server in ServerGroup.items()
server.setGraphicalMode()
} graphicalMode with respLow;
@conf = select*(ServiceClass, SGNego);
negotiation { @conf };
} SG;
De acordo com o contrato, quando o tempo de resposta
se encontra alto, para voltar a atender as requisições adequadamente, podemos adicionar servidores ao grupo visando
reduzir o tempo de resposta. Porém, existe a possibilidade de um aumento exagerado de requisições que não poderão ser atendidas, mesmo utilizando o tamanho máximo
de réplicas de servidores, devido ao orçamento ter chegado
ao limite. Neste caso, em vez de não fornecer serviço algum, uma opção é servir um conteúdo mı́nimo no formato
textual durante o perı́odo de pico. Quando o tempo de
resposta voltar ao normal, o número de réplicas de servidores do grupo pode então ser reduzido, a fim de economizar custo de operação (e.g. energia), ou ser realocado
para outro serviço, e também o conteúdo pode voltar para a
qualidade gráfica, a fim de melhor servir aos clientes. Assim, definimos três objetivos que influenciam a seleção de
configurações do grupo de servidores: (a) o tempo de resposta, (b) o custo operacional em relação aos servidores ativos e (c) a qualidade do conteúdo (textual ou gráfica).
Para decidir sobre qual adaptação escolher diante do contexto de execução, a negociação é orientada pela função de
seleção em que a classe ServiceClass representa o conjunto
de configurações de serviço pré-definido no contrato, e as
preferências e utilidades em relação às dimensões de qualidade para cada configuração são descritas na classe de utilidade SGN ego. A classe é descrita abaixo:
Utility {
response = {low:1,medium:0.5,high:0} weight 0.5;
budget = {under,unchanged:1,over:0} weight 0.3;
quality = {graph:1,unchanged:0.5,text:0} weight 0.2;
utility(main) =
[response.low,budget.under,quality.graph];
utility(addServer) =
[resp(Replication.replicas+1),
quality.unchanged,bud(Replication.replicas+1)];
utility(removeServer) =
[resp(Replication.replicas-1),
quality.unchanged,bud(Replication.replicas-1)];
utility(textualMode) =
[reponse.low,quality.textual,budget.unchanged];
utility(graphicalMode) =
[reponse.medium,quality.graphical,budget.unchanged];
} SGNego;
A cada configuração associamos um vetor de utilidades com os três objetivos (tempo de resposta, qualidade
do conteúdo e orçamento), onde as utilidades são discretizadas em um espaço de qualidade suficientemente expressivo do sistema. A idéia do vetor de utilidades é representar explicitamente os custos e efeitos esperados em relação
aos objetivos considerados, e utilizar essas informações na
seleção das configurações. Para calcular o vetor de utilidades das configurações addServer e removeServer,
utilizamos as funções resp e bud. A especificação adequada destas funções depende de uma análise prévia (ou
de técnicas de previsão) do comportamento do sistema em
que o contrato será aplicado. Por exemplo, em [14], foram
realizados experimentos sobre o desempenho do sistema variando o número de servidores ativos e a demanda a fim de
especificar essas funções de utilidade. Neste exemplo, assumimos que uma análise de desempenho foi realizada e a
função resp relaciona diretamente o número de servidores
a um valor de utilidade para o critério tempo de resposta,
sendo definida por:
response.medium, se S1 < ns < S2
resp(ns) = response.low,
se > S2
response.high,
senão
Onde S1 e S2 são os valores assumidos para o número de
servidores que indicam os intervalos de efeito sobre o tempo
de resposta. Por exemplo, caso o número de servidores que
se deseja adicionar seja maior que S2, o efeito é tornar o
tempo de resposta baixo (response.low). De forma similar,
a função bud relaciona o número de servidores a um valor
de utilidade de custo que indica se este número está acima
ou abaixo do orçamento:
(
budget.under, se ns ∗ c < BUD
bud(ns) =
budget.over,
senão
Onde c é o custo unitário por servidor e BU D é o valor
limite do orçamento. Em ambas as funções, a variável ns
representa o número de servidores.
Dessa forma, a partir do contrato, onde são descritas
as configurações, e da classe de utilidade, onde temos as
informações sobre as preferências de qualidade, a seleção
da adaptação será feita através de uma função de utilidade
que tenha a melhor combinação entre os objetivos: tempo
de resposta, qualidade e custo (orçamento).
5. Trabalhos Relacionados
O CR-RIO se relaciona com diversas outras propostas em relação a sistemas de suporte a implantação de
aplicações distribuı́das com requisitos não-funcionais. Uma
discussão abrangente neste sentido e trabalhos estruturantes, relacionados, são apresentados em [13]. Observamos
que recentemente vários trabalhos estão adotando a teoria da utilidade multiatributo como método para guiar as
adaptações dinâmicas em aplicações. Em [1], um modelo
de adaptação baseado em utilidade é proposto onde a decisão da adaptação é realizada por um middleware com suporte a descoberta dinâmica e seleção da melhor alternativa
de configuração da aplicação. Assim como em nosso trabalho, as funções de utilidade permitem expressar as preferências dos usuários, visando guiar a escolha da melhor
adaptação. O trabalho de [3] apresenta um exemplo de
aplicação cliente-servidor similar ao descrito neste artigo
e também propõe uma linguagem de adaptação, baseada na
teoria da utilidade, em que estratégias de reparo são definidas para impor as possı́veis adaptações no sistema.
Nossa abordagem é diferente das outras no sentido
de utilizar uma linguagem de contratos, onde temos
pré-definidas todas as configurações possı́veis para a
aplicação e um mecanismo que permite a negociação dessas configurações. Isso permite ao projetista do contrato
ter o controle total e prévio sobre a seqüência dos estados
durante uma adaptação, o que pode ser requerido em sistemas crı́ticos. Assim, durante o funcionamento da aplicação,
o mecanismo de negociação continuamente mantém a melhor configuração possı́vel diante do contexto de execução,
o que acreditamos que seja uma forma clara e sistemática
de expressar as adaptações.
[2]
[3]
6. Considerações Finais
[4]
Neste artigo mostramos que as funções de utilidade, integradas ao mecanismo de seleção do CR-RIO, permitem
expressar preferências em alto nı́vel de abstração, no contexto de um contrato, sobre as adaptações dinâmicas de
componentes e configurações da arquitetura de software da
aplicação. Contudo, a tarefa de elicitar corretamente as preferências em relação aos diversos objetivos da aplicação
é complexa. Acreditamos que esforços envolvendo o uso
de melhores interfaces, ferramentas e algoritmos são fundamentais para tornar o uso das polı́ticas baseadas em
funções de utilidade predominante nas aplicações adaptativas, autônomas e reconfiguráveis.
No momento, estamos planejando experimentos numa
plataforma real para validar nossa proposta. O mecanismo
de seleção de configurações (serviços) da aplicação irá flexibilizar o processo de negociação especificado no Gerenciador de Contratos do CR-RIO [4]. A seleção dinâmica de
componentes a serem configurados na aplicação, dentre um
conjunto disponı́vel no ambiente, será integrada ao Serviço
de Descoberta, como inicialmente descrito em [2].
Como trabalho futuro, estamos pesquisando sobre
funções de aprendizagem. Em vez de as preferências dos
atributos serem fixadas de antemão, um algoritmo de aprendizagem poderia ser usado para calcular esses valores durante o funcionamento da aplicação a partir de estı́mulos
do próprio ambiente, de forma similar ao trabalho proposto em [15]. Estamos estudando também a possibilidade de incorporar uma noção de custo de adaptação ao
cálculo das funções de utilidade [10]. Esse custo, adequadamente dimensionado, captura a tolerância do usuário em
relação a mudanças de configurações, tornando o sistema
mais estável em relação às adaptações. Isso porque o monitoramento e a comparação, de forma direta, de variáveis
altamente dinâmicas pode levar a instabilidade ou provocar
oscilações no sistema.
Referências
[1] M. Alia, V. S. W. Eide, N. Paspallis, F. Eliassen, S. O. Hallsteinsen, and G. A. Papadopoulos. A utility-based adaptivity
model for mobile applications. In AINAW ’07: Proceedings
of the 21st International Conference on Advanced Informa-
[5]
[6]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
[15]
tion Networking and Applications Workshops, pages 556–
563, Washington, DC, USA, 2007. IEEE Computer Society.
L. Cardoso. Integração de serviços de monitoração e descoberta de recursos a um suporte para arquiteturas adaptáveis
de software. Master’s thesis, Instituto de Computação/UFF,
2006.
S.-W. Cheng, D. Garlan, and B. Schmerl. Architecturebased self-adaptation in the presence of multiple objectives. In SEAMS ’06: Proceedings of the 2006 international workshop on Self-adaptation and self-managing systems, pages 2–8, New York, NY, USA, 2006. ACM Press.
A. S. Corradi. Um framework de suporte a requisitos nãofuncionais para serviços de nı́vel alto. Master’s thesis, Instituto de Computação/UFF, 2005.
D. Garlan, S.-W. Cheng, A.-C. Huang, B. Schmerl, and
P. Steenkiste. Rainbow: Architecture-based self adaptation
with reusable infrastructure. IEEE Computer, 37(10), October 2004.
L. F. A. M. Gomes, C. F. S. Gomes, and A. T. de Almeida.
Tomada de Decisão Gerencial – Enfoque Multicritério. Editora Atlas S.A., São Paulo, Brasil, 2002.
M. C. Huebscher and J. A. McCann. An adaptive middleware framework for context-aware applications. Personal
Ubiquitous Computing, 10(1):12–20, 2005.
J. O. Kephart and D. M. Chess. The vision of autonomic
computing. Computer, 36(1):41–50, 2003.
O. Loques, A. Sztajnberg, R. C. Cerqueira, and S. Ansaloni. A contract-based approach to describe and deploy nonfunctional adaptations in software architectures. Journal of
the Brazilian Computer Society, 10(1):5–18, July 2004.
V. Poladian, J. P. Sousa, D. Garlan, B. Schmerl, and
M. Shaw. Task-based adaptation for ubiquitous computing.
IEEE Transactions on Systems, Man, and Cybernetics, Part
C: Applications and Reviews, Special Issue on Engineering
Autonomic Systems, 36(3), May 2006.
V. Poladian, J. P. Sousa, D. Garlan, and M. Shaw. Dynamic
configuration of resource-aware services. In ICSE ’04: Proceedings of the 26th International Conference on Software
Engineering, pages 604–613, Washington, DC, USA, 2004.
IEEE Computer Society.
A. Sztajnberg. Flexibilidade e Separação de Interesses para
a Concepção e Evolução de Aplicações Distribuı́das. PhD
thesis, COPPE/PEE/UFRJ, Maio 2002.
A. Sztajnberg, A. Corradi, A. Santos, F. Barros, L. Cardoso,
and O. Loques. Especificação e suporte de requisitos nãofuncionais para serviços de nı́vel alto. In In: BRASILEIRO,
Francisco Vilar. (Org.). Minicursos do 23o Simposio Brasileiro de Redes de Computadores, Minicursos. Livro Texto.,
pages 223–279, 2005.
G. Tesauro and J. O. Kephart. Utility functions in autonomic
systems. In ICAC ’04: Proceedings of the First International
Conference on Autonomic Computing (ICAC’04), pages 70–
77, Washington, DC, USA, 2004. IEEE Computer Society.
B. D. Ziebart, D. Roth, R. H. Campbell, and A. K. Dey.
Learning automation policies for pervasive computing environments. In ICAC ’05: Proceedings of the Second International Conference on Automatic Computing, pages 193–203,
Washington, DC, USA, 2005. IEEE Computer Society.