Spaces:
Running
on
Zero
Running
on
Zero
Update scoring_calculation_system.py
Browse files- scoring_calculation_system.py +300 -50
scoring_calculation_system.py
CHANGED
@@ -285,81 +285,328 @@ def calculate_breed_bonus(breed_info: dict, user_prefs: UserPreferences) -> floa
|
|
285 |
return min(0.5, max(-0.35, bonus))
|
286 |
|
287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
@staticmethod
|
289 |
def calculate_additional_factors(breed_info: dict, user_prefs: 'UserPreferences') -> dict:
|
290 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
factors = {
|
292 |
'versatility': 0.0, # 多功能性
|
293 |
'trainability': 0.0, # 可訓練度
|
294 |
'energy_level': 0.0, # 能量水平
|
295 |
'grooming_needs': 0.0, # 美容需求
|
296 |
'social_needs': 0.0, # 社交需求
|
297 |
-
'weather_adaptability': 0.0
|
|
|
|
|
298 |
}
|
299 |
|
300 |
temperament = breed_info.get('Temperament', '').lower()
|
|
|
301 |
size = breed_info.get('Size', 'Medium')
|
302 |
|
303 |
-
# 1. 多功能性評估
|
304 |
-
versatile_traits =
|
305 |
-
|
|
|
|
|
|
|
|
|
|
|
306 |
|
307 |
-
|
308 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
|
310 |
factors['versatility'] = min(1.0, trait_score + role_score)
|
311 |
|
312 |
-
# 2.
|
313 |
trainable_traits = {
|
314 |
'intelligent': 0.3,
|
315 |
'eager to please': 0.3,
|
316 |
'trainable': 0.2,
|
317 |
-
'quick learner': 0.2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
318 |
}
|
319 |
-
factors['trainability'] = min(1.0, sum(value for trait, value in trainable_traits.items()
|
320 |
-
if trait in temperament))
|
321 |
|
322 |
-
|
|
|
|
|
|
|
323 |
exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
|
324 |
energy_levels = {
|
325 |
-
'VERY HIGH':
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
}
|
331 |
-
factors['energy_level'] = energy_levels.get(exercise_needs, 0.6)
|
332 |
|
333 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
grooming_needs = breed_info.get('Grooming Needs', 'MODERATE').upper()
|
335 |
grooming_levels = {
|
336 |
'HIGH': 1.0,
|
337 |
'MODERATE': 0.6,
|
338 |
'LOW': 0.3
|
339 |
}
|
340 |
-
coat_penalty = 0.2 if any(term in breed_info.get('Description', '').lower()
|
341 |
-
for term in ['long coat', 'double coat']) else 0
|
342 |
-
factors['grooming_needs'] = min(1.0, grooming_levels.get(grooming_needs, 0.6) + coat_penalty)
|
343 |
|
344 |
-
#
|
345 |
-
|
346 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
347 |
|
348 |
-
social_score = sum(0.25 for trait in social_traits if trait in temperament)
|
349 |
-
antisocial_score = sum(-0.2 for trait in antisocial_traits if trait in temperament)
|
350 |
factors['social_needs'] = min(1.0, max(0.0, social_score + antisocial_score))
|
351 |
|
352 |
-
# 6. 氣候適應性評估
|
353 |
-
|
354 |
-
'cold':
|
355 |
-
|
356 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
}
|
358 |
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
return factors
|
364 |
|
365 |
|
@@ -1217,12 +1464,12 @@ def calculate_final_weighted_score(scores: dict, user_prefs: UserPreferences,
|
|
1217 |
breed_info: dict, adaptability_bonus: float) -> float:
|
1218 |
"""計算最終加權分數"""
|
1219 |
base_weights = {
|
1220 |
-
'space': 0.
|
1221 |
-
'exercise': 0.
|
1222 |
'grooming': 0.15,
|
1223 |
-
'experience': 0.
|
1224 |
-
'health': 0.
|
1225 |
-
'noise': 0.
|
1226 |
}
|
1227 |
|
1228 |
# 根據居住環境動態調整權重
|
@@ -1243,6 +1490,13 @@ def calculate_final_weighted_score(scores: dict, user_prefs: UserPreferences,
|
|
1243 |
base_weights['exercise'] *= 1.2
|
1244 |
base_weights['experience'] *= 0.8
|
1245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1246 |
# 有���童時的特殊調整
|
1247 |
if user_prefs.has_children:
|
1248 |
base_weights['noise'] *= 1.3
|
@@ -1268,16 +1522,12 @@ def calculate_final_weighted_score(scores: dict, user_prefs: UserPreferences,
|
|
1268 |
|
1269 |
def amplify_score_range(score: float) -> float:
|
1270 |
"""擴大分數範圍,使差異更明顯"""
|
1271 |
-
min_score = 0.
|
1272 |
-
max_score = 0.
|
1273 |
|
1274 |
-
#
|
1275 |
normalized = (score - 0.5) / 0.5
|
|
|
1276 |
|
1277 |
-
# 非線性轉換
|
1278 |
-
amplified = math.pow(abs(normalized), 1.5) * math.copysign(1, normalized)
|
1279 |
-
|
1280 |
-
# 映射回目標範圍
|
1281 |
final = min_score + (max_score - min_score) * ((amplified + 1) / 2)
|
1282 |
-
|
1283 |
-
return min(max_score, max(min_score, final))
|
|
|
285 |
return min(0.5, max(-0.35, bonus))
|
286 |
|
287 |
|
288 |
+
# @staticmethod
|
289 |
+
# def calculate_additional_factors(breed_info: dict, user_prefs: 'UserPreferences') -> dict:
|
290 |
+
# """計算額外的評估因素"""
|
291 |
+
# factors = {
|
292 |
+
# 'versatility': 0.0, # 多功能性
|
293 |
+
# 'trainability': 0.0, # 可訓練度
|
294 |
+
# 'energy_level': 0.0, # 能量水平
|
295 |
+
# 'grooming_needs': 0.0, # 美容需求
|
296 |
+
# 'social_needs': 0.0, # 社交需求
|
297 |
+
# 'weather_adaptability': 0.0 # 氣候適應性
|
298 |
+
# }
|
299 |
+
|
300 |
+
# temperament = breed_info.get('Temperament', '').lower()
|
301 |
+
# size = breed_info.get('Size', 'Medium')
|
302 |
+
|
303 |
+
# # 1. 多功能性評估
|
304 |
+
# versatile_traits = ['intelligent', 'adaptable', 'trainable', 'athletic']
|
305 |
+
# working_roles = ['working', 'herding', 'hunting', 'sporting', 'companion']
|
306 |
+
|
307 |
+
# trait_score = sum(0.2 for trait in versatile_traits if trait in temperament)
|
308 |
+
# role_score = sum(0.2 for role in working_roles if role in breed_info.get('Description', '').lower())
|
309 |
+
|
310 |
+
# factors['versatility'] = min(1.0, trait_score + role_score)
|
311 |
+
|
312 |
+
# # 2. 可訓練度評估
|
313 |
+
# trainable_traits = {
|
314 |
+
# 'intelligent': 0.3,
|
315 |
+
# 'eager to please': 0.3,
|
316 |
+
# 'trainable': 0.2,
|
317 |
+
# 'quick learner': 0.2
|
318 |
+
# }
|
319 |
+
# factors['trainability'] = min(1.0, sum(value for trait, value in trainable_traits.items()
|
320 |
+
# if trait in temperament))
|
321 |
+
|
322 |
+
# # 3. 能量水平評估
|
323 |
+
# exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
|
324 |
+
# energy_levels = {
|
325 |
+
# 'VERY HIGH': 1.0,
|
326 |
+
# 'HIGH': 0.8,
|
327 |
+
# 'MODERATE': 0.6,
|
328 |
+
# 'LOW': 0.4,
|
329 |
+
# 'VARIES': 0.6
|
330 |
+
# }
|
331 |
+
# factors['energy_level'] = energy_levels.get(exercise_needs, 0.6)
|
332 |
+
|
333 |
+
# # 4. 美容需求評估
|
334 |
+
# grooming_needs = breed_info.get('Grooming Needs', 'MODERATE').upper()
|
335 |
+
# grooming_levels = {
|
336 |
+
# 'HIGH': 1.0,
|
337 |
+
# 'MODERATE': 0.6,
|
338 |
+
# 'LOW': 0.3
|
339 |
+
# }
|
340 |
+
# coat_penalty = 0.2 if any(term in breed_info.get('Description', '').lower()
|
341 |
+
# for term in ['long coat', 'double coat']) else 0
|
342 |
+
# factors['grooming_needs'] = min(1.0, grooming_levels.get(grooming_needs, 0.6) + coat_penalty)
|
343 |
+
|
344 |
+
# # 5. 社交需求評估
|
345 |
+
# social_traits = ['friendly', 'social', 'affectionate', 'people-oriented']
|
346 |
+
# antisocial_traits = ['independent', 'aloof', 'reserved']
|
347 |
+
|
348 |
+
# social_score = sum(0.25 for trait in social_traits if trait in temperament)
|
349 |
+
# antisocial_score = sum(-0.2 for trait in antisocial_traits if trait in temperament)
|
350 |
+
# factors['social_needs'] = min(1.0, max(0.0, social_score + antisocial_score))
|
351 |
+
|
352 |
+
# # 6. 氣候適應性評估
|
353 |
+
# climate_terms = {
|
354 |
+
# 'cold': ['thick coat', 'winter', 'cold climate'],
|
355 |
+
# 'hot': ['short coat', 'warm climate', 'heat tolerant'],
|
356 |
+
# 'moderate': ['adaptable', 'all climate']
|
357 |
+
# }
|
358 |
+
|
359 |
+
# climate_matches = sum(1 for term in climate_terms[user_prefs.climate]
|
360 |
+
# if term in breed_info.get('Description', '').lower())
|
361 |
+
# factors['weather_adaptability'] = min(1.0, climate_matches * 0.3 + 0.4) # 基礎分0.4
|
362 |
+
|
363 |
+
# return factors
|
364 |
+
|
365 |
+
|
366 |
@staticmethod
|
367 |
def calculate_additional_factors(breed_info: dict, user_prefs: 'UserPreferences') -> dict:
|
368 |
+
"""
|
369 |
+
計算額外的評估因素,結合品種特性與使用者需求的全面評估系統
|
370 |
+
|
371 |
+
此函數整合了:
|
372 |
+
1. 多功能性評估 - 品種的多樣化能力
|
373 |
+
2. 訓練性評估 - 學習和服從能力
|
374 |
+
3. 能量水平評估 - 活力和運動需求
|
375 |
+
4. 美容需求評估 - 護理和維護需求
|
376 |
+
5. 社交需求評估 - 與人互動的需求程度
|
377 |
+
6. 氣候適應性 - 對環境的適應能力
|
378 |
+
7. 運動類型匹配 - 與使用者運動習慣的契合度
|
379 |
+
8. 生活方式適配 - 與使用者日常生活的匹配度
|
380 |
+
"""
|
381 |
factors = {
|
382 |
'versatility': 0.0, # 多功能性
|
383 |
'trainability': 0.0, # 可訓練度
|
384 |
'energy_level': 0.0, # 能量水平
|
385 |
'grooming_needs': 0.0, # 美容需求
|
386 |
'social_needs': 0.0, # 社交需求
|
387 |
+
'weather_adaptability': 0.0,# 氣候適應性
|
388 |
+
'exercise_match': 0.0, # 運動匹配度
|
389 |
+
'lifestyle_fit': 0.0 # 生活方式適配度
|
390 |
}
|
391 |
|
392 |
temperament = breed_info.get('Temperament', '').lower()
|
393 |
+
description = breed_info.get('Description', '').lower()
|
394 |
size = breed_info.get('Size', 'Medium')
|
395 |
|
396 |
+
# 1. 多功能性評估 - 加強品種用途評估
|
397 |
+
versatile_traits = {
|
398 |
+
'intelligent': 0.25,
|
399 |
+
'adaptable': 0.25,
|
400 |
+
'trainable': 0.20,
|
401 |
+
'athletic': 0.15,
|
402 |
+
'versatile': 0.15
|
403 |
+
}
|
404 |
|
405 |
+
working_roles = {
|
406 |
+
'working': 0.20,
|
407 |
+
'herding': 0.15,
|
408 |
+
'hunting': 0.15,
|
409 |
+
'sporting': 0.15,
|
410 |
+
'companion': 0.10
|
411 |
+
}
|
412 |
+
|
413 |
+
# 計算特質分數
|
414 |
+
trait_score = sum(value for trait, value in versatile_traits.items()
|
415 |
+
if trait in temperament)
|
416 |
+
|
417 |
+
# 計算角色分數
|
418 |
+
role_score = sum(value for role, value in working_roles.items()
|
419 |
+
if role in description)
|
420 |
+
|
421 |
+
# 根據使用者需求調整多功能性評分
|
422 |
+
purpose_traits = {
|
423 |
+
'light_walks': ['calm', 'gentle', 'easy-going'],
|
424 |
+
'moderate_activity': ['adaptable', 'balanced', 'versatile'],
|
425 |
+
'active_training': ['intelligent', 'trainable', 'working']
|
426 |
+
}
|
427 |
+
|
428 |
+
if user_prefs.exercise_type in purpose_traits:
|
429 |
+
matching_traits = sum(1 for trait in purpose_traits[user_prefs.exercise_type]
|
430 |
+
if trait in temperament)
|
431 |
+
trait_score += matching_traits * 0.15
|
432 |
|
433 |
factors['versatility'] = min(1.0, trait_score + role_score)
|
434 |
|
435 |
+
# 2. 訓練性評估 - 考慮使用者經驗
|
436 |
trainable_traits = {
|
437 |
'intelligent': 0.3,
|
438 |
'eager to please': 0.3,
|
439 |
'trainable': 0.2,
|
440 |
+
'quick learner': 0.2,
|
441 |
+
'obedient': 0.2
|
442 |
+
}
|
443 |
+
|
444 |
+
base_trainability = sum(value for trait, value in trainable_traits.items()
|
445 |
+
if trait in temperament)
|
446 |
+
|
447 |
+
# 根據使用者經驗調整訓練性評分
|
448 |
+
experience_multipliers = {
|
449 |
+
'beginner': 1.2, # 新手更需要容易訓練的狗
|
450 |
+
'intermediate': 1.0,
|
451 |
+
'advanced': 0.8 # 專家能處理較難訓練的狗
|
452 |
}
|
|
|
|
|
453 |
|
454 |
+
factors['trainability'] = min(1.0, base_trainability *
|
455 |
+
experience_multipliers.get(user_prefs.experience_level, 1.0))
|
456 |
+
|
457 |
+
# 3. 能量水平評估 - 強化運動需求匹配
|
458 |
exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
|
459 |
energy_levels = {
|
460 |
+
'VERY HIGH': {
|
461 |
+
'score': 1.0,
|
462 |
+
'min_exercise': 120,
|
463 |
+
'ideal_exercise': 150
|
464 |
+
},
|
465 |
+
'HIGH': {
|
466 |
+
'score': 0.8,
|
467 |
+
'min_exercise': 90,
|
468 |
+
'ideal_exercise': 120
|
469 |
+
},
|
470 |
+
'MODERATE': {
|
471 |
+
'score': 0.6,
|
472 |
+
'min_exercise': 60,
|
473 |
+
'ideal_exercise': 90
|
474 |
+
},
|
475 |
+
'LOW': {
|
476 |
+
'score': 0.4,
|
477 |
+
'min_exercise': 30,
|
478 |
+
'ideal_exercise': 60
|
479 |
+
}
|
480 |
}
|
|
|
481 |
|
482 |
+
breed_energy = energy_levels.get(exercise_needs, energy_levels['MODERATE'])
|
483 |
+
|
484 |
+
# 計算運動時間匹配度
|
485 |
+
if user_prefs.exercise_time >= breed_energy['ideal_exercise']:
|
486 |
+
energy_score = breed_energy['score']
|
487 |
+
else:
|
488 |
+
# 如果運動時間不足,按比例降低分數
|
489 |
+
deficit_ratio = max(0.4, user_prefs.exercise_time / breed_energy['ideal_exercise'])
|
490 |
+
energy_score = breed_energy['score'] * deficit_ratio
|
491 |
+
|
492 |
+
factors['energy_level'] = energy_score
|
493 |
+
|
494 |
+
# 4. 美容需求評估 - 加入更多毛髮類型考量
|
495 |
grooming_needs = breed_info.get('Grooming Needs', 'MODERATE').upper()
|
496 |
grooming_levels = {
|
497 |
'HIGH': 1.0,
|
498 |
'MODERATE': 0.6,
|
499 |
'LOW': 0.3
|
500 |
}
|
|
|
|
|
|
|
501 |
|
502 |
+
# 特殊毛髮類型評估
|
503 |
+
coat_adjustments = 0
|
504 |
+
if 'long coat' in description:
|
505 |
+
coat_adjustments += 0.2
|
506 |
+
if 'double coat' in description:
|
507 |
+
coat_adjustments += 0.15
|
508 |
+
if 'curly' in description:
|
509 |
+
coat_adjustments += 0.15
|
510 |
+
|
511 |
+
# 根據使用者承諾度調整
|
512 |
+
commitment_multipliers = {
|
513 |
+
'low': 1.5, # 低承諾度時加重美容需求的影響
|
514 |
+
'medium': 1.0,
|
515 |
+
'high': 0.8 # 高承諾度時降低美容需求的影響
|
516 |
+
}
|
517 |
+
|
518 |
+
base_grooming = grooming_levels.get(grooming_needs, 0.6) + coat_adjustments
|
519 |
+
factors['grooming_needs'] = min(1.0, base_grooming *
|
520 |
+
commitment_multipliers.get(user_prefs.grooming_commitment, 1.0))
|
521 |
+
|
522 |
+
# 5. 社交需求評估 - 加強家庭情況考量
|
523 |
+
social_traits = {
|
524 |
+
'friendly': 0.25,
|
525 |
+
'social': 0.25,
|
526 |
+
'affectionate': 0.20,
|
527 |
+
'people-oriented': 0.20
|
528 |
+
}
|
529 |
+
|
530 |
+
antisocial_traits = {
|
531 |
+
'independent': -0.20,
|
532 |
+
'aloof': -0.20,
|
533 |
+
'reserved': -0.15
|
534 |
+
}
|
535 |
+
|
536 |
+
social_score = sum(value for trait, value in social_traits.items()
|
537 |
+
if trait in temperament)
|
538 |
+
antisocial_score = sum(value for trait, value in antisocial_traits.items()
|
539 |
+
if trait in temperament)
|
540 |
+
|
541 |
+
# 家庭情況調整
|
542 |
+
if user_prefs.has_children:
|
543 |
+
child_friendly_bonus = 0.2 if 'good with children' in temperament else 0
|
544 |
+
social_score += child_friendly_bonus
|
545 |
|
|
|
|
|
546 |
factors['social_needs'] = min(1.0, max(0.0, social_score + antisocial_score))
|
547 |
|
548 |
+
# 6. 氣候適應性評估 - 更細緻的環境適應評估
|
549 |
+
climate_traits = {
|
550 |
+
'cold': {
|
551 |
+
'positive': ['thick coat', 'winter', 'cold climate'],
|
552 |
+
'negative': ['short coat', 'heat sensitive']
|
553 |
+
},
|
554 |
+
'hot': {
|
555 |
+
'positive': ['short coat', 'heat tolerant', 'warm climate'],
|
556 |
+
'negative': ['thick coat', 'cold climate']
|
557 |
+
},
|
558 |
+
'moderate': {
|
559 |
+
'positive': ['adaptable', 'all climate'],
|
560 |
+
'negative': []
|
561 |
+
}
|
562 |
+
}
|
563 |
+
|
564 |
+
climate_score = 0.4 # 基礎分數
|
565 |
+
if user_prefs.climate in climate_traits:
|
566 |
+
# 正面特質加分
|
567 |
+
climate_score += sum(0.2 for term in climate_traits[user_prefs.climate]['positive']
|
568 |
+
if term in description)
|
569 |
+
# 負面特質減分
|
570 |
+
climate_score -= sum(0.2 for term in climate_traits[user_prefs.climate]['negative']
|
571 |
+
if term in description)
|
572 |
+
|
573 |
+
factors['weather_adaptability'] = min(1.0, max(0.0, climate_score))
|
574 |
+
|
575 |
+
# 7. 運動類型匹配評估
|
576 |
+
exercise_type_traits = {
|
577 |
+
'light_walks': ['calm', 'gentle'],
|
578 |
+
'moderate_activity': ['adaptable', 'balanced'],
|
579 |
+
'active_training': ['athletic', 'energetic']
|
580 |
}
|
581 |
|
582 |
+
if user_prefs.exercise_type in exercise_type_traits:
|
583 |
+
match_score = sum(0.25 for trait in exercise_type_traits[user_prefs.exercise_type]
|
584 |
+
if trait in temperament)
|
585 |
+
factors['exercise_match'] = min(1.0, match_score + 0.5) # 基礎分0.5
|
586 |
+
|
587 |
+
# 8. 生活方式適配評估
|
588 |
+
lifestyle_score = 0.5 # 基礎分數
|
589 |
+
|
590 |
+
# 空間適配
|
591 |
+
if user_prefs.living_space == 'apartment':
|
592 |
+
if size == 'Small':
|
593 |
+
lifestyle_score += 0.2
|
594 |
+
elif size == 'Large':
|
595 |
+
lifestyle_score -= 0.2
|
596 |
+
elif user_prefs.living_space == 'house_large':
|
597 |
+
if size in ['Large', 'Giant']:
|
598 |
+
lifestyle_score += 0.2
|
599 |
+
|
600 |
+
# 時間可用性適配
|
601 |
+
time_availability_bonus = {
|
602 |
+
'limited': -0.1,
|
603 |
+
'moderate': 0,
|
604 |
+
'flexible': 0.1
|
605 |
+
}
|
606 |
+
lifestyle_score += time_availability_bonus.get(user_prefs.time_availability, 0)
|
607 |
+
|
608 |
+
factors['lifestyle_fit'] = min(1.0, max(0.0, lifestyle_score))
|
609 |
+
|
610 |
return factors
|
611 |
|
612 |
|
|
|
1464 |
breed_info: dict, adaptability_bonus: float) -> float:
|
1465 |
"""計算最終加權分數"""
|
1466 |
base_weights = {
|
1467 |
+
'space': 0.30,
|
1468 |
+
'exercise': 0.25,
|
1469 |
'grooming': 0.15,
|
1470 |
+
'experience': 0.15,
|
1471 |
+
'health': 0.10,
|
1472 |
+
'noise': 0.05
|
1473 |
}
|
1474 |
|
1475 |
# 根據居住環境動態調整權重
|
|
|
1490 |
base_weights['exercise'] *= 1.2
|
1491 |
base_weights['experience'] *= 0.8
|
1492 |
|
1493 |
+
if user_prefs.exercise_time > 120: # 高運動時間
|
1494 |
+
base_weights['exercise'] *= 1.5
|
1495 |
+
base_weights['space'] *= 1.3
|
1496 |
+
elif user_prefs.exercise_time < 45: # 低運動時間
|
1497 |
+
base_weights['exercise'] *= 0.7
|
1498 |
+
base_weights['health'] *= 1.2
|
1499 |
+
|
1500 |
# 有���童時的特殊調整
|
1501 |
if user_prefs.has_children:
|
1502 |
base_weights['noise'] *= 1.3
|
|
|
1522 |
|
1523 |
def amplify_score_range(score: float) -> float:
|
1524 |
"""擴大分數範圍,使差異更明顯"""
|
1525 |
+
min_score = 0.40 # 降低最小分數
|
1526 |
+
max_score = 0.98 # 提高最高分數
|
1527 |
|
1528 |
+
# 使用更激進的非線性轉換
|
1529 |
normalized = (score - 0.5) / 0.5
|
1530 |
+
amplified = math.pow(abs(normalized), 1.3) * math.copysign(1, normalized)
|
1531 |
|
|
|
|
|
|
|
|
|
1532 |
final = min_score + (max_score - min_score) * ((amplified + 1) / 2)
|
1533 |
+
return max(min_score, min(max_score, final))
|
|