DmitrMakeev commited on
Commit
6eabd78
·
verified ·
1 Parent(s): 8043ac4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -39
app.py CHANGED
@@ -702,58 +702,79 @@ class NutrientCalculator:
702
  self.results = {}
703
  self.actual_profile = {k: 0.0 for k in self.target_profile}
704
  self.total_ec = 0.0
705
- self.tolerance = 0.5 # Допустимое отклонение в ppm
706
-
707
- def _init_nitrogen(self):
708
- total_parts = NO3_RATIO + NH4_RATIO
709
- self.target_profile['N (NO3-)'] = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
710
- self.target_profile['N (NH4+)'] = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
711
 
712
  def calculate(self):
713
- # Основные элементы в порядке приоритета
714
- elements_order = ['Ca', 'N (NH4+)', 'P', 'Mg', 'N (NO3-)', 'K', 'S']
715
-
716
- for element in elements_order:
717
- self._balance_element(element)
 
 
 
 
 
 
 
 
 
 
 
 
718
 
719
  # Финальная тонкая настройка
720
- self._fine_tuning()
721
 
722
  return self._prepare_results()
723
 
724
- def _balance_element(self, element):
725
  deficit = self.target_profile[element] - self.actual_profile[element]
726
  if deficit <= self.tolerance:
727
  return
728
 
729
- # Выбираем лучшее удобрение для элемента
730
- best_fert = self._find_best_fertilizer(element)
731
- if not best_fert:
732
- return
733
-
734
- # Рассчитываем необходимое количество
735
- content = self.fertilizers[best_fert][element]
736
- grams = (deficit * self.volume) / (content * 1000)
737
-
738
- # Вносим с учетом других элементов в удобрении
739
- self._apply_fertilizer(best_fert, grams)
740
-
741
- def _find_best_fertilizer(self, element):
742
- candidates = []
743
- for fert, contents in self.fertilizers.items():
744
- if element in contents:
745
- # Оцениваем "побочные" элементы
746
- side_effects = sum(
747
- max(0, self.target_profile[e] - self.actual_profile[e])
748
- for e in contents if e != element
749
  )
750
- candidates.append((fert, side_effects))
751
-
752
- if not candidates:
753
- return None
 
 
 
 
 
 
 
 
 
 
754
 
755
- # Выбираем удобрение с минимальными побочными эффектами
756
- return min(candidates, key=lambda x: x[1])[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
757
 
758
  def _apply_fertilizer(self, fert_name, grams):
759
  if fert_name not in self.results:
 
702
  self.results = {}
703
  self.actual_profile = {k: 0.0 for k in self.target_profile}
704
  self.total_ec = 0.0
705
+ self.tolerance = 1.0 # Допустимое отклонение в ppm
706
+ self.max_iterations = 100 # Максимальное число итераций
 
 
 
 
707
 
708
  def calculate(self):
709
+ # Оптимизированный порядок внесения элементов
710
+ priority_order = [
711
+ ('Ca', ['Кальциевая селитра', 'Сульфат кальция']),
712
+ ('N (NH4+)', ['Аммоний азотнокислый']),
713
+ ('P', ['Монофосфат калия']),
714
+ ('Mg', ['Сульфат магния']),
715
+ ('N (NO3-)', ['Калий азотнокислый', 'Кальциевая селитра']),
716
+ ('K', ['Калий азотнокислый', 'Калий сернокислый']),
717
+ ('S', ['Калий сернокислый', 'Сульфат магния'])
718
+ ]
719
+
720
+ for _ in range(self.max_iterations):
721
+ for element, fert_options in priority_order:
722
+ self._balance_element(element, fert_options)
723
+
724
+ if self._is_balanced():
725
+ break
726
 
727
  # Финальная тонкая настройка
728
+ self._fine_tune()
729
 
730
  return self._prepare_results()
731
 
732
+ def _balance_element(self, element, fert_options):
733
  deficit = self.target_profile[element] - self.actual_profile[element]
734
  if deficit <= self.tolerance:
735
  return
736
 
737
+ for fert_name in fert_options:
738
+ content = self.fertilizers[fert_name].get(element, 0)
739
+ if content == 0:
740
+ continue
741
+
742
+ # Рассчитываем возможное количество без перебора других элементов
743
+ max_possible = min(
744
+ deficit / content,
745
+ *[(self.target_profile[e] - self.actual_profile[e]) / self.fertilizers[fert_name].get(e, 1)
746
+ for e in self.fertilizers[fert_name] if e != element]
 
 
 
 
 
 
 
 
 
 
747
  )
748
+
749
+ if max_possible > 0:
750
+ grams = (max_possible * 1000) / self.volume
751
+ self._apply_fertilizer(fert_name, grams)
752
+ break
753
+
754
+ def _fine_tune(self):
755
+ # Тонкая подстройка малыми шагами (0.1 грамма)
756
+ for _ in range(20):
757
+ worst_element = max(
758
+ self.target_profile.keys(),
759
+ key=lambda x: abs(self.target_profile[x] - self.actual_profile[x])
760
+ )
761
+ deficit = self.target_profile[worst_element] - self.actual_profile[worst_element]
762
 
763
+ if abs(deficit) <= self.tolerance:
764
+ break
765
+
766
+ # Ищем удобрение, содержащее этот элемент
767
+ for fert_name, contents in self.fertilizers.items():
768
+ if worst_element in contents:
769
+ small_step = 0.1 # грамм
770
+ self._apply_fertilizer(fert_name, small_step)
771
+ break
772
+
773
+ def _is_balanced(self):
774
+ return all(
775
+ abs(self.target_profile[e] - self.actual_profile[e]) <= self.tolerance
776
+ for e in self.target_profile
777
+ )
778
 
779
  def _apply_fertilizer(self, fert_name, grams):
780
  if fert_name not in self.results: