DawnC commited on
Commit
4716fb2
1 Parent(s): c857afb

Update scoring_calculation_system.py

Browse files
Files changed (1) hide show
  1. scoring_calculation_system.py +244 -378
scoring_calculation_system.py CHANGED
@@ -1479,465 +1479,331 @@ def calculate_environmental_fit(breed_info: dict, user_prefs: UserPreferences) -
1479
 
1480
  # def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1481
  # """
1482
- # 改進的品種相容性評分系統
1483
- # 通過更細緻的特徵評估和動態權重調整,自然產生分數差異
 
 
 
 
1484
  # """
1485
- # # 評估關鍵特徵的匹配度,使用更極端的調整係數
1486
- # def evaluate_key_features():
1487
- # # 空間適配性評估
1488
- # space_multiplier = 1.0
1489
- # if user_prefs.living_space == 'apartment':
1490
- # if breed_info['Size'] == 'Giant':
1491
- # space_multiplier = 0.3 # 嚴重不適合
1492
- # elif breed_info['Size'] == 'Large':
1493
- # space_multiplier = 0.4 # 明顯不適合
1494
- # elif breed_info['Size'] == 'Small':
1495
- # space_multiplier = 1.4 # 明顯優勢
1496
 
1497
- # # 運動需求評估
1498
- # exercise_multiplier = 1.0
 
 
 
 
 
1499
  # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1500
- # if exercise_needs == 'VERY HIGH':
1501
- # if user_prefs.exercise_time < 60:
1502
- # exercise_multiplier = 0.3 # 嚴重不足
1503
- # elif user_prefs.exercise_time > 150:
1504
- # exercise_multiplier = 1.5 # 完美匹配
1505
  # elif exercise_needs == 'LOW' and user_prefs.exercise_time > 150:
1506
- # exercise_multiplier = 0.5 # 運動過度
1507
-
1508
- # return space_multiplier, exercise_multiplier
1509
-
1510
- # # 計算經驗匹配度
1511
- # def evaluate_experience():
1512
- # exp_multiplier = 1.0
1513
  # care_level = breed_info.get('Care Level', 'MODERATE')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1514
 
