DawnC commited on
Commit
82609ed
1 Parent(s): 5ae32ee

Update scoring_calculation_system.py

Browse files
Files changed (1) hide show
  1. scoring_calculation_system.py +168 -399
scoring_calculation_system.py CHANGED
@@ -1292,330 +1292,7 @@ def calculate_environmental_fit(breed_info: dict, user_prefs: UserPreferences) -
1292
  adaptability_score += 0.05
1293
 
1294
  return min(0.2, adaptability_score)
1295
-
1296
-
1297
- # def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1298
- # """
1299
- # 1. 運動類型與時間的精確匹配
1300
- # 2. 進階使用者的專業需求
1301
- # 3. 空間利用的實際效果
1302
- # 4. 條件組合的嚴格評估
1303
- # """
1304
- # def evaluate_perfect_conditions():
1305
- # """評估條件匹配度,特別強化運動類型與專業程度的評估"""
1306
- # perfect_matches = {
1307
- # 'size_match': 0,
1308
- # 'exercise_match': 0,
1309
- # 'experience_match': 0,
1310
- # 'living_condition_match': 0
1311
- # }
1312
-
1313
- # # 運動類型與需求的精確匹配
1314
- # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1315
- # exercise_time = user_prefs.exercise_time
1316
- # exercise_type = user_prefs.exercise_type
1317
-
1318
- # # 定義品種的理想運動模式
1319
- # breed_exercise_preferences = {
1320
- # 'VERY HIGH': {
1321
- # 'ideal_type': 'active_training',
1322
- # 'acceptable_types': ['moderate_activity'],
1323
- # 'time_ranges': {
1324
- # 'ideal': (120, 180),
1325
- # 'acceptable': (90, 200)
1326
- # }
1327
- # },
1328
- # 'HIGH': {
1329
- # 'ideal_type': 'moderate_activity',
1330
- # 'acceptable_types': ['active_training', 'light_walks'],
1331
- # 'time_ranges': {
1332
- # 'ideal': (90, 150),
1333
- # 'acceptable': (60, 180)
1334
- # }
1335
- # },
1336
- # 'MODERATE': {
1337
- # 'ideal_type': 'moderate_activity',
1338
- # 'acceptable_types': ['light_walks', 'active_training'],
1339
- # 'time_ranges': {
1340
- # 'ideal': (45, 90),
1341
- # 'acceptable': (30, 120)
1342
- # }
1343
- # },
1344
- # 'LOW': {
1345
- # 'ideal_type': 'light_walks',
1346
- # 'acceptable_types': ['moderate_activity'],
1347
- # 'time_ranges': {
1348
- # 'ideal': (30, 60),
1349
- # 'acceptable': (15, 90)
1350
- # }
1351
- # }
1352
- # }
1353
-
1354
- # # 計算運動匹配度
1355
- # exercise_profile = breed_exercise_preferences.get(exercise_needs,
1356
- # breed_exercise_preferences['MODERATE'])
1357
-
1358
- # # 時間匹配度計算
1359
- # time_ranges = exercise_profile['time_ranges']
1360
- # if time_ranges['ideal'][0] <= exercise_time <= time_ranges['ideal'][1]:
1361
- # time_score = 1.0
1362
- # elif time_ranges['acceptable'][0] <= exercise_time <= time_ranges['acceptable'][1]:
1363
- # # 計算與理想範圍的距離
1364
- # if exercise_time < time_ranges['ideal'][0]:
1365
- # deviation = (time_ranges['ideal'][0] - exercise_time) / time_ranges['ideal'][0]
1366
- # else:
1367
- # deviation = (exercise_time - time_ranges['ideal'][1]) / time_ranges['ideal'][1]
1368
- # time_score = max(0.4, 1 - (deviation * 0.6))
1369
- # else:
1370
- # time_score = 0.3
1371
-
1372
- # # 運動類型匹配度計算
1373
- # if exercise_type == exercise_profile['ideal_type']:
1374
- # type_score = 1.0
1375
- # elif exercise_type in exercise_profile['acceptable_types']:
1376
- # type_score = 0.7
1377
- # else:
1378
- # type_score = 0.4
1379
-
1380
- # # 若運動時間過長但強度不足,額外降低分數
1381
- # if exercise_time > time_ranges['acceptable'][1] and exercise_type != exercise_profile['ideal_type']:
1382
- # type_score *= 0.7
1383
-
1384
- # perfect_matches['exercise_match'] = (time_score * 0.6) + (type_score * 0.4)
1385
-
1386
- # # 體型與空間的實際利用評估
1387
- # space_utilization = {
1388
- # 'apartment': {
1389
- # 'Small': 1.0,
1390
- # 'Medium': 0.4,
1391
- # 'Large': 0.2,
1392
- # 'Giant': 0.1
1393
- # },
1394
- # 'house_small': {
1395
- # 'Small': 0.9,
1396
- # 'Medium': 1.0,
1397
- # 'Large': 0.5,
1398
- # 'Giant': 0.3
1399
- # },
1400
- # 'house_large': {
1401
- # 'Small': 0.7,
1402
- # 'Medium': 0.9,
1403
- # 'Large': 1.0,
1404
- # 'Giant': 0.95
1405
- # }
1406
- # }
1407
-
1408
- # # 增加活動空間需求評估
1409
- # space_needs = 'high' if exercise_needs in ['VERY HIGH', 'HIGH'] else 'moderate'
1410
- # if space_needs == 'high' and user_prefs.living_space != 'house_large':
1411
- # space_score = space_utilization[user_prefs.living_space][breed_info['Size']] * 0.8
1412
- # else:
1413
- # space_score = space_utilization.get(user_prefs.living_space,
1414
- # space_utilization['house_small'])[breed_info['Size']]
1415
-
1416
- # perfect_matches['size_match'] = space_score
1417
-
1418
- # # 經驗需求的專業評估
1419
- # care_level = breed_info.get('Care Level', 'MODERATE').upper()
1420
- # temperament = breed_info.get('Temperament', '').lower()
1421
-
1422
- # # 定義進階特徵
1423
- # advanced_traits = ['working', 'independent', 'dominant', 'protective']
1424
- # advanced_trait_count = sum(1 for trait in advanced_traits if trait in temperament)
1425
-
1426
- # # 經驗匹配度計算
1427
- # experience_matrix = {
1428
- # 'HIGH': {
1429
- # 'beginner': 0.2, # 更嚴格的新手限制
1430
- # 'intermediate': 0.6,
1431
- # 'advanced': 1.0
1432
- # },
1433
- # 'MODERATE': {
1434
- # 'beginner': 0.5,
1435
- # 'intermediate': 0.9,
1436
- # 'advanced': 0.95
1437
- # },
1438
- # 'LOW': {
1439
- # 'beginner': 0.9,
1440
- # 'intermediate': 0.85,
1441
- # 'advanced': 0.8 # 對專家稍微降低簡單品種的分數
1442
- # }
1443
- # }
1444
-
1445
- # experience_score = experience_matrix[care_level][user_prefs.experience_level]
1446
-
1447
- # # 根據進階特徵調整分數
1448
- # if advanced_trait_count > 0:
1449
- # if user_prefs.experience_level == 'beginner':
1450
- # experience_score *= (0.8 ** advanced_trait_count)
1451
- # elif user_prefs.experience_level == 'advanced':
1452
- # experience_score *= (1.1 ** min(advanced_trait_count, 2))
1453
-
1454
- # perfect_matches['experience_match'] = experience_score
1455
-
1456
- # # 生活條件整體評估
1457
- # living_score = 1.0
1458
-
1459
- # # 院子影響的嚴格評估
1460
- # if breed_info.get('Exercise Needs', 'MODERATE').upper() in ['HIGH', 'VERY HIGH']:
1461
- # yard_impacts = {
1462
- # 'no_yard': 0.5, # 更嚴格的懲罰
1463
- # 'shared_yard': 0.7,
1464
- # 'private_yard': 1.0
1465
- # }
1466
- # living_score *= yard_impacts.get(user_prefs.yard_access, 0.7)
1467
-
1468
- # # 時間可用性評估
1469
- # time_impacts = {
1470
- # 'limited': 0.6, # 更嚴格的時間限制影響
1471
- # 'moderate': 0.8,
1472
- # 'flexible': 1.0
1473
- # }
1474
- # living_score *= time_impacts.get(user_prefs.time_availability, 0.8)
1475
-
1476
- # perfect_matches['living_condition_match'] = living_score
1477
-
1478
- # return perfect_matches
1479
-
1480
- # def calculate_weights():
1481
- # """計算動態權重,強化條件極端情況的影響"""
1482
- # base_weights = {
1483
- # 'space': 0.20,
1484
- # 'exercise': 0.20,
1485
- # 'experience': 0.20,
1486
- # 'grooming': 0.15,
1487
- # 'noise': 0.15,
1488
- # 'health': 0.10
1489
- # }
1490
-
1491
- # # 計算條件極端度
1492
- # def calculate_condition_extremity():
1493
- # extremities = {}
1494
-
1495
- # # 運動時間極端度評估
1496
- # if user_prefs.exercise_time < 30:
1497
- # extremities['exercise'] = ('very_low', 0.9)
1498
- # elif user_prefs.exercise_time < 60:
1499
- # extremities['exercise'] = ('low', 0.7)
1500
- # elif user_prefs.exercise_time > 150:
1501
- # extremities['exercise'] = ('very_high', 0.9)
1502
- # elif user_prefs.exercise_time > 120:
1503
- # extremities['exercise'] = ('high', 0.7)
1504
- # else:
1505
- # extremities['exercise'] = ('moderate', 0.3)
1506
-
1507
- # # 空間限制極端度評估
1508
- # if user_prefs.living_space == 'apartment':
1509
- # extremities['space'] = ('very_restricted', 0.9)
1510
- # elif user_prefs.living_space == 'house_small':
1511
- # extremities['space'] = ('restricted', 0.6)
1512
- # else:
1513
- # extremities['space'] = ('spacious', 0.3)
1514
-
1515
- # return extremities
1516
-
1517
- # extremities = calculate_condition_extremity()
1518
-
1519
- # # 權重調整
1520
- # weight_adjustments = {}
1521
-
1522
- # # 空間權重調整
1523
- # if extremities['space'][0] == 'very_restricted':
1524
- # weight_adjustments['space'] = 3.0
1525
- # weight_adjustments['noise'] = 2.5
1526
- # elif extremities['space'][0] == 'restricted':
1527
- # weight_adjustments['space'] = 2.0
1528
- # weight_adjustments['noise'] = 1.8
1529
- # elif extremities['space'][0] == 'spacious':
1530
- # weight_adjustments['space'] = 0.7 # 大空間時降低空間權重
1531
- # weight_adjustments['exercise'] = 1.5 # 提升運動重要性
1532
-
1533
- # # 運動需求權重調整
1534
- # if extremities['exercise'][0] in ['very_low', 'very_high']:
1535
- # weight_adjustments['exercise'] = 3.0
1536
- # elif extremities['exercise'][0] in ['low', 'high']:
1537
- # weight_adjustments['exercise'] = 2.0
1538
-
1539
- # # 經驗需求權重調整
1540
- # if user_prefs.experience_level == 'beginner':
1541
- # weight_adjustments['experience'] = 2.5
1542
- # elif user_prefs.experience_level == 'advanced':
1543
- # weight_adjustments['experience'] = 2.0
1544
-
1545
- # # 應用權重調整
1546
- # final_weights = base_weights.copy()
1547
- # for key, adjustment in weight_adjustments.items():
1548
- # final_weights[key] *= adjustment
1549
-
1550
- # return final_weights
1551
-
1552
- # def apply_special_case_adjustments(score):
1553
- # """處理特殊情況,更嚴格的條件組合評估"""
1554
- # severity = 1.0
1555
-
1556
- # # 空間與運動組合的嚴格評估
1557
- # if user_prefs.living_space == 'apartment':
1558
- # if breed_info.get('Exercise Needs', 'MODERATE').upper() == 'VERY HIGH':
1559
- # severity *= 0.5 # 更嚴重的懲罰
1560
- # elif breed_info.get('Exercise Needs') == 'HIGH':
1561
- # severity *= 0.6
1562
- # if breed_info['Size'] in ['Large', 'Giant']:
1563
- # severity *= 0.5
1564
-
1565
- # # 經驗與品種難度組合的嚴格評估
1566
- # if user_prefs.experience_level == 'beginner':
1567
- # if breed_info.get('Care Level') == 'HIGH':
1568
- # if user_prefs.has_children:
1569
- # severity *= 0.5
1570
- # else:
1571
- # severity *= 0.6
1572
-
1573
- # # 時間限制與需求組合的嚴格評估
1574
- # if user_prefs.time_availability == 'limited':
1575
- # if breed_info.get('Exercise Needs').upper() in ['VERY HIGH', 'HIGH']:
1576
- # severity *= 0.6
1577
-
1578
- # # 運動類型不匹配的懲罰
1579
- # if user_prefs.exercise_time > 120:
1580
- # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1581
- # if exercise_needs == 'LOW':
1582
- # severity *= 0.7
1583
- # elif exercise_needs == 'VERY HIGH' and user_prefs.exercise_type == 'light_walks':
1584
- # severity *= 0.6
1585
-
1586
- # return score * severity
1587
-
1588
- # # 評估完美匹配條件
1589
- # perfect_conditions = evaluate_perfect_conditions()
1590
-
1591
- # # 計算動態權重
1592
- # weights = calculate_weights()
1593
-
1594
- # # 正規化權重
1595
- # total_weight = sum(weights.values())
1596
- # normalized_weights = {k: v/total_weight for k, v in weights.items()}
1597
 
