agroplan-ai-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/backend-template/.env.example +21 -0
- package/backend-template/Dockerfile +21 -0
- package/backend-template/README.md +274 -0
- package/backend-template/api.py +538 -0
- package/backend-template/core/bruteforce_validator.py +248 -0
- package/backend-template/core/genetic_optimizer.py +328 -0
- package/backend-template/core/loader.py +8 -0
- package/backend-template/core/planner.py +79 -0
- package/backend-template/core/report_generator.py +785 -0
- package/backend-template/core/scenario_simulator.py +286 -0
- package/backend-template/core/scorer.py +101 -0
- package/backend-template/core/terrain_analyzer.py +123 -0
- package/backend-template/data/culturas.csv +11 -0
- package/backend-template/data/regras_culturas.csv +11 -0
- package/backend-template/data/talhoes.csv +11 -0
- package/backend-template/main.py +487 -0
- package/backend-template/reports/.gitkeep +1 -0
- package/backend-template/requirements.txt +6 -0
- package/dist/index.js +719 -0
- package/package.json +51 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
from core.loader import carregar_dados
|
|
2
|
+
from core.planner import gerar_plano_inteligente, gerar_cenarios, gerar_plano_genetico
|
|
3
|
+
from core.scenario_simulator import recomendar_melhor_cenario
|
|
4
|
+
from core.bruteforce_validator import comparar_ag_com_forca_bruta, executar_multiplas_rodadas
|
|
5
|
+
from core.report_generator import gerar_relatorio_completo
|
|
6
|
+
|
|
7
|
+
def exibir_plano_detalhado():
|
|
8
|
+
"""Modo 1: Exibe análise detalhada com ranking completo"""
|
|
9
|
+
print("=" * 80)
|
|
10
|
+
print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
|
|
11
|
+
print(" Fase 1.5: Analisador de Terreno com Pontuação de Culturas")
|
|
12
|
+
print("=" * 80)
|
|
13
|
+
print()
|
|
14
|
+
|
|
15
|
+
# Carrega dados
|
|
16
|
+
print("📊 Carregando dados...")
|
|
17
|
+
culturas, talhoes, regras = carregar_dados()
|
|
18
|
+
print(f"✅ {len(culturas)} culturas carregadas")
|
|
19
|
+
print(f"✅ {len(talhoes)} talhões carregados")
|
|
20
|
+
print(f"✅ {len(regras)} regras de cultivo carregadas")
|
|
21
|
+
print()
|
|
22
|
+
|
|
23
|
+
# Gera plano de plantio inteligente
|
|
24
|
+
print("🧠 Analisando terrenos e gerando recomendações...")
|
|
25
|
+
plano = gerar_plano_inteligente(culturas, talhoes, regras)
|
|
26
|
+
print()
|
|
27
|
+
|
|
28
|
+
# Exibe resultados detalhados
|
|
29
|
+
print("=" * 80)
|
|
30
|
+
print("📋 ANÁLISE COMPLETA E RECOMENDAÇÕES")
|
|
31
|
+
print("=" * 80)
|
|
32
|
+
|
|
33
|
+
lucro_total = 0
|
|
34
|
+
area_total = 0
|
|
35
|
+
risco_ponderado = 0
|
|
36
|
+
|
|
37
|
+
for p in plano:
|
|
38
|
+
print()
|
|
39
|
+
print("─" * 80)
|
|
40
|
+
print(f"🌾 TALHÃO {p['talhao']} — {p['area']} ha")
|
|
41
|
+
print(f" Características: Solo {p['solo']} | Clima {p['clima']} | "
|
|
42
|
+
f"Relevo {p['relevo']} | Água {p['agua']}")
|
|
43
|
+
print()
|
|
44
|
+
|
|
45
|
+
# Ranking de culturas
|
|
46
|
+
print(" 📊 RANKING DE CULTURAS:")
|
|
47
|
+
for i, cultura in enumerate(p['ranking'][:5], 1): # Top 5
|
|
48
|
+
emoji = "🥇" if i == 1 else "🥈" if i == 2 else "🥉" if i == 3 else " "
|
|
49
|
+
print(f" {emoji} {i}º {cultura['cultura'].upper():10} — "
|
|
50
|
+
f"Nota: {cultura['nota']:5.2f} | "
|
|
51
|
+
f"Lucro: R$ {cultura['lucro_total']:>10,.2f} | "
|
|
52
|
+
f"Risco: {cultura['risco']}%")
|
|
53
|
+
|
|
54
|
+
print()
|
|
55
|
+
print(f" ✅ RECOMENDAÇÃO: Plantar {p['cultura_recomendada'].upper()}")
|
|
56
|
+
print(f" Nota final: {p['nota']:.2f}")
|
|
57
|
+
print(f" 💰 Lucro estimado: R$ {p['lucro_estimado']:,.2f}")
|
|
58
|
+
print(f" ⚠️ Risco: {p['risco']}%")
|
|
59
|
+
print(f" ⏱️ Tempo de colheita: {p['tempo']} dias")
|
|
60
|
+
print()
|
|
61
|
+
print(f" 💡 JUSTIFICATIVA:")
|
|
62
|
+
print(f" {p['justificativa']}")
|
|
63
|
+
|
|
64
|
+
lucro_total += p['lucro_estimado']
|
|
65
|
+
area_total += p['area']
|
|
66
|
+
risco_ponderado += p['risco'] * p['area']
|
|
67
|
+
|
|
68
|
+
risco_medio = risco_ponderado / area_total if area_total > 0 else 0
|
|
69
|
+
|
|
70
|
+
print()
|
|
71
|
+
print("=" * 80)
|
|
72
|
+
print("📈 RESUMO DO PLANO")
|
|
73
|
+
print("=" * 80)
|
|
74
|
+
print(f"💵 Lucro total estimado: R$ {lucro_total:,.2f}")
|
|
75
|
+
print(f"⚠️ Risco médio ponderado: {risco_medio:.1f}%")
|
|
76
|
+
print(f"🌾 Talhões planejados: {len(plano)}")
|
|
77
|
+
print(f"📏 Área total: {area_total} ha")
|
|
78
|
+
print("=" * 80)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def exibir_simulacao_cenarios():
|
|
82
|
+
"""Modo 2: Exibe comparação entre diferentes cenários"""
|
|
83
|
+
print("=" * 80)
|
|
84
|
+
print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
|
|
85
|
+
print(" Fase 2: Simulador de Cenários")
|
|
86
|
+
print("=" * 80)
|
|
87
|
+
print()
|
|
88
|
+
|
|
89
|
+
# Carrega dados
|
|
90
|
+
print("📊 Carregando dados...")
|
|
91
|
+
culturas, talhoes, regras = carregar_dados()
|
|
92
|
+
print(f"✅ {len(culturas)} culturas carregadas")
|
|
93
|
+
print(f"✅ {len(talhoes)} talhões carregados")
|
|
94
|
+
print(f"✅ {len(regras)} regras de cultivo carregadas")
|
|
95
|
+
print()
|
|
96
|
+
|
|
97
|
+
# Gera cenários
|
|
98
|
+
print("🧠 Simulando diferentes cenários de planejamento...")
|
|
99
|
+
cenarios = gerar_cenarios(culturas, talhoes, regras)
|
|
100
|
+
print()
|
|
101
|
+
|
|
102
|
+
# Exibe comparação de cenários
|
|
103
|
+
print("=" * 80)
|
|
104
|
+
print("📊 SIMULAÇÃO DE CENÁRIOS")
|
|
105
|
+
print("=" * 80)
|
|
106
|
+
print()
|
|
107
|
+
|
|
108
|
+
ordem_cenarios = ['equilibrado', 'maximo_lucro', 'baixo_risco', 'sustentavel', 'conservador']
|
|
109
|
+
|
|
110
|
+
for key in ordem_cenarios:
|
|
111
|
+
cenario = cenarios[key]
|
|
112
|
+
|
|
113
|
+
print("─" * 80)
|
|
114
|
+
print(f"🎯 CENÁRIO: {cenario['nome'].upper()}")
|
|
115
|
+
print(f" {cenario['descricao']}")
|
|
116
|
+
print()
|
|
117
|
+
print(f" 💰 Lucro total: R$ {cenario['lucro_total']:,.2f}")
|
|
118
|
+
print(f" ⚠️ Risco médio ponderado: {cenario['risco_medio']:.1f}%")
|
|
119
|
+
print(f" 📏 Área total: {cenario['area_total']} ha")
|
|
120
|
+
print()
|
|
121
|
+
print(" 🌾 Plano de plantio:")
|
|
122
|
+
|
|
123
|
+
for p in cenario['plano']:
|
|
124
|
+
print(f" Talhão {p['talhao']} ({p['area']} ha) → {p['cultura'].upper()} "
|
|
125
|
+
f"(Lucro: R$ {p['lucro_estimado']:,.2f} | Risco: {p['risco']}%)")
|
|
126
|
+
|
|
127
|
+
print()
|
|
128
|
+
|
|
129
|
+
# Recomendação do sistema
|
|
130
|
+
print("=" * 80)
|
|
131
|
+
print("✨ MELHOR CENÁRIO RECOMENDADO")
|
|
132
|
+
print("=" * 80)
|
|
133
|
+
print()
|
|
134
|
+
|
|
135
|
+
recomendacao = recomendar_melhor_cenario(cenarios)
|
|
136
|
+
cenario_recomendado = cenarios[recomendacao['cenario']]
|
|
137
|
+
|
|
138
|
+
print(f"🏆 Cenário: {cenario_recomendado['nome'].upper()}")
|
|
139
|
+
print()
|
|
140
|
+
print(f"💡 Justificativa:")
|
|
141
|
+
print(f" {recomendacao['justificativa']}")
|
|
142
|
+
print()
|
|
143
|
+
print("=" * 80)
|
|
144
|
+
|
|
145
|
+
# Tabela comparativa
|
|
146
|
+
print()
|
|
147
|
+
print("📊 TABELA COMPARATIVA")
|
|
148
|
+
print("=" * 80)
|
|
149
|
+
print(f"{'Cenário':<20} {'Lucro Total':>20} {'Risco Médio':>15}")
|
|
150
|
+
print("─" * 80)
|
|
151
|
+
|
|
152
|
+
for key in ordem_cenarios:
|
|
153
|
+
cenario = cenarios[key]
|
|
154
|
+
emoji = "🏆 " if key == recomendacao['cenario'] else " "
|
|
155
|
+
print(f"{emoji}{cenario['nome']:<17} R$ {cenario['lucro_total']:>15,.2f} {cenario['risco_medio']:>13.1f}%")
|
|
156
|
+
|
|
157
|
+
print("=" * 80)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def exibir_otimizacao_genetica(objetivo='equilibrado'):
|
|
161
|
+
"""Modo 3: Exibe otimização com Algoritmo Genético"""
|
|
162
|
+
print("=" * 80)
|
|
163
|
+
print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
|
|
164
|
+
print(" Fase 3: Otimizador com Algoritmo Genético")
|
|
165
|
+
print("=" * 80)
|
|
166
|
+
print()
|
|
167
|
+
|
|
168
|
+
# Carrega dados
|
|
169
|
+
print("📊 Carregando dados...")
|
|
170
|
+
culturas, talhoes, regras = carregar_dados()
|
|
171
|
+
print(f"✅ {len(culturas)} culturas carregadas")
|
|
172
|
+
print(f"✅ {len(talhoes)} talhões carregados")
|
|
173
|
+
print(f"✅ {len(regras)} regras de cultivo carregadas")
|
|
174
|
+
print()
|
|
175
|
+
|
|
176
|
+
# Executa otimização genética
|
|
177
|
+
print(f"🧬 Executando Algoritmo Genético (objetivo: {objetivo})...")
|
|
178
|
+
print(" Gerando população inicial...")
|
|
179
|
+
print(" Evoluindo soluções...")
|
|
180
|
+
resultado = gerar_plano_genetico(culturas, talhoes, regras, objetivo=objetivo, geracoes=100, populacao=50)
|
|
181
|
+
print(" ✅ Otimização concluída!")
|
|
182
|
+
print()
|
|
183
|
+
|
|
184
|
+
# Exibe resultado
|
|
185
|
+
print("=" * 80)
|
|
186
|
+
print("🧬 OTIMIZAÇÃO COM ALGORITMO GENÉTICO")
|
|
187
|
+
print("=" * 80)
|
|
188
|
+
print()
|
|
189
|
+
print(f"🎯 Objetivo: {resultado['objetivo'].upper()}")
|
|
190
|
+
print(f"🔄 Gerações: {resultado['geracoes']}")
|
|
191
|
+
print(f"📊 Fitness final: {resultado['fitness']:.2f}")
|
|
192
|
+
print(f"🌾 Diversidade: {resultado['diversidade']} cultura(s) diferente(s)")
|
|
193
|
+
print()
|
|
194
|
+
|
|
195
|
+
print("─" * 80)
|
|
196
|
+
print("📋 PLANO OTIMIZADO ENCONTRADO")
|
|
197
|
+
print("─" * 80)
|
|
198
|
+
print()
|
|
199
|
+
|
|
200
|
+
for p in resultado['plano']:
|
|
201
|
+
print(f"🌾 Talhão {p['talhao']} — {p['area']} ha")
|
|
202
|
+
print(f" Características: Solo {p['solo']} | Clima {p['clima']} | "
|
|
203
|
+
f"Relevo {p['relevo']} | Água {p['agua']}")
|
|
204
|
+
print(f" 🌱 Cultura: {p['cultura'].upper()}")
|
|
205
|
+
print(f" 💰 Lucro estimado: R$ {p['lucro_estimado']:,.2f}")
|
|
206
|
+
print(f" ⚠️ Risco: {p['risco']}%")
|
|
207
|
+
print(f" 📊 Nota de compatibilidade: {p['nota']:.2f}")
|
|
208
|
+
print(f" ⏱️ Tempo de colheita: {p['tempo']} dias")
|
|
209
|
+
print()
|
|
210
|
+
|
|
211
|
+
print("=" * 80)
|
|
212
|
+
print("📈 RESUMO DO PLANO OTIMIZADO")
|
|
213
|
+
print("=" * 80)
|
|
214
|
+
print(f"💵 Lucro total: R$ {resultado['lucro_total']:,.2f}")
|
|
215
|
+
print(f"⚠️ Risco médio ponderado: {resultado['risco_medio']:.1f}%")
|
|
216
|
+
print(f"📏 Área total: {resultado['area_total']} ha")
|
|
217
|
+
print(f"🌾 Culturas utilizadas: {resultado['diversidade']}")
|
|
218
|
+
print(f"🎯 Fitness alcançado: {resultado['fitness']:.2f}")
|
|
219
|
+
print()
|
|
220
|
+
print("💡 JUSTIFICATIVA:")
|
|
221
|
+
print(f" {resultado['justificativa']}")
|
|
222
|
+
print("=" * 80)
|
|
223
|
+
|
|
224
|
+
# Comparação com cenários manuais
|
|
225
|
+
print()
|
|
226
|
+
print("=" * 80)
|
|
227
|
+
print("📊 COMPARAÇÃO: AG vs CENÁRIOS MANUAIS")
|
|
228
|
+
print("=" * 80)
|
|
229
|
+
print()
|
|
230
|
+
|
|
231
|
+
cenarios = gerar_cenarios(culturas, talhoes, regras)
|
|
232
|
+
|
|
233
|
+
print(f"{'Estratégia':<25} {'Lucro Total':>20} {'Risco Médio':>15} {'Método':>15}")
|
|
234
|
+
print("─" * 80)
|
|
235
|
+
print(f"{'🧬 AG ' + resultado['objetivo'].title():<25} "
|
|
236
|
+
f"R$ {resultado['lucro_total']:>15,.2f} "
|
|
237
|
+
f"{resultado['risco_medio']:>13.1f}% "
|
|
238
|
+
f"{'Otimizado':>15}")
|
|
239
|
+
|
|
240
|
+
ordem_cenarios = ['equilibrado', 'maximo_lucro', 'baixo_risco', 'sustentavel', 'conservador']
|
|
241
|
+
nomes_cenarios = {
|
|
242
|
+
'equilibrado': 'Equilibrado',
|
|
243
|
+
'maximo_lucro': 'Máximo Lucro',
|
|
244
|
+
'baixo_risco': 'Baixo Risco',
|
|
245
|
+
'sustentavel': 'Sustentável',
|
|
246
|
+
'conservador': 'Conservador'
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
for key in ordem_cenarios:
|
|
250
|
+
cenario = cenarios[key]
|
|
251
|
+
print(f" {nomes_cenarios[key]:<22} "
|
|
252
|
+
f"R$ {cenario['lucro_total']:>15,.2f} "
|
|
253
|
+
f"{cenario['risco_medio']:>13.1f}% "
|
|
254
|
+
f"{'Manual':>15}")
|
|
255
|
+
|
|
256
|
+
print("=" * 80)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def exibir_validacao_ag(objetivo='equilibrado'):
|
|
260
|
+
"""Modo 4: Valida AG comparando com força bruta"""
|
|
261
|
+
print("=" * 80)
|
|
262
|
+
print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
|
|
263
|
+
print(" Fase 3.5: Validação do Algoritmo Genético")
|
|
264
|
+
print("=" * 80)
|
|
265
|
+
print()
|
|
266
|
+
|
|
267
|
+
# Carrega dados
|
|
268
|
+
print("📊 Carregando dados...")
|
|
269
|
+
culturas, talhoes, regras = carregar_dados()
|
|
270
|
+
print(f"✅ {len(culturas)} culturas carregadas")
|
|
271
|
+
print(f"✅ {len(talhoes)} talhões carregados")
|
|
272
|
+
print(f"✅ {len(regras)} regras de cultivo carregadas")
|
|
273
|
+
print()
|
|
274
|
+
|
|
275
|
+
print(f"🔬 Validando Algoritmo Genético (objetivo: {objetivo})...")
|
|
276
|
+
resultado = comparar_ag_com_forca_bruta(culturas, talhoes, regras, objetivo)
|
|
277
|
+
|
|
278
|
+
if resultado.get('erro'):
|
|
279
|
+
print(f"\n⚠️ {resultado['mensagem']}")
|
|
280
|
+
return
|
|
281
|
+
|
|
282
|
+
print()
|
|
283
|
+
print("=" * 80)
|
|
284
|
+
print("🔬 VALIDAÇÃO DO ALGORITMO GENÉTICO")
|
|
285
|
+
print("=" * 80)
|
|
286
|
+
print()
|
|
287
|
+
print(f"🎯 Objetivo: {objetivo.upper()}")
|
|
288
|
+
print(f"🔢 Total de combinações testadas por força bruta: {resultado['forca_bruta']['total_combinacoes']}")
|
|
289
|
+
print()
|
|
290
|
+
|
|
291
|
+
# Força Bruta
|
|
292
|
+
fb = resultado['forca_bruta']
|
|
293
|
+
print("─" * 80)
|
|
294
|
+
print("📊 MELHOR SOLUÇÃO POR FORÇA BRUTA")
|
|
295
|
+
print("─" * 80)
|
|
296
|
+
for p in fb['plano']:
|
|
297
|
+
print(f" Talhão {p['talhao']} → {p['cultura'].upper()}")
|
|
298
|
+
print()
|
|
299
|
+
print(f" 📊 Fitness: {fb['melhor_fitness']:.2f}")
|
|
300
|
+
print(f" 💰 Lucro total: R$ {fb['lucro_total']:,.2f}")
|
|
301
|
+
print(f" ⚠️ Risco médio: {fb['risco_medio']:.1f}%")
|
|
302
|
+
print(f" 🌾 Diversidade: {fb['diversidade']} cultura(s)")
|
|
303
|
+
print()
|
|
304
|
+
|
|
305
|
+
# AG
|
|
306
|
+
ag = resultado['ag']
|
|
307
|
+
print("─" * 80)
|
|
308
|
+
print("🧬 MELHOR SOLUÇÃO PELO ALGORITMO GENÉTICO")
|
|
309
|
+
print("─" * 80)
|
|
310
|
+
for p in ag['plano']:
|
|
311
|
+
print(f" Talhão {p['talhao']} → {p['cultura'].upper()}")
|
|
312
|
+
print()
|
|
313
|
+
print(f" 📊 Fitness: {ag['fitness']:.2f}")
|
|
314
|
+
print(f" 💰 Lucro total: R$ {ag['lucro_total']:,.2f}")
|
|
315
|
+
print(f" ⚠️ Risco médio: {ag['risco_medio']:.1f}%")
|
|
316
|
+
print(f" 🌾 Diversidade: {ag['diversidade']} cultura(s)")
|
|
317
|
+
print()
|
|
318
|
+
|
|
319
|
+
# Comparação
|
|
320
|
+
print("=" * 80)
|
|
321
|
+
print("📈 RESULTADO DA VALIDAÇÃO")
|
|
322
|
+
print("=" * 80)
|
|
323
|
+
print()
|
|
324
|
+
if resultado['ag_encontrou_otimo_global']:
|
|
325
|
+
print("✅ STATUS: O AG ENCONTROU O ÓTIMO GLOBAL")
|
|
326
|
+
else:
|
|
327
|
+
print("⚠️ STATUS: O AG NÃO ENCONTROU O ÓTIMO GLOBAL")
|
|
328
|
+
print()
|
|
329
|
+
print(f" Diferença de fitness: {resultado['diferenca_fitness']:.2f}")
|
|
330
|
+
print(f" Diferença de lucro: R$ {resultado['diferenca_lucro']:,.2f}")
|
|
331
|
+
print()
|
|
332
|
+
print("💡 ANÁLISE:")
|
|
333
|
+
print(f" {resultado['analise']}")
|
|
334
|
+
print()
|
|
335
|
+
print("=" * 80)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def exibir_multiplas_rodadas(objetivo='equilibrado', rodadas=10):
|
|
339
|
+
"""Modo 5: Executa AG múltiplas vezes para avaliar estabilidade"""
|
|
340
|
+
print("=" * 80)
|
|
341
|
+
print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
|
|
342
|
+
print(" Fase 3.5: Análise de Estabilidade do AG")
|
|
343
|
+
print("=" * 80)
|
|
344
|
+
print()
|
|
345
|
+
|
|
346
|
+
# Carrega dados
|
|
347
|
+
print("📊 Carregando dados...")
|
|
348
|
+
culturas, talhoes, regras = carregar_dados()
|
|
349
|
+
print(f"✅ {len(culturas)} culturas carregadas")
|
|
350
|
+
print(f"✅ {len(talhoes)} talhões carregados")
|
|
351
|
+
print(f"✅ {len(regras)} regras de cultivo carregadas")
|
|
352
|
+
print()
|
|
353
|
+
|
|
354
|
+
print(f"🔄 Executando {rodadas} rodadas do AG (objetivo: {objetivo})...")
|
|
355
|
+
print()
|
|
356
|
+
resultado = executar_multiplas_rodadas(culturas, talhoes, regras, objetivo, rodadas)
|
|
357
|
+
print()
|
|
358
|
+
|
|
359
|
+
print("=" * 80)
|
|
360
|
+
print("📊 ANÁLISE DE ESTABILIDADE DO ALGORITMO GENÉTICO")
|
|
361
|
+
print("=" * 80)
|
|
362
|
+
print()
|
|
363
|
+
print(f"🎯 Objetivo: {objetivo.upper()}")
|
|
364
|
+
print(f"🔄 Rodadas executadas: {resultado['rodadas']}")
|
|
365
|
+
print()
|
|
366
|
+
print("─" * 80)
|
|
367
|
+
print("📈 ESTATÍSTICAS DE FITNESS")
|
|
368
|
+
print("─" * 80)
|
|
369
|
+
print(f" 🏆 Melhor fitness: {resultado['melhor_fitness']:.2f}")
|
|
370
|
+
print(f" 📊 Fitness médio: {resultado['fitness_medio']:.2f}")
|
|
371
|
+
print(f" 📉 Pior fitness: {resultado['pior_fitness']:.2f}")
|
|
372
|
+
print(f" 📏 Desvio padrão: {resultado['desvio_padrao']:.2f}")
|
|
373
|
+
print(f" 📐 Coeficiente de variação: {resultado['coeficiente_variacao']:.2f}%")
|
|
374
|
+
print()
|
|
375
|
+
print(f" 💰 Lucro médio: R$ {resultado['lucro_medio']:,.2f}")
|
|
376
|
+
print(f" ⚠️ Risco médio: {resultado['risco_medio']:.1f}%")
|
|
377
|
+
print()
|
|
378
|
+
|
|
379
|
+
# Estabilidade
|
|
380
|
+
emoji_estabilidade = "🟢" if resultado['estabilidade'] == 'alta' else "🟡" if resultado['estabilidade'] == 'média' else "🔴"
|
|
381
|
+
print("─" * 80)
|
|
382
|
+
print(f"{emoji_estabilidade} ESTABILIDADE: {resultado['estabilidade'].upper()}")
|
|
383
|
+
print("─" * 80)
|
|
384
|
+
print(f" {resultado['estabilidade_descricao']}")
|
|
385
|
+
print()
|
|
386
|
+
|
|
387
|
+
# Melhor plano
|
|
388
|
+
melhor = resultado['melhor_plano']
|
|
389
|
+
print("=" * 80)
|
|
390
|
+
print("🏆 MELHOR PLANO ENCONTRADO")
|
|
391
|
+
print("=" * 80)
|
|
392
|
+
print()
|
|
393
|
+
for p in melhor['plano']:
|
|
394
|
+
print(f" Talhão {p['talhao']} ({p['area']} ha) → {p['cultura'].upper()}")
|
|
395
|
+
print(f" Lucro: R$ {p['lucro_estimado']:,.2f} | Risco: {p['risco']}% | Nota: {p['nota']:.2f}")
|
|
396
|
+
print()
|
|
397
|
+
print(f" 📊 Fitness: {melhor['fitness']:.2f}")
|
|
398
|
+
print(f" 💰 Lucro total: R$ {melhor['lucro_total']:,.2f}")
|
|
399
|
+
print(f" ⚠️ Risco médio: {melhor['risco_medio']:.1f}%")
|
|
400
|
+
print(f" 🌾 Diversidade: {melhor['diversidade']} cultura(s)")
|
|
401
|
+
print()
|
|
402
|
+
print("=" * 80)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def gerar_relatorio(objetivo='equilibrado'):
|
|
406
|
+
"""Modo 6: Gera relatório completo"""
|
|
407
|
+
print("=" * 80)
|
|
408
|
+
print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
|
|
409
|
+
print(" Fase 4: Geração de Relatórios")
|
|
410
|
+
print("=" * 80)
|
|
411
|
+
print()
|
|
412
|
+
|
|
413
|
+
# Carrega dados
|
|
414
|
+
print("📊 Carregando dados...")
|
|
415
|
+
culturas, talhoes, regras = carregar_dados()
|
|
416
|
+
print(f"✅ {len(culturas)} culturas carregadas")
|
|
417
|
+
print(f"✅ {len(talhoes)} talhões carregados")
|
|
418
|
+
print(f"✅ {len(regras)} regras de cultivo carregadas")
|
|
419
|
+
print()
|
|
420
|
+
|
|
421
|
+
print(f"📝 Gerando relatório completo (objetivo: {objetivo})...")
|
|
422
|
+
print()
|
|
423
|
+
|
|
424
|
+
# Gera relatórios em ambos os formatos
|
|
425
|
+
caminho_md = gerar_relatorio_completo(culturas, talhoes, regras, objetivo, formato='md')
|
|
426
|
+
caminho_txt = gerar_relatorio_completo(culturas, talhoes, regras, objetivo, formato='txt')
|
|
427
|
+
|
|
428
|
+
print()
|
|
429
|
+
print("=" * 80)
|
|
430
|
+
print("✅ RELATÓRIOS GERADOS COM SUCESSO")
|
|
431
|
+
print("=" * 80)
|
|
432
|
+
print()
|
|
433
|
+
print("📄 Arquivos criados:")
|
|
434
|
+
print(f" - {caminho_md}")
|
|
435
|
+
print(f" - {caminho_txt}")
|
|
436
|
+
print()
|
|
437
|
+
print("💡 Dica: Abra o arquivo .md em um visualizador Markdown para melhor formatação")
|
|
438
|
+
print("=" * 80)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def main():
|
|
442
|
+
"""Menu principal"""
|
|
443
|
+
import sys
|
|
444
|
+
|
|
445
|
+
# Verifica argumentos
|
|
446
|
+
if len(sys.argv) > 1:
|
|
447
|
+
modo = sys.argv[1].lower()
|
|
448
|
+
|
|
449
|
+
if modo == 'detalhado':
|
|
450
|
+
exibir_plano_detalhado()
|
|
451
|
+
elif modo == 'genetico':
|
|
452
|
+
# Verifica se há objetivo específico
|
|
453
|
+
objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
|
|
454
|
+
if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
|
|
455
|
+
print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
|
|
456
|
+
objetivo = 'equilibrado'
|
|
457
|
+
exibir_otimizacao_genetica(objetivo)
|
|
458
|
+
elif modo == 'validar':
|
|
459
|
+
# Validação com força bruta
|
|
460
|
+
objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
|
|
461
|
+
if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
|
|
462
|
+
print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
|
|
463
|
+
objetivo = 'equilibrado'
|
|
464
|
+
exibir_validacao_ag(objetivo)
|
|
465
|
+
elif modo == 'rodadas':
|
|
466
|
+
# Múltiplas rodadas
|
|
467
|
+
objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
|
|
468
|
+
if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
|
|
469
|
+
print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
|
|
470
|
+
objetivo = 'equilibrado'
|
|
471
|
+
rodadas = int(sys.argv[3]) if len(sys.argv) > 3 else 10
|
|
472
|
+
exibir_multiplas_rodadas(objetivo, rodadas)
|
|
473
|
+
elif modo == 'relatorio':
|
|
474
|
+
# Geração de relatório
|
|
475
|
+
objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
|
|
476
|
+
if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
|
|
477
|
+
print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
|
|
478
|
+
objetivo = 'equilibrado'
|
|
479
|
+
gerar_relatorio(objetivo)
|
|
480
|
+
else:
|
|
481
|
+
exibir_simulacao_cenarios()
|
|
482
|
+
else:
|
|
483
|
+
exibir_simulacao_cenarios()
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
if __name__ == "__main__":
|
|
487
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Pasta para relatórios gerados
|