Arthur-Attili commited on
Commit
89658d8
·
verified ·
1 Parent(s): d8858c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -91
app.py CHANGED
@@ -85,16 +85,29 @@ 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 - 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,26 +117,36 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
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,7 +155,6 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
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,76 +167,7 @@ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_des
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,6 +179,7 @@ def buscar_combinacoes_amplo(credito_desejado, entrada_desejada, parcela_desejad
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
 
 
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
+ # Aumenta a tolerância para valores muito altos
93
+ fator = min(tolerancia_max, tolerancia_base * (1 + math.log10(valor / 1000000) * 0.2))
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
+ # Tolerâncias máximas
103
+ tolerancia_max_credito = 0.40 # 40%
104
+ tolerancia_max_entrada = 0.40 # 40%
105
+ tolerancia_max_parcela = 0.60 # 60%
106
+
107
+ # Calcula tolerâncias adaptativas
108
+ tolerancia_credito = calcular_tolerancia(credito_desejado, tolerancia_credito_base, tolerancia_credito_base, tolerancia_max_credito)
109
+ tolerancia_entrada = calcular_tolerancia(entrada_desejada, tolerancia_entrada_base, tolerancia_entrada_base, tolerancia_max_entrada)
110
+ tolerancia_parcela = calcular_tolerancia(parcela_desejada, tolerancia_parcela_base, tolerancia_parcela_base, tolerancia_max_parcela)
111
 
112
  # Define faixas de tolerância
113
  credito_min = credito_desejado * (1 - tolerancia_credito)
 
117
  parcela_min = parcela_desejada * (1 - tolerancia_parcela)
118
  parcela_max = parcela_desejada * (1 + tolerancia_parcela)
119
 
120
+ print(f"🔧 Tolerâncias aplicadas: Crédito: ±{tolerancia_credito*100:.1f}%, Entrada: ±{tolerancia_entrada*100:.1f}%, Parcela: ±{tolerancia_parcela*100:.1f}%")
121
+ print(f"🔧 Faixas: Crédito: {credito_min:,.0f} - {credito_max:,.0f}, Entrada: {entrada_min:,.0f} - {entrada_max:,.0f}, Parcela: {parcela_min:,.0f} - {parcela_max:,.0f}")
122
 
123
  resultados = []
124
 
125
  # Para cada administradora, busca combinações
126
  for adm, cotas in grupos_filtrados.items():
127
+ # Pré-filtra cotas que individualmente estão dentro das faixas de tolerância
128
+ cotas_filtradas = []
129
+ for cota in cotas:
130
+ cota_credito = cota['valor_credito']
131
+ cota_entrada = cota['valor_entrada'] + (cota_credito * 0.085)
132
+ cota_parcela = cota['valor_parcela']
133
+
134
+ if (credito_min <= cota_credito <= credito_max and
135
+ entrada_min <= cota_entrada <= entrada_max and
136
+ parcela_min <= cota_parcela <= parcela_max):
137
+ cotas_filtradas.append(cota)
138
 
139
+ # Se não cotas individuais dentro da tolerância, tenta combinações
140
+ if not cotas_filtradas:
141
+ cotas_filtradas = cotas # Usa todas as cotas para combinações
142
 
143
+ # Gera combinações (até 3 cotas por combinação para performance)
144
+ for r in range(1, min(4, len(cotas_filtradas) + 1)):
145
  # Limita o número de combinações testadas por administradora
146
+ max_combinacoes_por_adm = 50
147
  combinacoes_geradas = 0
148
 
149
+ for combinacao in itertools.combinations(cotas_filtradas, r):
150
  if combinacoes_geradas >= max_combinacoes_por_adm:
151
  break
152
 
 
155
  total_entrada = total_entrada_base + (total_credito * 0.085)
156
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
157
 
 
158
  if (credito_min <= total_credito <= credito_max and
159
  entrada_min <= total_entrada <= entrada_max and
160
  parcela_min <= total_parcelas <= parcela_max):
 
167
  combinacoes_geradas += 1
168
 
169
  # Para se já encontrou combinações suficientes
170
+ if len(resultados) >= max_combinacoes * 3: # Coleta mais para depois filtrar as melhores
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  break
172
 
173
  if len(resultados) >= max_combinacoes * 3:
 
179
  if not resultados:
180
  return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
181
 
182
+ # Ordena pela diferença e pega as melhores
183
  resultados.sort(key=lambda x: x[2])
184
  return formatar_resultados(resultados[:max_combinacoes])
185