1598
- # # 計算基礎分數
1599
- # base_score = sum(scores[k] * normalized_weights[k] for k in scores.keys())
1600
-
1601
- # # 完美匹配獎勵計算(降低獎勵影響)
1602
- # perfect_bonus = 1.0
1603
- # perfect_bonus += 0.12 * perfect_conditions['size_match']
1604
- # perfect_bonus += 0.12 * perfect_conditions['exercise_match']
1605
- # perfect_bonus += 0.12 * perfect_conditions['experience_match']
1606
- # perfect_bonus += 0.04 * perfect_conditions['living_condition_match']
1607
-
1608
- # # 品種特性加成
1609
- # breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
1610
-
1611
- # # 計算最終分數
1612
- # final_score = (base_score * 0.85 + breed_bonus * 0.15) * perfect_bonus
1613
-
1614
- # # 應用特殊情況調整
1615
- # final_score = apply_special_case_adjustments(final_score)
1616
-
1617
- # return min(1.0, final_score)
1618
-
1619
 
1620
  def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1621
  """
@@ -2136,33 +1813,93 @@ def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreference
2136
 
2137
  return multiplier
2138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2139
  def evaluate_breed_specific_requirements():
2140
- """評估品種特定的要求,加強運動需求的判斷"""
 
 
 
 
2141
  multiplier = 1.0
2142
  exercise_time = user_prefs.exercise_time
2143
  exercise_type = user_prefs.exercise_type
2144
 
2145
- # 檢查品種的基本特性
2146
  temperament = breed_info.get('Temperament', '').lower()
2147
  description = breed_info.get('Description', '').lower()
2148
  exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2149
 
2150
- # 加強運動需求的匹配判斷
2151
- if exercise_needs == 'LOW':
2152
- if exercise_time > 90: # 如果用戶運動時間過長
2153
- multiplier *= 0.5 # 給予更強的懲罰
2154
- elif exercise_needs == 'VERY HIGH':
2155
- if exercise_time < 60: # 如果用戶運動時間過短
2156
- multiplier *= 0.5
2157
-
2158
- if 'sprint' in temperament:
2159
- if exercise_time > 120 and exercise_type != 'active_training':
2160
- multiplier *= 0.7
2161
-
2162
- if any(trait in temperament for trait in ['working', 'herding']):
2163
- if exercise_time < 90 or exercise_type == 'light_walks':
2164
- multiplier *= 0.7
2165
-
2166
  return multiplier
2167
 
2168
  def evaluate_environmental_impact():
@@ -2192,40 +1929,76 @@ def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreference
2192
  final_score = score * severity_multiplier
2193
  return max(0.2, min(1.0, final_score))
2194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2195
  def calculate_base_score(scores: dict, weights: dict) -> float:
2196
  """