1515
- # if care_level == 'High':
1516
- # if user_prefs.experience_level == 'beginner':
1517
- # exp_multiplier = 0.4
1518
- # elif user_prefs.experience_level == 'advanced':
1519
- # exp_multiplier = 1.3
1520
- # elif care_level == 'Low':
1521
- # if user_prefs.experience_level == 'advanced':
1522
- # exp_multiplier = 0.9 # 略微降低評分,因為可能不夠有挑戰性
1523
-
1524
- # return exp_multiplier
1525
-
1526
- # # 取得特徵調整係數
1527
- # space_mult, exercise_mult = evaluate_key_features()
1528
- # exp_mult = evaluate_experience()
1529
-
1530
- # # 調整基礎分數
1531
- # adjusted_scores = {
1532
- # 'space': scores['space'] * space_mult,
1533
- # 'exercise': scores['exercise'] * exercise_mult,
1534
- # 'experience': scores['experience'] * exp_mult,
1535
- # 'grooming': scores['grooming'],
1536
- # 'health': scores['health'],
1537
- # 'noise': scores['noise']
1538
- # }
1539
-
1540
- # # 計算加權平均,關鍵特徵佔更大權重
1541
- # weights = {
1542
- # 'space': 0.35,
1543
- # 'exercise': 0.30,
1544
- # 'experience': 0.20,
1545
- # 'grooming': 0.15,
1546
- # 'health': 0.10,
1547
- # 'noise': 0.10
1548
- # }
1549
-
1550
- # # 動態調整權重
1551
- # if user_prefs.has_children:
1552
- # if user_prefs.children_age == 'toddler':
1553
- # weights['noise'] *= 1.5 # 幼童對噪音更敏感
1554
- # weights['experience'] *= 1.3 # 需要更有經驗的飼主
1555
-
1556
- # if user_prefs.living_space == 'apartment':
1557
- # weights['space'] *= 1.4 # 公寓空間限制更重要
1558
- # weights['noise'] *= 1.3 # 噪音問題更重要
1559
-
1560
- # # 運動時間極端情況
1561
- # if user_prefs.exercise_time < 30:
1562
- # weights['exercise'] *= 1.5 # 運動時間極少時加重權重
1563
- # elif user_prefs.exercise_time > 150:
1564
- # weights['exercise'] *= 1.3 # 運動時間充足時略微加重
1565
-
1566
- # # 正規化權重
1567
- # total_weight = sum(weights.values())
1568
- # normalized_weights = {k: v/total_weight for k, v in weights.items()}
1569
-
1570
- # # 計算最終分數
1571
- # final_score = sum(adjusted_scores[k] * normalized_weights[k] for k in scores.keys())
1572
-
1573
- # # 品種特性加成
1574
- # breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
1575
-
1576
- # # 整合最終分數,保持在0-1範圍內
1577
- # return min(1.0, max(0.0, (final_score * 0.85) + (breed_bonus * 0.15)))
1578
-
1579
-
1580
- # def amplify_score_extreme(score: float) -> float:
1581
- # """
1582
- # 改進的分數轉換函數,提供更大的分數區間和更明顯的差異
1583
-
1584
- # 轉換邏輯:
1585
- # - 極差匹配 (0.0-0.2) -> 50-60%
1586
- # - 較差匹配 (0.2-0.4) -> 60-70%
1587
- # - 中等匹配 (0.4-0.6) -> 70-82%
1588
- # - 良好匹配 (0.6-0.8) -> 82-90%
1589
- # - 優秀匹配 (0.8-1.0) -> 90-98%
1590
- # """
1591
- # if score < 0.2:
1592
- # # 極差匹配:更低的起始分數
1593
- # return 0.50 + (score / 0.2) * 0.10
1594
- # elif score < 0.4:
1595
- # # 較差匹配:緩慢增長
1596
- # position = (score - 0.2) / 0.2
1597
- # return 0.60 + position * 0.10
1598
- # elif score < 0.6:
1599
- # # 中等匹配:較大的分數增長
1600
- # position = (score - 0.4) / 0.2
1601
- # return 0.70 + position * 0.12
1602
- # elif score < 0.8:
1603
- # # 良好匹配:快速增長
1604
- # position = (score - 0.6) / 0.2
1605
- # return 0.82 + position * 0.08
1606
- # else:
1607
- # # 優秀匹配:達到更高分數
1608
- # position = (score - 0.8) / 0.2
1609
- # return 0.90 + position * 0.08
1610
-
1611
-
1612
- # def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1613
- # """改進的品種相容性評分系統"""
1614
-
1615
- # def evaluate_key_features():
1616
- # # 空間適配性評估 - 更極端的調整
1617
- # space_multiplier = 1.0
1618
  # if user_prefs.living_space == 'apartment':
1619
- # if breed_info['Size'] == 'Giant':
1620
- # space_multiplier = 0.2 # 更嚴重的懲罰
1621
- # elif breed_info['Size'] == 'Large':
1622
- # space_multiplier = 0.3
1623
- # elif breed_info['Size'] == 'Medium':
1624
- # space_multiplier = 0.7
1625
- # elif breed_info['Size'] == 'Small':
1626
- # space_multiplier = 1.6 # 更大的獎勵
1627
-
1628
- # # 運動需求評估 - 更細緻的匹配
1629
- # exercise_multiplier = 1.0
1630
- # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1631
 
1632
- # # 運動時間差異計算
1633
- # time_diff_ratio = abs(user_prefs.exercise_time - get_ideal_exercise_time(exercise_needs)) / 60.0
 
 
 
 
 
 
 
1634
 
1635
- # if exercise_needs == 'VERY HIGH':
1636
- # if user_prefs.exercise_time < 90:
1637
- # exercise_multiplier = max(0.2, 1.0 - time_diff_ratio)
1638
- # elif user_prefs.exercise_time > 150:
1639
- # exercise_multiplier = min(2.0, 1.0 + time_diff_ratio/2)
1640
- # elif exercise_needs == 'HIGH':
1641
- # if user_prefs.exercise_time < 60:
1642
- # exercise_multiplier = max(0.3, 1.0 - time_diff_ratio)
1643
- # elif user_prefs.exercise_time > 120:
1644
- # exercise_multiplier = min(1.8, 1.0 + time_diff_ratio/2)
1645
- # elif exercise_needs == 'LOW':
1646
- # if user_prefs.exercise_time > 120:
1647
- # exercise_multiplier = max(0.4, 1.0 - time_diff_ratio/2)
1648
-
1649
- # return space_multiplier, exercise_multiplier
1650
-
1651
- # def get_ideal_exercise_time(exercise_needs: str) -> int:
1652
- # """獲取理想運動時間"""
1653
- # return {
1654
- # 'VERY HIGH': 150,
1655
- # 'HIGH': 120,
1656
- # 'MODERATE HIGH': 90,
1657
- # 'MODERATE': 60,
1658
- # 'MODERATE LOW': 45,
1659
- # 'LOW': 30
1660
- # }.get(exercise_needs, 60)
1661
-
1662
- # # 經驗匹配度評估 - 更強的影響力
1663
- # def evaluate_experience():
1664
- # exp_multiplier = 1.0
1665
- # care_level = breed_info.get('Care Level', 'MODERATE')
1666
-
1667
- # if care_level == 'High':
1668
- # if user_prefs.experience_level == 'beginner':
1669
- # exp_multiplier = 0.3 # 更嚴重的懲罰
1670
- # elif user_prefs.experience_level == 'advanced':
1671
- # exp_multiplier = 1.5 # 更大的獎勵
1672
- # elif care_level == 'Low':
1673
- # if user_prefs.experience_level == 'advanced':
1674
- # exp_multiplier = 0.8
1675
-
1676
- # return exp_multiplier
1677
-
1678
- # # 計算調整係數
1679
- # space_mult, exercise_mult = evaluate_key_features()
1680
- # exp_mult = evaluate_experience()
1681
-
1682
- # # 調整基礎分數
1683
- # adjusted_scores = {
1684
- # 'space': scores['space'] * space_mult,
1685
- # 'exercise': scores['exercise'] * exercise_mult,
1686
- # 'experience': scores['experience'] * exp_mult,
1687
- # 'grooming': scores['grooming'],
1688
- # 'health': scores['health'] * (1.5 if user_prefs.health_sensitivity == 'high' else 1.0),
1689
- # 'noise': scores['noise']
1690
- # }
1691
-
1692
- # # 基礎權重
1693
- # weights = {
1694
- # 'space': 0.25,
1695
- # 'exercise': 0.25,
1696
- # 'experience': 0.15,
1697
- # 'grooming': 0.15,
1698
- # 'health': 0.10,
1699
- # 'noise': 0.10
1700
- # }
1701
-
1702
- # # 動態權重調整 - 更強的條件反應
1703
- # if user_prefs.has_children:
1704
- # if user_prefs.children_age == 'toddler':
1705
- # weights['noise'] *= 2.0 # 更強的噪音影響
1706
- # weights['experience'] *= 1.5
1707
- # weights['health'] *= 1.3
1708
- # elif user_prefs.children_age == 'school_age':
1709
- # weights['noise'] *= 1.5
1710
- # weights['experience'] *= 1.3
1711
-
1712
- # if user_prefs.living_space == 'apartment':
1713
- # weights['space'] *= 1.8 # 更強的空間限制
1714
- # weights['noise'] *= 1.6
1715
-
1716
- # # 運動時間極端情況
1717
- # if user_prefs.exercise_time < 30:
1718
- # weights['exercise'] *= 2.0
1719
- # elif user_prefs.exercise_time > 150:
1720
- # weights['exercise'] *= 1.5
1721
 
 
 
 
 
 
 
1722
  # # 正規化權重
1723
  # total_weight = sum(weights.values())
1724
  # normalized_weights = {k: v/total_weight for k, v in weights.items()}
1725
-
1726
- # # 計算基礎分數
1727
- # base_score = sum(adjusted_scores[k] * normalized_weights[k] for k in scores.keys())
 
 
 
 
 
1728
 
1729
  # # 品種特性加成
1730
  # breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
1731
 
1732
- # # 動態整合係數
1733
- # bonus_weight = min(0.25, max(0.15, breed_bonus)) # 讓優秀特性有更大影響
 
 
 
1734
 
1735
  # # 完美匹配加成
1736
- # if all(score >= 0.8 for score in adjusted_scores.values()):
1737
- # base_score *= 1.2
1738
 
1739
- # # 極端不匹配懲罰
1740
- # if any(score <= 0.3 for score in adjusted_scores.values()):
1741
- # base_score *= 0.6
1742
-
1743
- # return min(1.0, max(0.0, (base_score * (1.0 - bonus_weight)) + (breed_bonus * bonus_weight)))
 
 
1744
 
1745
 
1746
  # def amplify_score_extreme(score: float) -> float:
1747
  # """
1748
- # 改進的分數轉換函數,提供更動態的分數範圍
1749
 
