Sie könnten Sets (oder Hashes, unabhängig von der Sprache sie nennt), um die Zeiteffizienz zu optimieren.
Konvertieren Sie das Zielarray in einen Satz, und subtrahieren Sie dann die ausgewählte Quelle davon (d. H. Entfernen von gemeinsamen Werten). Führen Sie das rekursiv durch, bis die Zielmenge leer ist. Behalten Sie das beste Ergebnis im Auge (möglichst wenige Quell-Arrays verwenden). Backtrack, wenn die Anzahl der verwendeten Quell-Arrays die Länge der besten Lösung überschreitet, die zu diesem Zeitpunkt bereits gefunden wurde. Hier
ist der Code in 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)
Sehen Sie es auf repl.it laufen
In 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; }
Wenn Notwendigkeit mehr Beschreibung, bitte lassen Kommentar unter Antwort –
Vielleicht wurde die Frage schlecht beschrieben, aber die ganze Bedeutung des Algorithmus ist M1 zu finden. Ich definiere M1 und M2 zur Erklärung der optimalen Lösung, nicht weil sie im Algorithmus bekannt sind. – VahagnNikoghosian
Sie müssen zu mehr Schnittpunkt Array von 'A1-A5 mit' MatchingArray 'finden? –