2197
- 計算基礎分數,更寬容地處理極端組合
2198
  """
2199
- # 進一步降低關鍵指標閾值,使系統更包容極端組合
2200
  critical_thresholds = {
2201
- 'space': 0.45, # 進一步降低閾值
2202
- 'exercise': 0.45,
2203
- 'experience': 0.55,
2204
- 'noise': 0.55
2205
  }
2206
 
 
 
 
 
 
 
 
 
 
2207
  critical_failures = []
2208
  for metric, threshold in critical_thresholds.items():
2209
  if scores[metric] < threshold:
2210
  critical_failures.append((metric, scores[metric]))
2211
 
2212
- base_score = sum(scores[k] * weights[k] for k in scores.keys())
2213
-
2214
  if critical_failures:
2215
- space_exercise_penalty = 0
2216
- other_penalty = 0
2217
-
2218
- for metric, score in critical_failures:
2219
- if metric in ['space', 'exercise']:
2220
- space_exercise_penalty += (critical_thresholds[metric] - score) * 0.15 # 降低懲罰
2221
- else:
2222
- other_penalty += (critical_thresholds[metric] - score) * 0.3
2223
-
2224
- total_penalty = (space_exercise_penalty + other_penalty) / 2
2225
- base_score *= (1 - total_penalty)
2226
 
2227
  if len(critical_failures) > 1:
2228
- base_score *= (0.98 ** (len(critical_failures) - 1)) # 進一步降低多重失敗懲罰
2229
 
2230
  return base_score
2231
 
@@ -2329,75 +2102,71 @@ def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreference
2329
 
2330
 
2331
  def amplify_score_extreme(score: float) -> float:
2332
- """優化分數分布,提供更高的分數範圍"""
 
 
 
 
2333
  def smooth_curve(x: float, steepness: float = 12) -> float:
2334
  import math
2335
  return 1 / (1 + math.exp(-steepness * (x - 0.5)))
2336
 
 
 
 
 
 
 
2337
  if score >= 0.9:
2338
- position = (score - 0.9) / 0.1
2339
- return 0.96 + (position * 0.04) # 90-100的原始分映射到96-100
 
2340
 
2341
  elif score >= 0.8:
2342
- position = (score - 0.8) / 0.1
2343
- return 0.90 + (position * 0.06) # 80-90的原始分映射到90-96
 
2344
 
2345
  elif score >= 0.7:
2346
- position = (score - 0.7) / 0.1
2347
- return 0.82 + (position * 0.08) # 70-80的原始分映射到82-90
 
2348
 
2349
  elif score >= 0.5:
 
2350
  position = (score - 0.5) / 0.2
2351
- return 0.75 + (smooth_curve(position) * 0.07) # 50-70的原始分映射到75-82
 
2352
 
2353
  else:
 
2354
  position = score / 0.5
2355
- return 0.70 + (smooth_curve(position) * 0.05) # 50以下的原始分映射到70-75
2356
-
 
2357
 
2358
  # def amplify_score_extreme(score: float) -> float:
2359
- # """
2360
- # - 完美匹配可達到95-99%
2361
- # - 優秀匹配在90-95%
2362
- # - 良好匹配在85-90%
2363
- # - 一般匹配在75-85%
2364
- # - 較差匹配在65-75%
2365
- # - 極差匹配在50-65%
2366
- # """
2367
  # def smooth_curve(x: float, steepness: float = 12) -> float:
2368
- # """使用sigmoid curve"""
2369
  # import math
2370
  # return 1 / (1 + math.exp(-steepness * (x - 0.5)))
2371
 
2372
  # if score >= 0.9:
2373
- # # 完美匹配:95-99%
2374
  # position = (score - 0.9) / 0.1
2375
- # return 0.95 + (position * 0.04)
2376
 
2377
  # elif score >= 0.8:
2378
- # # 優秀匹配:90-95%
2379
  # position = (score - 0.8) / 0.1
2380
- # return 0.90 + (position * 0.05)
2381
 
2382
  # elif score >= 0.7:
2383
- # # 良好匹配:85-90%
2384
  # position = (score - 0.7) / 0.1
2385
- # return 0.85 + (position * 0.05)
2386
 
2387
  # elif score >= 0.5:
2388
- # # 一般匹配:75-85%
2389
  # position = (score - 0.5) / 0.2
2390
- # base = 0.75
2391
- # return base + (smooth_curve(position) * 0.10)
2392
-
2393
- # elif score >= 0.3:
2394
- # # 較差匹配:65-75%
2395
- # position = (score - 0.3) / 0.2
2396
- # base = 0.65
2397
- # return base + (smooth_curve(position) * 0.10)
2398
 
2399
  # else:
2400
- # # 極差匹配:50-65%
2401
- # position = score / 0.3
2402
- # base = 0.50
2403
- # return base + (smooth_curve(position) * 0.15)
 
