Arthur-Attili commited on
Commit
d8858c4
·
verified ·
1 Parent(s): 8571ff6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -39
app.py CHANGED
@@ -85,24 +85,16 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
85
  if not grupos_filtrados:
86
  return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
87
 
88
- # TOLERÂNCIAS ADAPTATIVAS - Ajusta com base no valor
89
- # Para valores altos, aumenta a tolerância percentual
90
- def calcular_tolerancia(valor, tolerancia_base, tolerancia_min, tolerancia_max):
91
- if valor > 1000000: # Para valores acima de 1 milhão
92
- # Reduz gradualmente a tolerância percentual conforme o valor aumenta
93
- fator = max(tolerancia_min, min(tolerancia_max, tolerancia_base * (1000000 / valor)**0.5))
94
- return fator
95
- return tolerancia_base
96
-
97
- # Tolerâncias base
98
- tolerancia_credito_base = 0.10 # 10%
99
- tolerancia_entrada_base = 0.10 # 10%
100
- tolerancia_parcela_base = 0.30 # 30%
101
-
102
- # Calcula tolerâncias adaptativas
103
- tolerancia_credito = calcular_tolerancia(credito_desejado, tolerancia_credito_base, 0.15, 0.25)
104
- tolerancia_entrada = calcular_tolerancia(entrada_desejada, tolerancia_entrada_base, 0.15, 0.25)
105
- tolerancia_parcela = calcular_tolerancia(parcela_desejada, tolerancia_parcela_base, 0.40, 0.50)
106
 
107
  # Define faixas de tolerância
108
  credito_min = credito_desejado * (1 - tolerancia_credito)
@@ -112,35 +104,26 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
112
  parcela_min = parcela_desejada * (1 - tolerancia_parcela)
113
  parcela_max = parcela_desejada * (1 + tolerancia_parcela)
114
 
115
- print(f"🔧 Tolerâncias aplicadas: Crédito: ±{tolerancia_credito*100:.1f}%, Entrada: ±{tolerancia_entrada*100:.1f}%, Parcela: ±{tolerancia_parcela*100:.1f}%")
 
116
 
117
  resultados = []
118
 
119
  # Para cada administradora, busca combinações
120
  for adm, cotas in grupos_filtrados.items():
121
- # Pré-filtra cotas que individualmente estão dentro das faixas de tolerância
122
- cotas_filtradas = []
123
- for cota in cotas:
124
- cota_credito = cota['valor_credito']
125
- cota_entrada = cota['valor_entrada'] + (cota_credito * 0.085)
126
- cota_parcela = cota['valor_parcela']
127
-
128
- if (credito_min <= cota_credito <= credito_max and
129
- entrada_min <= cota_entrada <= entrada_max and
130
- parcela_min <= cota_parcela <= parcela_max):
131
- cotas_filtradas.append(cota)
132
 
133
- # Se não cotas individuais dentro da tolerância, tenta combinações
134
- if not cotas_filtradas:
135
- cotas_filtradas = cotas # Usa todas as cotas para combinações
136
 
137
- # Gera combinações (até 3 cotas por combinação para performance)
138
- for r in range(1, min(4, len(cotas_filtradas) + 1)):
139
  # Limita o número de combinações testadas por administradora
140
- max_combinacoes_por_adm = 50
141
  combinacoes_geradas = 0
142
 
143
- for combinacao in itertools.combinations(cotas_filtradas, r):
144
  if combinacoes_geradas >= max_combinacoes_por_adm:
145
  break
146
 
@@ -149,6 +132,7 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
149
  total_entrada = total_entrada_base + (total_credito * 0.085)
150
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
151
 
 
152
  if (credito_min <= total_credito <= credito_max and
153
  entrada_min <= total_entrada <= entrada_max and
154
  parcela_min <= total_parcelas <= parcela_max):
@@ -161,7 +145,76 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
161
  combinacoes_geradas += 1
162
 
163
  # Para se já encontrou combinações suficientes
164
- if len(resultados) >= max_combinacoes * 3: # Coleta mais para depois filtrar as melhores
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  break
166
 
167
  if len(resultados) >= max_combinacoes * 3:
@@ -173,7 +226,6 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
173
  if not resultados:
174
  return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
175
 
176
- # Ordena pela diferença e pega as melhores
177
  resultados.sort(key=lambda x: x[2])
178
  return formatar_resultados(resultados[:max_combinacoes])
179
 
 
85
  if not grupos_filtrados:
86
  return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
87
 
88
+ # TOLERÂNCIAS - Ajustadas para valores altos
89
+ # Para valores altos, focamos em combinações de múltiplas cotas
90
+ if credito_desejado > 1000000: # Para valores acima de 1 milhão
91
+ tolerancia_credito = 0.10 # 10%
92
+ tolerancia_entrada = 0.10 # 10%
93
+ tolerancia_parcela = 0.30 # 30%
94
+ else:
95
+ tolerancia_credito = 0.10 # 10%
96
+ tolerancia_entrada = 0.10 # 10%
97
+ tolerancia_parcela = 0.30 # 30%
 
 
 
 
 
 
 
 
98
 
99
  # Define faixas de tolerância
100
  credito_min = credito_desejado * (1 - tolerancia_credito)
 
104
  parcela_min = parcela_desejada * (1 - tolerancia_parcela)
105
  parcela_max = parcela_desejada * (1 + tolerancia_parcela)
106
 