1750
- # 動態轉換邏輯:
1751
- # - 極差匹配 (0.0-0.2) -> 45-58%
1752
- # - 較差匹配 (0.2-0.4) -> 58-72%
1753
- # - 中等匹配 (0.4-0.6) -> 72-85%
1754
- # - 良好匹配 (0.6-0.8) -> 85-92%
1755
- # - 優秀匹配 (0.8-0.9) -> 92-96%
1756
- # - 完美匹配 (0.9-1.0) -> 96-99%
1757
  # """
 
 
 
 
 
1758
  # if score < 0.2:
1759
- # return 0.45 + (score / 0.2) * 0.13
 
 
 
 
 
1760
  # elif score < 0.4:
 
 
 
1761
  # position = (score - 0.2) / 0.2
1762
- # return 0.58 + position * 0.14
 
1763
  # elif score < 0.6:
 
 
 
1764
  # position = (score - 0.4) / 0.2
1765
- # return 0.72 + position * 0.13
 
1766
  # elif score < 0.8:
 
 
 
1767
  # position = (score - 0.6) / 0.2
1768
- # return 0.85 + position * 0.07
 
1769
  # elif score < 0.9:
 
 
 
1770
  # position = (score - 0.8) / 0.1
1771
- # return 0.92 + position * 0.04
 
1772
  # else:
 
 
 
1773
  # position = (score - 0.9) / 0.1
1774
- # return 0.96 + position * 0.03
1775
 
1776
 
1777
  def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1778
  """
1779
- 改進的品種相容性評分系統,提供更動態和精確的評分
1780
-
1781
- 主要改進:
1782
- 1. 更動態的權重系統
1783
- 2. 更強的極端情況處理
1784
- 3. 更精確的品種特性評估
1785
  """
1786
- def evaluate_condition_extremity():
1787
- """評估使用者條件的極端程度"""
1788
- extremity_count = 0
 
 
 
 
 
1789
 
1790
- # 空間條件極端性
1791
- if user_prefs.living_space == 'apartment' and breed_info['Size'] in ['Large', 'Giant']:
1792
- extremity_count += 2
1793
- elif user_prefs.living_space == 'house_large' and breed_info['Size'] == 'Small':
1794
- extremity_count += 1
1795
 
1796
- # 運動需求極端性
1797
  exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1798
- if exercise_needs == 'VERY HIGH' and user_prefs.exercise_time < 60:
1799
- extremity_count += 2
1800
- elif exercise_needs == 'LOW' and user_prefs.exercise_time > 150:
1801
- extremity_count += 1
 
 
1802
 
1803
- # 經驗等級極端性
1804
  care_level = breed_info.get('Care Level', 'MODERATE')
1805
- if care_level == 'High' and user_prefs.experience_level == 'beginner':
1806
- extremity_count += 2
 
 
 
 
1807
 
1808
- return extremity_count
 
 
 
 
1809
 
1810
- def calculate_dynamic_weights():
1811
  """計算動態權重"""
1812
- # 基礎權重
1813
- weights = {
1814
  'space': 0.20,
1815
  'exercise': 0.20,
1816
- 'experience': 0.15,
1817
  'grooming': 0.15,
1818
  'health': 0.15,
1819
- 'noise': 0.15
1820
  }
1821
 
1822
- # 根據生活環境調整權重
1823
- if user_prefs.living_space == 'apartment':
1824
- weights['space'] *= 2.0
1825
- weights['noise'] *= 1.8
1826
-
1827
- # 根據家庭情況調整
1828
- if user_prefs.has_children:
1829
- if user_prefs.children_age == 'toddler':
1830
- weights['noise'] *= 2.0
1831
- weights['experience'] *= 1.8
1832
- weights['health'] *= 1.5
1833
- elif user_prefs.children_age == 'school_age':
1834
- weights['noise'] *= 1.5
1835
- weights['experience'] *= 1.3
1836
 
1837
- # 根據運動時間調整
1838
- if user_prefs.exercise_time < 30:
1839
- weights['exercise'] *= 2.5
1840
- elif user_prefs.exercise_time > 150:
1841
- weights['exercise'] *= 2.0
 
 
 
 
 
 
 
 
 
 
 
1842
 
1843
- # 根據健康敏感度調整
1844
- if user_prefs.health_sensitivity == 'high':
1845
- weights['health'] *= 1.8
1846
 
1847
- return weights
1848
 
1849
- # 計算條件極端程度
1850
- extremity_level = evaluate_condition_extremity()
1851
 
1852
  # 計算動態權重
1853
- weights = calculate_dynamic_weights()
1854
 
1855
  # 正規化權重