1292
  adaptability_score += 0.05
1293
 
1294
  return min(0.2, adaptability_score)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1296
 
1297
  def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1298
  """
 
1813
 
1814
  return multiplier
1815
 
1816
+ # def evaluate_breed_specific_requirements():
1817
+ # """評估品種特定的要求,加強運動需求的判斷"""
1818
+ # multiplier = 1.0
1819
+ # exercise_time = user_prefs.exercise_time
1820
+ # exercise_type = user_prefs.exercise_type
1821
+
1822
+ # # 檢查品種的基本特性
1823
+ # temperament = breed_info.get('Temperament', '').lower()
1824
+ # description = breed_info.get('Description', '').lower()
1825
+ # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1826
+
1827
+ # # 加強運動需求的匹配判斷
1828
+ # if exercise_needs == 'LOW':
1829
+ # if exercise_time > 90: # 如果用戶運動時間過長
1830
+ # multiplier *= 0.5 # 給予更強的懲罰
1831
+ # elif exercise_needs == 'VERY HIGH':
1832
+ # if exercise_time < 60: # 如果用戶運動時間過短
1833
+ # multiplier *= 0.5
1834
+
1835
+ # if 'sprint' in temperament:
1836
+ # if exercise_time > 120 and exercise_type != 'active_training':
1837
+ # multiplier *= 0.7
1838
+
1839
+ # if any(trait in temperament for trait in ['working', 'herding']):
1840
+ # if exercise_time < 90 or exercise_type == 'light_walks':
1841
+ # multiplier *= 0.7
1842
+
1843
+ # return multiplier
1844
+
1845
  def evaluate_breed_specific_requirements():
1846
+ """
1847
+ 1. 嚴格的運動需求匹配
1848
+ 2. 細緻的品種特性評估
1849
+ 3. 強化經驗要求的判斷
1850
+ """
1851
  multiplier = 1.0
1852
  exercise_time = user_prefs.exercise_time
1853
  exercise_type = user_prefs.exercise_type
1854
 
1855
+ # 獲取品種的關鍵特性
1856
  temperament = breed_info.get('Temperament', '').lower()
1857
  description = breed_info.get('Description', '').lower()
1858
  exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1859
+ care_level = breed_info.get('Care Level', 'MODERATE').upper()
1860
+
1861
+ # 運動需求匹配評估
1862
+ exercise_mismatch = {
1863
+ 'VERY HIGH': {
1864
+ 'min_time': 60,
1865
+ 'penalty_rate': 0.4 if exercise_time < 60 else 0.0
1866
+ },
1867
+ 'HIGH': {
1868
+ 'min_time': 45,
1869
+ 'penalty_rate': 0.35 if exercise_time < 45 else 0.0
1870
+ },
1871
+ 'LOW': {
1872
+ 'max_time': 90,
1873
+ 'penalty_rate': 0.4 if exercise_time > 90 else 0.0
1874
+ }
1875
+ }
1876
+
1877
+ if exercise_needs in exercise_mismatch:
1878
+ match_info = exercise_mismatch[exercise_needs]
1879
+ if 'min_time' in match_info and exercise_time < match_info['min_time']:
1880
+ multiplier *= (1 - match_info['penalty_rate'])
1881
+ elif 'max_time' in match_info and exercise_time > match_info['max_time']:
1882
+ multiplier *= (1 - match_info['penalty_rate'])
1883
+
1884
+ # 品種特性專門評估
1885
+ breed_traits = {
1886
+ 'working_dog': ['working', 'herding', 'intelligent', 'active'],
1887
+ 'family_dog': ['gentle', 'friendly', 'good with children', 'patient'],
1888
+ 'guard_dog': ['protective', 'territorial', 'alert', 'watchdog']
1889
+ }
1890
+
1891
+ # 根據用戶條件評估特殊特性
1892
+ for trait_type, traits in breed_traits.items():
1893
+ if any(trait in temperament for trait in traits):
1894
+ if trait_type == 'working_dog':
1895
+ if user_prefs.experience_level == 'beginner':
1896
+ multiplier *= 0.7
1897
+ if exercise_time < 90:
1898
+ multiplier *= 0.75
1899
+ elif trait_type == 'guard_dog':
1900
+ if user_prefs.has_children and user_prefs.experience_level != 'advanced':
1901
+ multiplier *= 0.8
1902
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1903
  return multiplier
1904
 
1905
  def evaluate_environmental_impact():
 
1929
  final_score = score * severity_multiplier
1930
  return max(0.2, min(1.0, final_score))
1931
 
1932
+ # def calculate_base_score(scores: dict, weights: dict) -> float:
1933
+ # """
1934
+ # 計算基礎分數,更寬容地處理極端組合
1935
+ # """
1936
+ # # 進一步降低關鍵指標閾值,使系統更包容極端組合
1937
+ # critical_thresholds = {
1938
+ # 'space': 0.45, # 進一步降低閾值
1939
+ # 'exercise': 0.45,
1940
+ # 'experience': 0.55,
1941
+ # 'noise': 0.55
1942
+ # }
1943
+
1944
+ # critical_failures = []
1945
+ # for metric, threshold in critical_thresholds.items():
1946
+ # if scores[metric] < threshold:
1947
+ # critical_failures.append((metric, scores[metric]))
1948
+
1949
+ # base_score = sum(scores[k] * weights[k] for k in scores.keys())
1950
+
1951
+ # if critical_failures:
1952
+ # space_exercise_penalty = 0
1953
+ # other_penalty = 0
1954
+
1955
+ # for metric, score in critical_failures:
1956
+ # if metric in ['space', 'exercise']:
1957
+ # space_exercise_penalty += (critical_thresholds[metric] - score) * 0.15 # 降低懲罰
1958
+ # else:
1959
+ # other_penalty += (critical_thresholds[metric] - score) * 0.3
1960
+
1961
+ # total_penalty = (space_exercise_penalty + other_penalty) / 2
1962
+ # base_score *= (1 - total_penalty)
1963
+
1964
+ # if len(critical_failures) > 1:
1965
+ # base_score *= (0.98 ** (len(critical_failures) - 1)) # 進一步降低多重失敗懲罰
1966
+
1967
+ # return base_score
1968
+
1969
  def calculate_base_score(scores: dict, weights: dict) -> float:
