Jander0 / Inteligenciacomputacional

0 stars 0 forks source link

Logica Fuzzy para doze de quinino #1

Open Jander0 opened 1 year ago

Jander0 commented 1 year ago

Resposta para: Construa um programa baseado em lógica fuzzy conforme as regras disponibilizadas na Seção 18.9 (Sistema para recomendar dose de quinino) do livro “Inteligência Artificial”, Ben Coppin; LTC, 2010. O programa deverá solicitar as entradas ao usuário e exibir a saída produzida. Obs. 1 – na Regra 3, executar o operador lógico OU antes do E. 2 – Não usar aplicações que realizem diretamente a tarefa, como, por exemplo, o Fuzzy Logic Designer do MATLAB.

Jander0 commented 1 year ago

clear clc clf

// Função que recebe um valor e um conjunto fuzzy de entrada e retorna o pertencimento do valor ao conjunto // Formato de um conjunto fuzzy: // [ // valor_minimo, grau_de_pertencimento; // ... // valor_mediano, grau_de_pertencimento; // valor_maximo, grau_de_pertencimento; // ] function [result]=pertencimento(val, conjuntoFuzzy) // Verifica se o valor é menor do que o valor mínimo do conjunto e retorna seu grau de pertencimento if (val < conjuntoFuzzy(1, 1)) then result = conjuntoFuzzy(1, 2) return end

fuzzyLength = size(conjuntoFuzzy)(1)

// Verifica se o valor é maior do que o valor máximo do conjunto e retorna seu grau de pertencimento if (val > conjuntoFuzzy(fuzzyLength, 1)) then result = conjuntoFuzzy(fuzzyLength, 2) return end

// Verifica se o valor é igual a algum dos valores de referencia do conjunto e retorna seu grau de pertencimento for i=1:fuzzyLength if (conjuntoFuzzy(i, 1) == val) then result = conjuntoFuzzy(i, 2) return end end

// Cria um vetor com os valores de referencia do conjunto (sem os pertencimentos) localizador = [] for i=1:fuzzyLength localizador = [localizador conjuntoFuzzy(i, 1)] end

// Procura no vetor localizador o valor anterior ao procurado preVal = find(localizador < val) preVal = preVal(length(preVal))

// Procura no vetor localizador o valor posterior ao procurado posVal = find(localizador > val) posVal = posVal(1)

// Verifica se os pertencimentos associados ao valores anteriores e posteriores ao procurado são iguais e retorna seu grau de pertencimento if (conjuntoFuzzy(preVal, 2) == conjuntoFuzzy(posVal, 2)) then result = conjuntoFuzzy(preVal, 2) return end

// Calcula a distância do valor procurado ao valor anterior e posterior e aproxima o resultado do grau de pertencimento result = abs(conjuntoFuzzy(preVal, 2) - ((val-conjuntoFuzzy(preVal, 1))/(conjuntoFuzzy(posVal, 1)-conjuntoFuzzy(preVal, 1)))) endfunction

// Função que recebe os valores de entrada requeridos pelas regras e uma variável booleana para ativar o debugMode (imprime no console os valores calculados) function [result]=pressaoFreio(pressPedal, velRoda, velCarro, debugMode) // Conjunto fuzzy de pressão do freio baixo, médio e alto pressPedalFuzzyBaixo = [0 1; 50 0] pressPedalFuzzyMedio = [30 0; 50 1; 70 0] pressPedalFuzzyAlto = [50 0; 100 1]

// Conjunto fuzzy da velocidade da roda e do carro (já que são iguais) baixo, médio e alto velRodaCarroFuzzyBaixo = [0 1; 60 0] velRodaCarroFuzzyMedio = [20 0; 50 1; 80 0] velRodaCarroFuzzyAlto = [40 0; 100 1]

// Regra 1 - resposta para aperte o freio (pressão do freio no conjunto médio) aperteRegra1 = pertencimento(pressPedal, pressPedalFuzzyMedio)

if (debugMode) then printf("pertencimento(%f pressPedalFuzzyMedio): %f\n", pressPedal, aperteRegra1) printf("aperteRegra1: %f\n", aperteRegra1) end

// Regra 2 - resposta para aperte o freio // Pressão do freio no conjunto alto pressPedalRegra2 = pertencimento(pressPedal, pressPedalFuzzyAlto) // Velocidade do carro no conjunto alto velCarroRegra2 = pertencimento(velCarro, velRodaCarroFuzzyAlto) // Velocidade da roda no conjunto alto velRodaRegra2 = pertencimento(velRoda, velRodaCarroFuzzyAlto) // Resultado - mínimo dos valores acima da regra 2 aperteRegra2 = min([pressPedalRegra2 velCarroRegra2 velRodaRegra2])

if (debugMode) then printf("pertencimento(%f pressPedalFuzzyAlto): %f\n", pressPedal, pressPedalRegra2) printf("pertencimento(%f velRodaCarroFuzzyAlto): %f\n", velCarro, velCarroRegra2) printf("pertencimento(%f velRodaCarroFuzzyAlto): %f\n", velRoda, velRodaRegra2) printf("aperteRegra2(min): %f\n", aperteRegra2) end

// Regra 3 - resposta para libere o freio // Pressão do freio no conjunto alto pressPedalRegra3 = pertencimento(pressPedal, pressPedalFuzzyAlto) // Velocidade do carro no conjunto alto velCarroRegra3 = pertencimento(velCarro, velRodaCarroFuzzyAlto) // Velocidade da roda no conjunto baixo velRodaRegra3 = pertencimento(velRoda, velRodaCarroFuzzyBaixo) // Resultado - mínimo dos valores acima da regra 3 libereRegra3 = min([pressPedalRegra3 velCarroRegra3 velRodaRegra3])