1856
  total_weight = sum(weights.values())
1857
  normalized_weights = {k: v/total_weight for k, v in weights.items()}
1858
 
1859
- # 計算加權分數
1860
- weighted_scores = {
1861
- k: scores[k] * normalized_weights[k] for k in scores.keys()
1862
- }
1863
-
1864
- # 基礎分數
1865
- base_score = sum(weighted_scores.values())
1866
-
 
 
 
 
 
 
1867
  # 品種特性加成
1868
- breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
1869
-
1870
- # 根據極端程度調整最終分數
1871
- if extremity_level >= 3:
1872
- base_score *= 0.6 # 多個極端條件的嚴重懲罰
1873
- elif extremity_level >= 2:
1874
- base_score *= 0.8 # 較少極端條件的適度懲罰
1875
-
1876
- # 完美匹配加成
1877
- if all(score >= 0.8 for score in scores.values()):
1878
- base_score *= 1.3
1879
 
1880
- # 品種特性影響力隨匹配度增加
1881
- bonus_weight = min(0.35, max(0.15, breed_bonus))
1882
 
1883
- # 最終分數計算
1884
- final_score = (base_score * (1.0 - bonus_weight)) + (breed_bonus * bonus_weight)
1885
 
1886
- return min(1.0, max(0.0, final_score))
1887
-
1888
 
1889
  def amplify_score_extreme(score: float) -> float:
1890
  """
1891
- 改進的分數轉換函數,提供更合理的分數分布
1892
-
1893
- 特點:
1894
- 1. 更大的分數範圍
1895
- 2. 更平滑的轉換曲線
1896
- 3. 更準確的極端情況處理
 
1897
  """
1898
- def sigmoid_transform(x: float, steepness: float = 10) -> float:
1899
- """使用 sigmoid 函數實現更平滑的轉換"""
1900
  import math
1901
  return 1 / (1 + math.exp(-steepness * (x - 0.5)))
1902
 
1903
- if score < 0.2:
1904
- # 極差匹配:使用更低的起始分數
1905
- base = 0.40
1906
- range_score = 0.15
1907
- position = score / 0.2
1908
- return base + (sigmoid_transform(position) * range_score)
1909
 
1910
- elif score < 0.4:
1911
- # 較差匹配:緩慢增長
1912
- base = 0.55
1913
- range_score = 0.15
1914
- position = (score - 0.2) / 0.2
1915
- return base + (sigmoid_transform(position) * range_score)
1916
 
1917
- elif score < 0.6:
1918
- # 中等匹��:較大增長
1919
- base = 0.70
1920
- range_score = 0.15
1921
- position = (score - 0.4) / 0.2
1922
- return base + (sigmoid_transform(position) * range_score)
1923
 
1924
- elif score < 0.8:
1925
- # 良好匹配:快速增長
1926
- base = 0.85
1927
- range_score = 0.10
1928
- position = (score - 0.6) / 0.2
1929
- return base + (sigmoid_transform(position) * range_score)
1930
 
1931
- elif score < 0.9:
1932
- # 優秀匹配:接近最高分
1933
- base = 0.95
1934
- range_score = 0.03
1935
- position = (score - 0.8) / 0.1
1936
- return base + (sigmoid_transform(position) * range_score)
1937
 
1938
  else:
1939
- # 完美匹配:可能達到最高分
1940
- base = 0.98
1941
- range_score = 0.02
1942
- position = (score - 0.9) / 0.1
1943
- return base + (sigmoid_transform(position) * range_score)
 
1479
 
1480
  # def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1481
  # """
1482
+ # 改進的品種相容性評分系統,提供更動態和精確的評分
1483
+
1484
+ # 主要改進:
1485
+ # 1. 更動態的權重系統
1486
+ # 2. 更強的極端情況處理
1487
+ # 3. 更精確的品種特性評估
1488
  # """
1489
+ # def evaluate_condition_extremity():
1490
+ # """評估使用者條件的極端程度"""
1491
+ # extremity_count = 0
 
 
 
 
 
 
 
 
1492
 
1493
+ # # 空間條件極端性
1494
+ # if user_prefs.living_space == 'apartment' and breed_info['Size'] in ['Large', 'Giant']:
1495
+ # extremity_count += 2
1496
+ # elif user_prefs.living_space == 'house_large' and breed_info['Size'] == 'Small':
1497
+ # extremity_count += 1
1498
+
1499
+ # # 運動需求極端性
1500
  # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1501
