DmitrMakeev commited on
Commit
add695f
·
verified ·
1 Parent(s): f5fb09b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -19
app.py CHANGED
@@ -803,7 +803,7 @@ class NutrientCalculator:
803
  self.total_ec = 0.0
804
  self.best_solution = None
805
  self.min_difference = float('inf')
806
- self.max_recursion_depth = 1000
807
  self.current_depth = 0
808
 
809
  # Расчёт азота
@@ -822,10 +822,13 @@ class NutrientCalculator:
822
 
823
  if self._backtrack_search():
824
  print("Оптимальная комбинация найдена!")
825
- return self.best_solution
826
  else:
827
  print("Идеальное решение не найдено. Возвращаю лучшее найденное решение.")
828
- return self.best_solution or {"error": "Не удалось найти подходящую комбинацию"}
 
 
 
 
829
 
830
  except Exception as e:
831
  print(f"Ошибка при расчёте: {str(e)}")
@@ -840,10 +843,6 @@ class NutrientCalculator:
840
  current_composition = Composition('Current Profile', list(self.actual_profile.values()))
841
  current_diff = self._calculate_difference(current_composition)
842
 
843
- print(f"\nТекущая разница: {current_diff:.2f}")
844
- print("Текущий профиль:")
845
- print(current_composition)
846
-
847
  if current_diff < self.min_difference:
848
  self.min_difference = current_diff
849
  self.best_solution = {
@@ -861,15 +860,10 @@ class NutrientCalculator:
861
  fert_name = list(self.fertilizers.keys())[i]
862
  fert_composition = self.fertilizers[fert_name]
863
 
864
- print(f"\nПроверяю удобрение: {fert_name}")
865
-
866
  # Проверяем, можно ли применить удобрение
867
  if not self._can_apply_fertilizer(fert_composition):
868
- print(f"Удобрение {fert_name} не подходит (превышает целевые значения).")
869
  continue
870
 
871
- print(f"Добавляю удобрение: {fert_name}, количество: {step:.2f} г")
872
-
873
  # Пробуем добавить удобрение с текущим шагом
874
  self._apply_fertilizer(fert_name, step)
875
 
@@ -878,12 +872,10 @@ class NutrientCalculator:
878
  return True
879
 
880
  # Если не получилось - откатываемся
881
- print(f"Откатываю удобрение: {fert_name}, количество: {step:.2f} г")
882
  self._remove_fertilizer(fert_name, step)
883
 
884
- # Пробуем уменьшить шаг для более точного поиска
885
- if step > 0.1 and current_diff > 5.0:
886
- print(f"Уменьшаю шаг до {step / 2:.2f} г")
887
  if self._backtrack_search(i, step / 2):
888
  return True
889
 
@@ -893,7 +885,7 @@ class NutrientCalculator:
893
  """Проверяет, можно ли применить удобрение без перебора"""
894
  for element, content in zip(nutrients_stencil, fert_composition.vector):
895
  added_ppm = (1 * content * 1000) / self.volume
896
- if self.actual_profile[element] + added_ppm > self.target_profile[element] + 0.5: # Уменьшаем допустимую погрешность
897
  return False
898
  return True
899
 
@@ -933,9 +925,30 @@ class NutrientCalculator:
933
  del self.results[fert_name]
934
 
935
  def _calculate_difference(self, current_composition):
936
- """Вычисляет общее отклонение от целевого профиля"""
937
  diff_vector = self.target_composition.vector - current_composition.vector
938
- return np.sum(np.abs(diff_vector))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
939
 
940
  def generate_report(self):
941
  """Генерация отчета о питательном растворе"""
 
803
  self.total_ec = 0.0
804
  self.best_solution = None
805
  self.min_difference = float('inf')
806
+ self.max_recursion_depth = 5000
807
  self.current_depth = 0
808
 
809
  # Расчёт азота
 
822
 
823
  if self._backtrack_search():
824
  print("Оптимальная комбинация найдена!")
 
825
  else:
826
  print("Идеальное решение не найдено. Возвращаю лучшее найденное решение.")
827
+
828
+ # Попытка точного добора
829
+ self._post_optimize()
830
+
831
+ return self.best_solution or {"error": "Не удалось найти подходящую комбинацию"}
832
 
833
  except Exception as e:
834
  print(f"Ошибка при расчёте: {str(e)}")
 
843
  current_composition = Composition('Current Profile', list(self.actual_profile.values()))
844
  current_diff = self._calculate_difference(current_composition)
845
 
 
 
 
 
846
  if current_diff < self.min_difference:
847
  self.min_difference = current_diff
848
  self.best_solution = {
 
860
  fert_name = list(self.fertilizers.keys())[i]
861
  fert_composition = self.fertilizers[fert_name]
862
 
 
 
863
  # Проверяем, можно ли применить удобрение
864
  if not self._can_apply_fertilizer(fert_composition):
 
865
  continue
866
 
 
 
867
  # Пробуем добавить удобрение с текущим шагом
868
  self._apply_fertilizer(fert_name, step)
869
 
 
872
  return True
873
 
874
  # Если не получилось - откатываемся
 
875
  self._remove_fertilizer(fert_name, step)
876
 
877
+ # Уменьшаем шаг для более точного поиска
878
+ if step > 0.1:
 
879
  if self._backtrack_search(i, step / 2):
880
  return True
881
 
 
885
  """Проверяет, можно ли применить удобрение без перебора"""
886
  for element, content in zip(nutrients_stencil, fert_composition.vector):
887
  added_ppm = (1 * content * 1000) / self.volume
888
+ if self.actual_profile[element] + added_ppm > self.target_profile[element] * 1.03: # Разрешаем перерасход на 3%
889
  return False
890
  return True
891
 
 
925
  del self.results[fert_name]
926
 
927
  def _calculate_difference(self, current_composition):
928
+ """Вычисляет общее отклонение от целевого профиля с учетом весов"""
929
  diff_vector = self.target_composition.vector - current_composition.vector
930
+ weights = np.array([1.5 if el in ['K', 'S', 'Mg'] else 1.0 for el in nutrients_stencil])
931
+ return np.sum(np.abs(diff_vector) * weights)
932
+
933
+ def _copy_results(self):
934
+ """Создаёт глубокую копию результатов"""
935
+ return {
936
+ fert_name: {
937
+ 'граммы': data['граммы'],
938
+ 'миллиграммы': data['миллиграммы'],
939
+ 'вклад в EC': data['вклад в EC']
940
+ }
941
+ for fert_name, data in self.results.items()
942
+ }
943
+
944
+ def _post_optimize(self):
945
+ """Попытка точного добора после основного подбора"""
946
+ for fert_name, fert in self.fertilizers.items():
947
+ for i, nutrient in enumerate(nutrients_stencil):
948
+ deficit = self.target_profile[nutrient] - self.actual_profile[nutrient]
949
+ if deficit > 2.0 and fert.vector[i] > 0: # Если дефицит больше 2 ppm
950
+ small_amount = deficit * self.volume / (fert.vector[i] * 1000)
951
+ self._apply_fertilizer(fert_name, min(small_amount, 2.0)) # Не больше 2 г
952
 
953
  def generate_report(self):
954
  """Генерация отчета о питательном растворе"""