如何优化基于预定义分组的国家子集最短描述求解?
问题:寻找国家子集的最优极简描述
需求说明
- 核心目标:通过预定义国家分组与单个国家的组合(支持
+包含、-排除操作),生成目标国家子集的最短描述(即元素数量最少的表达式) - 基础设定:
- 国家范围:所有双字母ISO国家代码(如US、DE、NL等)
- 预定义分组:固定的国家集合,示例:
- GROUP1: NL, BE, LU
- GROUP2: NL, BE, LU, CZ, US, FI, NO, GI, FR, DK
- 示例验证:目标子集
CZ, US, FI, NO, GI, FR, DK, DE的最优描述为+GROUP2 +DE -GROUP1,展开后可完全还原目标子集
当前困境
- 现有的暴力遍历解法(遍历所有可能的分组/国家组合)复杂度极高,无法应对大规模的国家或分组数量
- 暂未找到可扩展的算法思路、适配库或实现示例
暴力解法示例代码(JavaScript)
let countries = ['C1', 'C2', 'C3', 'C4', 'C5', 'C6'] let groups = { G1: ['C1', 'C2', 'C3', 'C4', 'C5'], G2: ['C1', 'C4'], } let output = getBest(['C2', 'C3', 'C5', 'C6']) // output == ["+C6", "+G1", "-G2"] function getBest(input) { const ids = countries.concat(Object.keys(groups)) let best = input for (const t of combinations(ids)) { if (expand(t, groups).sort().toString() == input.toString()) { if (t.length < best.length) best = [...t] } } return best } // Expands short form to long form function expand(s, groups) { return Array.from( s.sort().reduce((acc, curr) => { let symbol = curr[0] let id = curr.slice(1) if (groups[id]) { curr = groups[id] } else { curr = [id] } if (symbol == '+') { return new Set([...acc, ...curr]) } else { return new Set([...acc].filter((a) => !curr.includes(a))) } }, new Set()) ) } // Yields all possible short form options function* combinations(array) { array = ['+', '-'].reduce((acc, curr) => { return acc.concat(array.map((s) => curr + s)) }, []) for (const subset of subsets(array)) { yield subset } } // Creates powerset of array function* subsets(array, offset = 0) { while (offset < array.length) { let first = array[offset++] for (let subset of subsets(array, offset)) { subset.push(first) yield subset } } yield [] }
内容的提问来源于stack exchange,提问作者erik
相关产品推荐
相关产品推荐

