Metaheurística com 2 variáveis

Essa versão é um pouquinho mais elaborada que a versão com uma variável (https://ferramentasexcelvba.wordpress.com/2021/03/27/exemplo-de-metaheuristica-uma-variavel/)

Serve para resolver o problema linear:

Max 10*x +5*y

Sujeito a:

2*x+4*y <= 50

1*x -6*y <= 15

É semelhante ao anterior, mas agora as variáveis são matrizes.

‘Inicializando coeficientes FO

coefFO(1) = 10

coefFO(2) = 5

‘Inicializando coeficientes Matriz

coefMatriz(1, 1) = 2

coefMatriz(1, 2) = 4

coefMatriz(2, 1) = 1

coefMatriz(2, 2) = -6

‘Inicializando rhs

RHS(1) = 50

RHS(2) = 15

Um parâmetro adicional, restringindo as variáveis a assumir valor máximo 50 e mínimo 0.

For i = 1 To nvar

    varmin(i) = 0 ‘Range Mínimo

    varmax(i) = 50 ‘Range Máximo

Next i

Em linhas gerais:

– Escolhe valores aleatórios no range das variáveis

– Pondera o valor aleatório com a melhor solução até agora

– Lambda controla o mix valor aleatório x melhor solução até agora. No início lambda é pequeno, depois vai aumentando

– Verifica se cumpre todas as restrições

 – função objetivo que avalia a solução

– salva o histórico

‘Algoritmo evolutivo

For iter = 1 To Niteracoes ‘Numero de iteracoes

    lambda = iter / Niteracoes

    ‘Sorteia um valor

    sorteia var, varmin, varmax, varbest, lambda

    ‘Verifica restricoes

    isOk = verificaRestricoes(var, coefMatriz, RHS)

    If isOk Then

        ‘Avalia a função atual

        FOatual = FO(var, coefFO)

        ‘Salva a melhor (maximizando)

        If FOatual > FOBest Then

            FOBest = FOatual

            copiaUni var, varbest

        End If

    End If

    FOhist(iter, 1) = FOBest

Next iter

Usando o solver, as variáveis ótimas são 22,5 e 1,25.


A metaheurística chega a valores próximos ao ótimo, o que mostra que funciona para uma solução suficientemente boa.

Provavelmente, com muitas variáveis e muitas restrições, vai ficar bem mais difícil convergir para uma solução boa.

Uma coisa ruim é todas as equações serem hard coded, mas quem domina código consegue fazer isso fácil.

É possível “tunar” esse algoritmo básico com pré processamento, ou algum chute guiado ao invés de ser basicamente aleatório, mas aí vai depender do problema.

Planilha para download no Github: https://github.com/asgunzi/Metaheuristica-2-var

A Conjectura de Collatz

A Conjectura de Collatz é o problema não resolvido de matemática mais simples da história.

Pegue um número qualquer n.

  • Se n for par, divida por 2
  • Se n for ímpar, calcule 3*n+1

E continue fazendo essa conta.

A conjectura diz que a sequência sempre vai convergir para 1.

Exemplo: número inicial 5

5 -> 16 -> 8 -> 4 -> 2 -> 1

Foram 5 passos para convergir para 1.

Exemplo: número inicial 6

6 -> 3 -> 10 -> 5 -> 16 ->  8 -> 4 -> 2 -> 1

Foram 8 passos para convergir para 1.

Para números de 2 a 50, o resultado do número de passos mostra:

Informações interessantes: apesar de extremamente simples de ser formulada, essa conjectura até hoje não foi provada.

É contra intuitivo; parece que vai crescer, mas aí converge.

A sequência é errática: um número pode precisar de 100 passos, o vizinho precisa de 5.

No VBA, a forma mais simples de resolver é com um simples loop while.

Function collatz(n)

Dim count As Long

count = 0
While n > 1

If n Mod 2 = 0 Then
    n = n / 2
Else
    n = 3 * n + 1
End If
count = count + 1

Wend

collatz = count

End Function

É possível pensar numa estrutura da dados mais complexa, porém com melhor performance computacional.

Por exemplo, salvar o número de passos de todos os valores já rodados. Rodar a sequência até chegar a um número menor do que o atual, e aí resgatar da memória o resultado já calculado.

Com esse método, é possível calcular os primeiros 110 mil números, em menos de 1 segundo.

No VBA, o limite é restrição de tamanho do tipo Long. Não há um tipo Big Int, como em Java ou Python, o que torna bem complicado calcular mais do que isso.

Código no Github: https://github.com/asgunzi/CollatzVBA

Veja também:

https://en.wikipedia.org/wiki/Collatz_conjecture

https://www.quantamagazine.org/why-mathematicians-still-cant-solve-the-collatz-conjecture-20200922/

Escrever por extenso

A macro da planilha (https://github.com/asgunzi/EscreverExtensoVBA) lê um número e escreve por extenso.

O código não é meu. Originalmente é VB6. Peguei num fórum e colei no Excel, e parece que funciona legal.

Não sei se isso pode ser útil de alguma forma.

Ideias técnicas com uma pitada de filosofia
https://ideiasesquecidas.com/

Entre no grupo de estudos de Computação Quântica:
https://www.facebook.com/groups/1013309389112487

Pequena rotina de criptografia

A criptografia existe desde a Roma antiga, pelo menos.

A forma mais básica de codificar / decodificar uma mensagem é com uma cifra de substituição simples.

Por exemplo, transformo a em w, b -> x, c -> y,

Segundo a tabela abaixo.

Exemplo:

“contar” -> “ykjpwn”

E para decodificar, fazer o oposto:

“ykjpwn” -> “contar”

Desafio: criar uma rotina que codifique/decodifique uma frase qualquer.

A minha resposta está no arquivo aqui.

Basta ativar macros e rodar. A macro faz exatamente o que a gente faria manualmente: para cada sílaba, procura na tabela qual o símbolo correspondente, e substitui.

Uma curiosidade. Tem um conto de Sherlock Holmes, chamado “o caso dos dançarinos”.

O detetive recebeu uma mensagem cifrada, com figuras de dançarinos. É a mesma lógica do desafio proposto, cifra de substituição simples.

Para quebrar o código, Holmes fez uma contagem dos símbolos. O dançarino que mais aparecia seria provavelmente o “E”, letra mais frequente em inglês. A seguir, o segundo símbolo mais frequente seria o “E”.

E assim sucessivamente, ele foi deduzindo as letras até decodificar a mensagem.

xkw pwnza lwnw pkzko!

Multiplicador de shapes – Power Point

Segue uma rotina que pode ser útil, para criar apresentações (Multiplicador.pptm)

É um “multiplicador de shapes”.

O objetivo é pegar um shape assim:

E criar cópias dele:

O primeiro passo é selecionar com o mouse o shape que queremos multiplicar.

Com o shape selecionado, rodamos a macro.  Atalho (alt + F11) para abrir o editor de macros, e F5 para rodar a macro “multiplier”

Vai surgir uma caixa, perguntando quantas linhas e colunas queremos (separar os números com um espaço)

Resultado:

Se eu tiver várias formas compostas, é necessário agrupar todos num único shape.

Resultado:

As macros devem estar habilitadas.


Ideias técnicas com uma pitada de filosofia

https://ideiasesquecidas.com/

Mudar cor de célula – VBA

Segue um exemplo de código VBA, para mudar a cor de  fundo de uma célula.

Todas as cores podem ser decompostas em vermelho, verde e azul. O código RGB atribui um número de 0 a 255 para cada cor.

O código a seguir diz para colorir o range “f4:g5” com as cores lidas na planilha.

R = Range(“b5”)

G = Range(“c5”)

B = Range(“d5”)

Exemplo no One Drive aqui.

Triângulo de Pascal em Excel

O triângulo de Pascal, em homenagem ao matemático Blaise Pascal, tem uma regra de formação bastante simples. Download aqui.

Cada linha começa e termina com 1. Os demais valores são a soma dos dois números acima da célula.

Ex. O valor 4 abaixo é a soma de 1 e 3, da linha acima.

Pascal - research

É bem simples criar um triângulo desses em Excel. É basicamente, colocar células de somar na posição correta.

A implementação em anexo utiliza macros, mas é a mesma ideia. Para colorir, é só usar formatação condicional.

Fica como exercício para casa: criar uma implementação do triângulo de Pascal.

Curiosidade: o mesmo triângulo é conhecido desde a antiguidade, sendo redescoberto em várias culturas.

Ideias técnicas com uma pitada de filosofia

https://ideiasesquecidas.com/

Joguinho de luzes

Uma aplicação de vba para colorir shapes.

Download aqui.

Cada seta troca as cores das luzes nos círculos – se estiver apagada, acende, e vice-versa.

O joguinho é deixar todas as luzes verde com o menor número de cliques.

É necessário ativar macros.

O joguinho ficou fácil demais. Se alguém tiver alguma ideia interessante, favor indicar.

Calculadora de IMC

Segue um projetinho simples.

Como fazer uma calculadora de IMC (Índice de massa corporal), utilizando formulários em Excel.

Com Alt + F11, abrimos o editor do VBA.

Inserir -> Userform

Vai abrir um formulário. Este formulário tem várias propriedades. Mudar a propriedade Caption (título) para IMC.

Na caixinha de controles, um deles é o label (um texto simples) e outro é uma caixa de texto (para input de dados).

Basta clicar no controle e inserir no formulário.

Inserir os elementos e posicionar no formulário.

No botão rodar, vai o código  que faz o cálculo.

Se a caixinha de texto se chama TxtPeso, para acessar o valor é TxtPeso.Value.

O IMC é o peso pela altura ao quadrado.

imc = peso / (altura ^ 2)

Pela tabela abaixo, temos a recomendação do IMC.

Resultado de imagem para imc tabela

E o resultado final é algo assim:

Link para download: https://drive.google.com/file/d/1DwMTDTahuvRk7JLeInMgdviUexA6bVuq/view?usp=sharing

Private Sub CommandButton1_Click()

Dim imc As Double

Dim peso As Double

Dim altura As Double

Dim texto As String

Dim txtAlt As String

If Information.IsNumeric(TxtPeso.Value) Then

    peso = TxtPeso.Value

Else

    MsgBox “Informar valor numérico para o peso”

    Exit Sub

End If

If Information.IsNumeric(TxtAltura.Value) Then

     altura = TxtAltura.Value

Else

    MsgBox “Informar valor numérico para a altura”

    Exit Sub

End If

imc = Math.Round(peso / (altura ^ 2), 1)

If imc < 17 Then

    texto = “IMC = ” & imc & “, Peso muito abaixo do ideal”

ElseIf imc < 18.5 Then

    texto = “IMC = ” & imc & “: Peso  abaixo do ideal”

ElseIf imc < 25 Then

    texto = “IMC = ” & imc & “: Peso normal”

ElseIf imc < 30 Then

    texto = “IMC = ” & imc & “: Acima do peso”

ElseIf imc < 35 Then

    texto = “IMC = ” & imc & “: Obesidade I”

ElseIf imc < 40 Then

    texto = “IMC = ” & imc & “; Obesidade II (severa)”

Else

    texto = “IMC = ” & imc & “: Obesidade III (mórbida)”

End If

Label3.Caption = texto

End Sub

Ideias técnicas com uma pitada de filosofia

http://ideiasesquecidas.com

2020 ao quadrado

Como encontrar pares de inteiros (não-negativos e maiores do que zero), tais que a^2 + b^2 = 2020^2?

Este tópico trouxe várias respostas criativas.

Resposta: são 4 pares (a,b) tais que a^2+b^2 = 2020^2:

 400 e 1980

868 e 1824

1212 e 1616

1344 e 1508

Seguem 4 resoluções, partindo da mais fácil para a mais elegante.

  1. O Arthur Bratti (de Santa Catarina) fez um tabelão, com as linhas e colunas variando de 1 a 2020, fez as contas para todas as alternativas, e ficou somente com as que davam 2020^2 = 4.080.400. Infelizmente, o excel ficou grande demais para enviar por e-mail. Como usa somente fórmulas de Excel, a lógica é bem simples.

O print abaixo é uma ilustração do método.

  1. Em VBA dá para fazer um loop for dentro de outro. Se for igual a 2020^2, guardo a solução, senão, vou para a próxima.

For i = 1 To 2019

    For j = i + 1 To 2019

        If i ^ 2 + j ^ 2 = 2020 ^ 2 Then

            c = c + 1

            sol(c, 1) = i

            sol(c, 2) = j

        End If

    Next

Next

  1. Python é a linguagem padrão em análise de dados (vide comentário aqui:

https://www.linkedin.com/posts/arnaldogunzi_as-linguagens-de-analytics-no-%C3%BAltimo-f%C3%B3rum-activity-6611608415540137984-48zg)

O mesmo código, em Python:

sol =[]

for a in range(2020):

    for b in  range(a+1,2020):

        if a**2 + b**2 == 2020**2:

            sol.append([a,b])

print(sol)

Note como Python é conciso e direto ao ponto.

  1. A solução mais elegante de todas for enviada pelo grande Marcos Melo. Utiliza matemática, ao invés de computação. Transcrevo aqui suas palavras.

A fórmula que engloba todos os números Pitagóricos é:

A= k*(X^2-Y^2)

B=k*(2*X*Y)

C= k*(X^2+Y^2)

Onde X e Y são primos entre si.

Como 2020 é 1*2*2*5*101

A chave é encontrar os resultados de hipotenusa X^2+Y^2=5: =101 e =505;

A hipotenusa 5 é do bem conhecido triângulo 3, 4 e 5 resultado do par X=2 e Y=1; multiplicado por 404 será de hipotenusa 2020.

(ou seja, resultado 1212 e 1616).

A hipotenusa 101 é do 20, 99 e 101 resultado do par X=10 e Y=1; multiplicado por 20 será de hipotenusa 2020.

(ou seja, o par 400 e 1980).

A hipotenusa 505 tem dois: o formado por X=21 e Y=8 e o X=19 e Y=12, que resultam nos triângulos 336, 377 e 505; e 217, 456.e 505; ambos multiplicados por 4 serão de hipotenusa 2020;

(ou seja, os dois pares faltantes: 868 e 1824; 1344 e 1508).