107
+ print(f"🔧 Buscando combinações para: Crédito: {credito_desejado:,.0f}, Entrada: {entrada_desejada:,.0f}, Parcela: {parcela_desejada:,.0f}")
108
+ print(f"🔧 Tolerâncias: Crédito: ±{tolerancia_credito*100:.1f}%, Entrada: ±{tolerancia_entrada*100:.1f}%, Parcela: ±{tolerancia_parcela*100:.1f}%")
109
 
110
  resultados = []
111
 
112
  # Para cada administradora, busca combinações
113
  for adm, cotas in grupos_filtrados.items():
114
+ # Para valores altos, NÃO filtramos cotas individuais primeiro
115
+ # Isso permite que cotas menores sejam combinadas para atingir valores altos
116
+ cotas_para_combinar = cotas
 
 
 
 
 
 
 
 
117
 
118
+ # Gera combinações (até 5 cotas por combinação para valores altos)
119
+ max_cotas_por_combinacao = 5 if credito_desejado > 1000000 else 3
 
120
 
121
+ for r in range(1, min(max_cotas_por_combinacao + 1, len(cotas_para_combinar) + 1)):
 
122
  # Limita o número de combinações testadas por administradora
123
+ max_combinacoes_por_adm = 100 if credito_desejado > 1000000 else 50
124
  combinacoes_geradas = 0
125
 
126
+ for combinacao in itertools.combinations(cotas_para_combinar, r):
127
  if combinacoes_geradas >= max_combinacoes_por_adm:
128
  break
129
 
 
132
  total_entrada = total_entrada_base + (total_credito * 0.085)
133
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
134
 
135
+ # Verifica se a combinação está dentro das tolerâncias
136
  if (credito_min <= total_credito <= credito_max and
137
  entrada_min <= total_entrada <= entrada_max and
138
  parcela_min <= total_parcelas <= parcela_max):
 
145
  combinacoes_geradas += 1
146
 
147
  # Para se já encontrou combinações suficientes
148
+ if len(resultados) >= max_combinacoes * 5: # Coleta mais para depois filtrar as melhores
149
+ break
150
+
151
+ if len(resultados) >= max_combinacoes * 5:
152
+ break
153
+
154
+ if len(resultados) >= max_combinacoes * 5:
155
+ break
156
+
157
+ if not resultados:
158
+ # Tenta uma busca mais ampla se não encontrou resultados
159
+ return buscar_combinacoes_amplo(credito_desejado, entrada_desejada, parcela_desejada, administradoras, max_combinacoes)
160
+
161
+ # Ordena pela diferença e pega as melhores
162
+ resultados.sort(key=lambda x: x[2])
163
+ return formatar_resultados(resultados[:max_combinacoes])
164
+
165
+ def buscar_combinacoes_amplo(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None, max_combinacoes=10):
166
+ """Busca combinações com tolerâncias mais amplas para valores altos."""
167
+ global grupos_imovel
168
+
169
+ # Filtra administradoras se especificado
170
+ if administradoras:
171
+ grupos_filtrados = {adm: cotas for adm, cotas in grupos_imovel.items() if adm in administradoras}
172
+ else:
173
+ grupos_filtrados = grupos_imovel
174
+
175
+ # Tolerâncias mais amplas para valores altos
176
+ tolerancia_credito = 0.20 # 20%
177
+ tolerancia_entrada = 0.20 # 20%
178
+ tolerancia_parcela = 0.50 # 50%
179
+
180
+ credito_min = credito_desejado * (1 - tolerancia_credito)
181
+ credito_max = credito_desejado * (1 + tolerancia_credito)
182
+ entrada_min = entrada_desejada * (1 - tolerancia_entrada)
183
+ entrada_max = entrada_desejada * (1 + tolerancia_entrada)
184
+ parcela_min = parcela_desejada * (1 - tolerancia_parcela)
185
+ parcela_max = parcela_desejada * (1 + tolerancia_parcela)
186
+
187
+ print(f"🔧 Busca ampla: Tolerâncias: Crédito: ±{tolerancia_credito*100:.1f}%, Entrada: ±{tolerancia_entrada*100:.1f}%, Parcela: ±{tolerancia_parcela*100:.1f}%")
188
+
189
+ resultados = []
190
+
191
+ for adm, cotas in grupos_filtrados.items():
192
+ # Gera combinações (até 6 cotas por combinação)
193
+ for r in range(1, min(7, len(cotas) + 1)):
194
+ combinacoes_geradas = 0
195
+ max_combinacoes_por_adm = 150
196
+
197
+ for combinacao in itertools.combinations(cotas, r):
198
+ if combinacoes_geradas >= max_combinacoes_por_adm:
199
+ break
200
+
201
+ total_credito = sum(c['valor_credito'] for c in combinacao)
202
+ total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
203
+ total_entrada = total_entrada_base + (total_credito * 0.085)
204
+ total_parcelas = sum(c['valor_parcela'] for c in combinacao)
205
+
206
+ if (credito_min <= total_credito <= credito_max and
207
+ entrada_min <= total_entrada <= entrada_max and
208
+ parcela_min <= total_parcelas <= parcela_max):
209
+
210
+ total_saldo = sum(c['saldo_devedor'] for c in combinacao)
211
+ valor_final = round(total_entrada + total_saldo, 2)
212
+ diferenca = abs(valor_final - total_credito)
213
+
214
+ resultados.append((adm, combinacao, diferenca))
215
+ combinacoes_geradas += 1
216
+
217
+ if len(resultados) >= max_combinacoes * 3:
218
  break
219
 
220
  if len(resultados) >= max_combinacoes * 3:
 
226
  if not resultados:
227
  return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
228
 
 
229
  resultados.sort(key=lambda x: x[2])
230
  return formatar_resultados(resultados[:max_combinacoes])
231