+ # if exercise_needs == 'VERY HIGH' and user_prefs.exercise_time < 60:
1502
+ # extremity_count += 2
 
 
 
1503
  # elif exercise_needs == 'LOW' and user_prefs.exercise_time > 150:
1504
+ # extremity_count += 1
1505
+
1506
+ # # 經驗等級極端性
 
 
 
 
1507
  # care_level = breed_info.get('Care Level', 'MODERATE')
1508
+ # if care_level == 'High' and user_prefs.experience_level == 'beginner':
1509
+ # extremity_count += 2
1510
+
1511
+ # return extremity_count
1512
+
1513
+ # def calculate_dynamic_weights():
1514
+ # """計算動態權重"""
1515
+ # # 基礎權重
1516
+ # weights = {
1517
+ # 'space': 0.20,
1518
+ # 'exercise': 0.20,
1519
+ # 'experience': 0.15,
1520
+ # 'grooming': 0.15,
1521
+ # 'health': 0.15,
1522
+ # 'noise': 0.15
1523
+ # }
1524
 
1525
+ # # 根據生活環境調整權重
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1526
  # if user_prefs.living_space == 'apartment':
1527
+ # weights['space'] *= 2.0
1528
+ # weights['noise'] *= 1.8
 
 
 
 
 
 
 
 
 
 
1529
 
1530
+ # # 根據家庭情況調整
1531
+ # if user_prefs.has_children:
1532
+ # if user_prefs.children_age == 'toddler':
1533
+ # weights['noise'] *= 2.0
1534
+ # weights['experience'] *= 1.8
1535
+ # weights['health'] *= 1.5
1536
+ # elif user_prefs.children_age == 'school_age':
1537
+ # weights['noise'] *= 1.5
1538
+ # weights['experience'] *= 1.3
1539
 
1540
+ # # 根據運動時間調整
1541
+ # if user_prefs.exercise_time < 30:
1542
+ # weights['exercise'] *= 2.5
1543
+ # elif user_prefs.exercise_time > 150:
1544
+ # weights['exercise'] *= 2.0
1545
+
1546
+ # # 根據健康敏感度調整
1547
+ # if user_prefs.health_sensitivity == 'high':
1548
+ # weights['health'] *= 1.8
1549
+
1550
+ # return weights
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1551
 
1552
+ # # 計算條件極端程度
1553
+ # extremity_level = evaluate_condition_extremity()
1554
+
1555
+ # # 計算動態權重
1556
+ # weights = calculate_dynamic_weights()
1557
+
1558
  # # 正規化權重
1559
  # total_weight = sum(weights.values())
1560
  # normalized_weights = {k: v/total_weight for k, v in weights.items()}
1561
+
1562
+ # # 計算加權分數
1563
+ # weighted_scores = {
1564
+ # k: scores[k] * normalized_weights[k] for k in scores.keys()
1565
+ # }
1566
+
1567
+ # # 基礎分數
1568
+ # base_score = sum(weighted_scores.values())
1569
 
1570
  # # 品種特性加成
1571
  # breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
1572
 
1573
+ # # 根據極端程度調整最終分數
1574
+ # if extremity_level >= 3:
1575
+ # base_score *= 0.6 # 多個極端條件的嚴重懲罰
1576
+ # elif extremity_level >= 2:
1577
+ # base_score *= 0.8 # 較少極端條件的適度懲罰
1578
 
1579
  # # 完美匹配加成
1580
+ # if all(score >= 0.8 for score in scores.values()):
1581
+ # base_score *= 1.3
1582
 
1583
+ # # 品種特性影響力隨匹配度增加
1584
+ # bonus_weight = min(0.35, max(0.15, breed_bonus))
1585
+
1586
+ # # 最終分數計算
1587
+ # final_score = (base_score * (1.0 - bonus_weight)) + (breed_bonus * bonus_weight)
1588
+
1589
+ # return min(1.0, max(0.0, final_score))
1590
 
1591
 
1592
  # def amplify_score_extreme(score: float) -> float:
1593
  # """
1594
+ # 改進的分數轉換函數,提供更合理的分數分布
1595
 
1596
+ # 特點:
1597
+ # 1. 更大的分數範圍
1598
+ # 2. 更平滑的轉換曲線
1599
+ # 3. 更準確的極端情況處理
 
 
 
1600
  # """