1970
  """
1971
+ 計算基礎分數,加強訓練需求評估
1972
  """
1973
+ # 基礎閾值保持不變
1974
  critical_thresholds = {
1975
+ 'space': 0.5,
1976
+ 'exercise': 0.5,
1977
+ 'experience': 0.55,
1978
+ 'noise': 0.55
1979
  }
1980
 
1981
+ # 評估訓練需求
1982
+ training_level = breed_info.get('Training', 'MODERATE').upper()
1983
+ if training_level == 'HIGH' and user_prefs.experience_level == 'beginner':
1984
+ # 對需要大量訓練的品種給予較低的基礎分數
1985
+ base_score = sum(scores[k] * weights[k] for k in scores.keys()) * 0.85
1986
+ else:
1987
+ base_score = sum(scores[k] * weights[k] for k in scores.keys())
1988
+
1989
+ # 其他評估邏輯保持不變...
1990
  critical_failures = []
1991
  for metric, threshold in critical_thresholds.items():
1992
  if scores[metric] < threshold:
1993
  critical_failures.append((metric, scores[metric]))
1994
 
 
 
1995
  if critical_failures:
1996
+ penalty = sum((critical_thresholds[metric] - score) * 0.3
1997
+ for metric, score in critical_failures) / len(critical_failures)
1998
+ base_score *= (1 - penalty)
 
 
 
 
 
 
 
 
1999
 
