! ------------------------------------------------------------ ! Modelo Mosel para o Problema "Ali e Amigos" (P4) ! Autor: Zanoni Dias ! Data: 16/maio/2006 ! ------------------------------------------------------------ model P4 ! ------------------------------------------------------------ ! usa biblioteca do resolvedor linear ! ------------------------------------------------------------ uses "mmxprs" ! ------------------------------------------------------------ ! delta usado para contornar problemas de precisao numerica ! ------------------------------------------------------------ parameters DELTA = sqrt(getparam("zerotol")) end-parameters ! ------------------------------------------------------------ ! declaracao das variaveis do programa ! ------------------------------------------------------------ declarations nomearq : string ! nome do arquivo de entrada n: integer ! numero de assaltantes k: integer ! numero de itens x: real ! porcentagem de erro vj: real ! valor justo soma: real ! variavel temporaria end-declarations ! ------------------------------------------------------------ ! solicita ao usuario que forneca o arquivo de entrada ! ------------------------------------------------------------ !writeln("Qual o nome do arquivo de entrada? ") readln(nomearq) ! ------------------------------------------------------------ ! inicializa a variavel "n" a partir do arquivo "nomearq" ! ------------------------------------------------------------ initializations from nomearq n k x end-initializations ! ------------------------------------------------------------ ! declaracao das variaveis do tipo array cujas dimensoes ! dependem da variavel "n" ! ! Nota: "y" eh uma variavel do MODELO e portanto do tipo ! "mpvar". Ela sera binaria (restricao mais abaixo) e ! "y(i,j)=1" se e somente se o item "i" foi ! atribuido ao ao assaltante j ! ------------------------------------------------------------ declarations itens:array(1..k) of real ! itens y: array(1..k,1..n) of mpvar ! variaveis do modelo end-declarations ! ------------------------------------------------------------ ! inicializacao da matriz de adjacencias a partir do arquivo ! "nomearq" ! ------------------------------------------------------------ initializations from nomearq itens end-initializations ! ------------------------------------------------------------ ! Cria as variaveis do modelo ! ------------------------------------------------------------ forall (i in 1..k) forall (j in 1..n) do create(y(i,j)) y(i,j) is_binary end-do ! ------------------------------------------------------------ ! Calcula o valor justo ! ------------------------------------------------------------ vj := (sum(i in 1..k) itens(i)) / n ! ------------------------------------------------------------ ! Nenhum assaltante pode receber um conjunto de itens que ! esteja muito distante do "valor justo" ! ------------------------------------------------------------ forall(j in 1..n) do ValorJustoMin(j) := sum(i in 1..k) (y(i,j)*itens(i)) >= vj*((100-x)/100) ValorJustoMax(j) := sum(i in 1..k) (y(i,j)*itens(i)) <= vj*((100+x)/100) end-do ! ------------------------------------------------------------ ! Um item so pode ser associado a um bandido ! ------------------------------------------------------------ forall(i in 1..k) Unicidade(i) := sum(j in 1..n) y(i,j) = 1 ! ------------------------------------------------------------ ! Monta a funcao objetivo ! ------------------------------------------------------------ Objetivo := sum(i in 1..k) y(i,1)*itens(i) ! ------------------------------------------------------------ ! Resolve o modelo (maximizacao) ! ------------------------------------------------------------ maximize(Objetivo) ! ------------------------------------------------------------ ! Imprime a distribuicao de itens ! ------------------------------------------------------------ ! Se encontrou uma solucao otima if (getprobstat = XPRS_OPT) then writeln("Valor otimo = ", strfmt(getobjval,1,2)) !writeln(vj*((100-x)/100), " <= valor justo <= ", vj*((100+x)/100)) forall(j in 1..n) do soma := 0 forall(i in 1..k) if(getsol(y(i,j)) >= 1-DELTA) then ! write(itens(i), " ") soma := soma + itens(i) end-if writeln("Assaltante ",j,": ", strfmt(soma,1,2)) end-do else ! Nao existe solucao otima writeln("Valor otimo nao encontrado") end-if end-model