if (debugMode) then printf("pertencimento(%f pressPedalFuzzyAlto): %f\n", pressPedal, pressPedalRegra3) printf("pertencimento(%f velRodaCarroFuzzyAlto): %f\n", velCarro, velCarroRegra3) printf("pertencimento(%f velRodaCarroFuzzyBaixo): %f\n", velRoda, velRodaRegra3) printf("libereRegra3(min): %f\n", libereRegra3) end

// Regra 4 - resposta para libere o freio (pressão do freio no conjunto baixo) libereRegra4 = pertencimento(pressPedal, pressPedalFuzzyBaixo)

if (debugMode) then printf("pertencimento(%f pressPedalFuzzyBaixo): %f\n", pressPedal, libereRegra4) printf("libereRegra4: %f\n", libereRegra4) end

// Soma das regras para aperte e libere o freio aperteSoma = aperteRegra1 + aperteRegra2 libereSoma = libereRegra3 + libereRegra4

if (debugMode) then printf("aperteSoma: %f | libereSoma: %f\n", aperteSoma, libereSoma) end

// Resultado final result = [libereSoma aperteSoma]

// Conjuntos fuzzy das respostas e suas respectivas equações de reta, serão usados adiante para plotar os gráficos // freioRespostaAperte: [0 0; 100 1] || y=x0.01 // freioRespostaLibere: [0 1; 100 0] || y=x-0.01

// Vetores de valores para plotar as retas de respostas eixoX = linspace(0, 100, 100) freioRespostaAperte = eixoX0.01 freioRespostaLibere = eixoX-0.01+1

// Calcula os pontos X de intersecção das retas de comando (valor de apertar ou liberar o freio) com as retas de resposta intersecLimiteSuperiorAperte = 100aperteSoma intersecLimiteInferiorLibere = -100(libereSoma - 1)

// Se em modo de debug mostra os pontos de intersecção if (debugMode) then plot(intersecLimiteSuperiorAperte, aperteSoma, "kv") plot(intersecLimiteInferiorLibere, libereSoma, "mv") end

// grafArea = [grafArea i-0.01+1] // grafArea = [grafArea i0.01] // grafArea = [grafArea libereSoma] // grafArea = [grafArea aperteSoma] grafArea = [] grafAperte = [] grafLibere = [] grafAperte1 = [] grafLibere1 = [] grafAperte2 = [] grafLibere2 = []

// Percorre o eixo X para calcular a área do gráfico de resposta aperte for i=0:(length(eixoX) - 1) if (i <= intersecLimiteSuperiorAperte) then grafAperte = [grafAperte i*0.01] else grafAperte = [grafAperte aperteSoma] end end

// Percorre o eixo X para calcular a área do gráfico de resposta libere for i=0:(length(eixoX) - 1) if (i < intersecLimiteInferiorLibere) then grafLibere = [grafLibere libereSoma] else grafLibere = [grafLibere i*-0.01+1] end end

// Pega a intersecção aproximada dos gráficos de reposta aperte e libere respostaIntersecX = 0 for i=1:length(eixoX) if (grafAperte(i) < grafLibere(i) + 0.01 & grafAperte(i) > grafLibere(i) - 0.01) then respostaIntersecX = i break end end

// Divide as áreas dos gráficos antes e depois da intersecção entre eles for i=1:length(eixoX) if (i <= respostaIntersecX) then grafAperte1 = [grafAperte1 grafAperte(i)] grafLibere1 = [grafLibere1 grafLibere(i)] else grafAperte2 = [grafAperte2 grafAperte(i)] grafLibere2 = [grafLibere2 grafLibere(i)] end end

// Verifica qual das áreas é maior antes e depois da intersecção e gera o vetor para somatório final das áreas if (sum(grafAperte1) > sum(grafLibere1)) then grafArea = [grafArea grafAperte1] else grafArea = [grafArea grafLibere1] end if (sum(grafAperte2) > sum(grafLibere2)) then grafArea = [grafArea grafAperte2] else grafArea = [grafArea grafLibere2] end

// Calculo do centroide da área do gráfico centroide = sum(grafArea.*eixoX)/sum(grafArea) // Evita o calculo do centroide de uma área vazia (NaN) if (sum(grafArea) == 0) then centroide = 0 end

// retorna o centroide como resposta da função result = centroide

printf("Aperte: %f\n", aperteSoma) printf("Libere: %f\n", libereSoma) printf("Centroide: %f\n", centroide)

if (debugMode) then printf("Área do Gráfico: %f\n", grafArea) plot(eixoX, grafAperte, "b-") plot(eixoX, grafLibere, "b-") end

// Plota as funções, as retas e a área do gráfico plot(eixoX, grafArea, "b-") plot(eixoX, freioRespostaAperte, "--r") plot(eixoX, freioRespostaLibere, "--g") plot([0 100], [aperteSoma aperteSoma], "--k") plot([0 100], [libereSoma libereSoma], "--m") xtitle("Resultado", "Pressão") legend("Área Resultante", "Aperte o Freio", "Libere o Freio", "Limite Superior", "Limite Inferior", 1)

endfunction

// Pede a entrada de valores no terminal para o usuário function askValues() pressPedalInput = input("Digite o valor da pressão no pedal: ") velRodaInput = input("Digite o valor da velocidade da roda: ") velCarroInput = input("Digite o valor da velocidade do carro: ")

// Executa a função para calcular a resposta da lógica do freio pressaoFreio(pressPedalInput, velRodaInput, velCarroInput, %f) endfunction

// Executa o programa askValues()