你可以使用集(或哈希值,無論語言稱他們),以優化的時間效率。
將目標數組轉換爲一個集合,然後從中減去所選的源(即刪除公共值)。繼續遞歸直到目標集合爲空。跟蹤最佳結果(儘可能使用最少的源數組)。如果正在使用的源數組的數量超過了當時已經找到的最佳解決方案的長度,則返回。
這裏是在Python代碼:
def find_optimal_coverage(target, sources):
max_size = len(target)
best = None
def recurse(target, sources, selected):
nonlocal max_size, best
if len(target) == 0:
best = selected
max_size = len(best) - 1
return True
if len(selected) == max_size:
return None
for i, source in enumerate(sources):
result = recurse(target - set(source), sources[i+1:],
selected + [list(source)])
if result:
return True
target = set(target) # convert to set for faster lookup
# limit the source lists to elements that occur in the target
sources = list(map(target.intersection, sources))
# limit target to elements that occur in at least one source
target = set.union(*sources)
# sort sources by decreasing length to maximise probability of
# finding optimal solution sooner
sources.sort(key = len, reverse = True)
if recurse(target, sources, []):
return best
result = find_optimal_coverage(
[1, 2, 3, 4, 5, 6, 8],
[
[1, 4, 6, 7],
[2, 3, 5],
[1, 5],
[4],
[1, 6]
]
)
print(result)
看到它在repl.it
運行在JavaScript:
function subtractArray(s, arr) {
return arr.reduce((s, v) => (s.delete(v), s), new Set(s));
}
function findOptimalCoverage(target, sources) {
var maxSize = target.size;
var best = null;
function recurse(target, sources, selected) {
if (target.size == 0) {
best = selected;
maxSize = best.length - 1;
return true;
}
if (selected.length == maxSize) return;
return sources.some((source, i) =>
recurse(subtractArray(target, source), sources.slice(i+1),
selected.concat([source]))
);
}
target = new Set(target) // convert to set for faster lookup
// limit the source arrays to elements that occur in the target
sources = sources.map(source => source.filter(target.has.bind(target)));
// limit target to elements that occur in at least one source
target = new Set([].concat(...sources));
// sort sources by decreasing length to maximise probability of
// finding optimal solution sooner
sources.sort((a,b) => b.length - a.length);
if (recurse(target, sources, [])) return best;
}
var result = findOptimalCoverage(
[1, 2, 3, 4, 5, 6, 8],
[
[1, 4, 6, 7],
[2, 3, 5],
[1, 5],
[4],
[1, 6]
]
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
如果需要更多的描述,請留下評論根據回答 –
也許問題描述不好,但算法的全部含義是找到M1。我定義了M1和M2來解釋最優解,並不是因爲它們在算法中是已知的。 – VahagnNikoghosian
你需要找到更多的'A1-A5'與'MatchingArray'相交的數組? –