2000
  if len(critical_failures) > 1:
2001
+ base_score *= (0.98 ** (len(critical_failures) - 1))
2002
 
2003
  return base_score
2004
 
 
2102
 
2103
 
2104
  def amplify_score_extreme(score: float) -> float:
2105
+ """
2106
+ 優化分數分布,增加區分度
2107
+ 1. 擴大分數區間差異
2108
+ 2. 更合理的分數映射
2109
+ """
2110
  def smooth_curve(x: float, steepness: float = 12) -> float:
2111
  import math
2112
  return 1 / (1 + math.exp(-steepness * (x - 0.5)))
2113
 
2114
+ def apply_distinction_factor(base_score: float, distinction: float = 0.05) -> float:
2115
+ """增加分數的區分度"""
2116
+ # 根據原始分數的位置增加區分
2117
+ position_factor = base_score - int(base_score * 10) / 10
2118
+ return base_score + (position_factor * distinction)
2119
+
2120
  if score >= 0.9:
2121
+ # 優秀匹配:92-100%
2122
+ base = 0.92 + ((score - 0.9) * 0.08)
2123
+ return apply_distinction_factor(base, 0.06)
2124
 
2125
  elif score >= 0.8:
2126
+ # 很好匹配:85-92%
2127
+ base = 0.85 + ((score - 0.8) * 0.07)
2128
+ return apply_distinction_factor(base, 0.05)
2129
 