1601
+ # def sigmoid_transform(x: float, steepness: float = 10) -> float:
1602
+ # """使用 sigmoid 函數實現更平滑的轉換"""
1603
+ # import math
1604
+ # return 1 / (1 + math.exp(-steepness * (x - 0.5)))
1605
+
1606
  # if score < 0.2:
1607
+ # # 極差匹配:使用更低的起始分數
1608
+ # base = 0.40
1609
+ # range_score = 0.15
1610
+ # position = score / 0.2
1611
+ # return base + (sigmoid_transform(position) * range_score)
1612
+
1613
  # elif score < 0.4:
1614
+ # # 較差匹配:緩慢增長
1615
+ # base = 0.55
1616
+ # range_score = 0.15
1617
  # position = (score - 0.2) / 0.2
1618
+ # return base + (sigmoid_transform(position) * range_score)
1619
+
1620
  # elif score < 0.6:
1621
+ # # 中等匹配:較大增長
1622
+ # base = 0.70
1623
+ # range_score = 0.15
1624
  # position = (score - 0.4) / 0.2
1625
+ # return base + (sigmoid_transform(position) * range_score)
1626
+
1627
  # elif score < 0.8:
1628
+ # # 良好匹配:快速增長
1629
+ # base = 0.85
1630
+ # range_score = 0.10
1631
  # position = (score - 0.6) / 0.2
1632
+ # return base + (sigmoid_transform(position) * range_score)
1633
+
1634
  # elif score < 0.9:
1635
+ # # 優秀匹配:接近最高分
1636
+ # base = 0.95
1637
+ # range_score = 0.03
1638
  # position = (score - 0.8) / 0.1
1639
+ # return base + (sigmoid_transform(position) * range_score)
1640
+
1641
  # else:
1642
+ # # 完美匹配:可能達到最高分
1643
+ # base = 0.98
1644
+ # range_score = 0.02
1645
  # position = (score - 0.9) / 0.1
1646
+ # return base + (sigmoid_transform(position) * range_score)
1647
 
1648
 
1649
  def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1650
  """
1651
+ 重構的品種相容性評分系統
1652
+ 目標:實現更大的分數差異和更高的頂部分數
 
 
 
 
1653
  """
1654
+ def evaluate_perfect_conditions():
1655
+ """評估完美條件匹配度"""
1656
+ perfect_matches = {
1657
+ 'size_match': False,
1658
+ 'exercise_match': False,
1659
+ 'experience_match': False,
1660
+ 'general_match': False
1661
+ }
1662
 
1663
+ # 體型與空間匹配
1664
+ if user_prefs.living_space == 'apartment':
1665
+ perfect_matches['size_match'] = breed_info['Size'] == 'Small'
1666
+ elif user_prefs.living_space == 'house_large':
1667
+ perfect_matches['size_match'] = breed_info['Size'] in ['Medium', 'Large']
1668
 
1669
+ # 運動需求匹配
1670
  exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1671
+ if exercise_needs == 'VERY HIGH' and user_prefs.exercise_time >= 150:
1672
+ perfect_matches['exercise_match'] = True
1673
+ elif exercise_needs == 'LOW' and 30 <= user_prefs.exercise_time <= 90:
1674
+ perfect_matches['exercise_match'] = True
1675
+ elif 60 <= user_prefs.exercise_time <= 120:
1676
+ perfect_matches['exercise_match'] = True
1677
 
1678
+ # 經驗匹配
1679
  care_level = breed_info.get('Care Level', 'MODERATE')
1680
+ if care_level == 'High' and user_prefs.experience_level == 'advanced':
1681
+ perfect_matches['experience_match'] = True
1682
+ elif care_level == 'Low' and user_prefs.experience_level == 'beginner':
1683
+ perfect_matches['experience_match'] = True
1684
+ elif user_prefs.experience_level == 'intermediate':
1685
+ perfect_matches['experience_match'] = True
1686
 
1687
+ # 一般條件匹配
1688
+ if all(score >= 0.85 for score in scores.values()):
1689
+ perfect_matches['general_match'] = True
1690
+
1691
+ return perfect_matches
1692
 
1693
+ def calculate_weights():
1694
  """計算動態權重"""
1695
+ base_weights = {
 
1696
  'space': 0.20,
1697
  'exercise': 0.20,
1698
+ 'experience': 0.20,
1699
  'grooming': 0.15,
1700
  'health': 0.15,
1701
+ 'noise': 0.10
1702
  }
1703
 
1704
+ # 極端條件權重調整
1705
+ multipliers = {}
 
 
 
 
 
 
 
 
 
 
 
 
1706
 
