如何在C#/Unity中高效定义变量组合的「质量」?
高效定义电影主题-类型组合质量的方案
无需全量枚举,规则引擎/权重模型才是更优解
直接枚举所有组合必然会遭遇规模爆炸问题。比如主题有n个,1-2个主题的组合数是n + C(n,2);类型有m个,最多3个类型的组合数是m + C(m,2) + C(m,3)。两者相乘就是总组合数,当n和m涨到10以上时,总组合数会轻松破千,维护成本极高,完全不具备扩展性。
你可以采用以下两种高效且易扩展的思路:
1. 基于规则的评分系统
核心是定义主题-类型适配规则和组合冲突规则,而非枚举所有可能:
- 先给单主题+单类型的基础配对打分:比如
war-action打3分,war-romance打1分,drugs-comedy打0分 - 再定义多元素组合的调整逻辑:
- 多主题:若两个主题高度适配(如
medieval-war),整体基础分保留最高值+0.5;若主题冲突(如space-medieval),基础分取最低值-1 - 多类型:若新增类型与现有组合冲突(如
war-action加romance),直接扣2分至0分;若新增类型适配(如space-action加drama),加0.5分(不超过3分上限)
- 多主题:若两个主题高度适配(如
- 最后将调整后的分数映射到0-3的整数区间
2. 基于权重的统计模型
如果有历史数据(如现有电影的票房、评分对应其主题类型组合),可以训练简单的权重模型:
- 给每个主题、每个类型分配基础权重
- 组合总权重 = 主题权重之和 + 类型权重之和 + 主题-类型交叉权重(比如
war和action的交叉权重很高,war和romance的交叉权重很低) - 将总权重归一化到0-3的评分区间
这种方式扩展性极强,新增主题/类型时只需补充对应的基础权重和交叉权重即可。
示例代码(规则引擎思路)
// 定义主题-类型基础配对得分 Dictionary<Tuple<string, string>, int> baseScores = new Dictionary<Tuple<string, string>, int>() { { Tuple.Create("war", "action"), 3 }, { Tuple.Create("war", "drama"), 2 }, { Tuple.Create("war", "romance"), 1 }, { Tuple.Create("war", "comedy"), 0 }, // 补充其他主题-类型配对... }; // 定义冲突类型对 HashSet<Tuple<string, string>> conflictingGenrePairs = new HashSet<Tuple<string, string>>() { { Tuple.Create("action", "romance") }, // 补充其他冲突类型对... }; int CalculateQualityScore(List<string> topics, List<string> genres) { // 第一步:计算基础得分(取主题-类型配对的最高分) int baseScore = 0; foreach (var topic in topics) { foreach (var genre in genres) { var key = Tuple.Create(topic, genre); if (baseScores.ContainsKey(key) && baseScores[key] > baseScore) { baseScore = baseScores[key]; } } } // 第二步:处理多类型冲突 if (genres.Count >= 2) { for (int i = 0; i < genres.Count; i++) { for (int j = i+1; j < genres.Count; j++) { var pair = Tuple.Create(genres[i], genres[j]); if (conflictingGenrePairs.Contains(pair) || conflictingGenrePairs.Contains(Tuple.Create(genres[j], genres[i]))) { baseScore = Math.Max(0, baseScore - 2); break; } } } } // 第三步:处理多主题适配 if (topics.Count == 2) { if (topics.Contains("war") && topics.Contains("medieval")) { baseScore = Math.Min(3, baseScore + 1); } else if (topics.Contains("space") && topics.Contains("medieval")) { baseScore = Math.Max(0, baseScore - 1); } } return baseScore; }
内容的提问来源于stack exchange,提问作者hell
相关产品推荐
相关产品推荐