2130
  elif score >= 0.7:
2131
+ # 良好匹配:76-85%
2132
+ base = 0.76 + ((score - 0.7) * 0.09)
2133
+ return apply_distinction_factor(base, 0.04)
2134
 
2135
  elif score >= 0.5:
2136
+ # 一般匹配:65-76%
2137
  position = (score - 0.5) / 0.2
2138
+ base = 0.65 + (smooth_curve(position) * 0.11)
2139
+ return apply_distinction_factor(base, 0.03)
2140
 
2141
  else:
2142
+ # 較低匹配:60-65%
2143
  position = score / 0.5
2144
+ base = 0.60 + (smooth_curve(position) * 0.05)
2145
+ return apply_distinction_factor(base, 0.02)
2146
+
2147
 
2148
  # def amplify_score_extreme(score: float) -> float:
2149
+ # """優化分數分布,提供更高的分數範圍"""
 
 
 
 
 
 
 
2150
  # def smooth_curve(x: float, steepness: float = 12) -> float:
 
2151
  # import math
2152
  # return 1 / (1 + math.exp(-steepness * (x - 0.5)))
2153
 
2154
  # if score >= 0.9:
 
2155
  # position = (score - 0.9) / 0.1
2156
+ # return 0.96 + (position * 0.04) # 90-100的原始分映射到96-100
2157
 
2158
  # elif score >= 0.8:
 
2159
  # position = (score - 0.8) / 0.1
2160
+ # return 0.90 + (position * 0.06) # 80-90的原始分映射到90-96
2161
 
2162
  # elif score >= 0.7:
 
2163
  # position = (score - 0.7) / 0.1
2164
+ # return 0.82 + (position * 0.08) # 70-80的原始分映射到82-90
2165
 
2166
  # elif score >= 0.5:
 
2167
  # position = (score - 0.5) / 0.2
2168
+ # return 0.75 + (smooth_curve(position) * 0.07) # 50-70的原始分映射到75-82
 
 
 
 
 
 
 
2169
 
2170
  # else:
2171
+ # position = score / 0.5
2172
+ # return 0.70 + (smooth_curve(position) * 0.05) # 50以下的原始分映射到70-75