1707
+ # 經驗權重調整
1708
+ if user_prefs.experience_level == 'beginner':
1709
+ multipliers['experience'] = 3.0 # 新手經驗極其重要
1710
+ elif user_prefs.experience_level == 'advanced':
1711
+ multipliers['experience'] = 2.5 # 專家經驗很重要
1712
+
1713
+ # 運動需求權重調整
1714
+ if user_prefs.exercise_time > 150:
1715
+ multipliers['exercise'] = 3.0
1716
+ elif user_prefs.exercise_time < 30:
1717
+ multipliers['exercise'] = 3.5
1718
+
1719
+ # 空間限制權重調整
1720
+ if user_prefs.living_space == 'apartment':
1721
+ multipliers['space'] = 2.5
1722
+ multipliers['noise'] = 2.0
1723
 
1724
+ # 應用乘數
1725
+ for key, multiplier in multipliers.items():
1726
+ base_weights[key] *= multiplier
1727
 
1728
+ return base_weights
1729
 
1730
+ # 評估完美匹配條件
1731
+ perfect_conditions = evaluate_perfect_conditions()
1732
 
1733
  # 計算動態權重
1734
+ weights = calculate_weights()
1735
 
1736
  # 正規化權重
1737
  total_weight = sum(weights.values())
1738
  normalized_weights = {k: v/total_weight for k, v in weights.items()}
1739
 
1740
+ # 計算基礎分數
1741
+ base_score = sum(scores[k] * normalized_weights[k] for k in scores.keys())
1742
+
1743
+ # 完美匹配獎勵
1744
+ perfect_bonus = 1.0
1745
+ if perfect_conditions['size_match']:
1746
+ perfect_bonus += 0.2
1747
+ if perfect_conditions['exercise_match']:
1748
+ perfect_bonus += 0.2
1749
+ if perfect_conditions['experience_match']:
1750
+ perfect_bonus += 0.2
1751
+ if perfect_conditions['general_match']:
1752
+ perfect_bonus += 0.2
1753
+
1754
  # 品種特性加成
1755
+ breed_bonus = calculate_breed_bonus(breed_info, user_prefs) * 1.5 # 增加品種特性影響
 
 
 
 
 
 
 
 
 
 
1756
 
1757
+ # 計算最終分數
1758
+ final_score = (base_score * 0.7 + breed_bonus * 0.3) * perfect_bonus
1759
 
1760
+ return min(1.0, final_score)
 
1761
 
 
 
1762
 
1763
  def amplify_score_extreme(score: float) -> float:
1764
  """
1765
+ 改進的分數轉換函數:實現更高的頂部分數
1766
+ - 完美匹配可達到95-99%
1767
+ - 優秀匹配在90-95%
1768
+ - 良好匹配在85-90%
1769
+ - 一般匹配在75-85%
1770
+ - 較差匹配在65-75%
1771
+ - 極差匹配在50-65%
1772
  """
1773
+ def smooth_curve(x: float, steepness: float = 12) -> float:
1774
+ """使用sigmoid curve"""
1775
  import math
1776
  return 1 / (1 + math.exp(-steepness * (x - 0.5)))
1777
 
1778
+ if score >= 0.9:
1779
+ # 完美匹配:95-99%
1780
+ position = (score - 0.9) / 0.1
1781
+ return 0.95 + (position * 0.04)
 
 
1782
 
1783
+ elif score >= 0.8:
1784
+ # 優秀匹配:90-95%
1785
+ position = (score - 0.8) / 0.1
1786
+ return 0.90 + (position * 0.05)
 
 
1787
 
1788
+ elif score >= 0.7:
1789
+ # 良好匹配:85-90%
1790
+ position = (score - 0.7) / 0.1
1791
+ return 0.85 + (position * 0.05)
 
 
1792
 
1793
+ elif score >= 0.5:
1794
+ # 一般匹配:75-85%
1795
+ position = (score - 0.5) / 0.2
1796
+ base = 0.75
1797
+ return base + (smooth_curve(position) * 0.10)
 
1798
 
1799
+ elif score >= 0.3:
1800
+ # 較差匹配:65-75%
1801
+ position = (score - 0.3) / 0.2
1802
+ base = 0.65
1803
+ return base + (smooth_curve(position) * 0.10)
 
1804
 
1805
  else:
1806
+ # 極差匹配:50-65%
1807
+ position = score / 0.3
1808
+ base = 0.50
1809
+ return base + (smooth_curve(position) * 0.15)