[英]Matching algorithm
我有一份鉛筆清單和一份橡皮擦清單。 目的是檢查所有橡皮擦是否可以放在鉛筆上。 橡皮擦可以放在多個不同的鉛筆上。 鉛筆最多可以有1個橡皮擦。
如果我只是穿過所有的橡皮擦並將它們放在鉛筆上,我最終會得到不適合沒有空置鉛筆的橡皮擦,即使有一個解決方案都有鉛筆上的所有橡皮擦。
我可以使用什么算法來找出適合鉛筆上所有橡皮擦的組合?
public class Eraser(){
public boolean matches(Pencil p){
//unimportant
}
}
public class Pencil(){
}
我的嘗試
public boolean doMatch(List<Eraser> erasers, List<Pencil> pencils){
for (Eraser e : erasers) {
boolean found = false;
Iterator it = pencils.iterator();
while (it.hasNext()) {
Pencil p = (Pencil) it.next();
if (e.matches(p)) {
found = true;
it.remove();
break;
}
}
if (!found) {
return false;
}
}
return true;
}
您可以將問題表述為約束滿足問題
變量將是例如
X_i=eraser put on pencil i
域名
D_i=erasers fitting on pencil i
而且約束是
X_i != X_j for i!=j
然后可以使用針對CSP的回溯算法來解決該問題。 有許多方法可以通過啟發式方法來改進回溯搜索,例如“最小剩余值”啟發式算法。 一本好書就是羅素,諾維格:人工智能
這是一個簡單的解決方案。 我懷疑它的擴展性很好。 從適合最少鉛筆的橡皮擦開始,可能會提高效率。
我沒有打過Eraser
課。 這里matches
列表中的每個索引都有一個Eraser
。
private static final class Pencil {
private final int id;
private Pencil(int id) { this.id = id; }
@Override
public String toString() { return "p" + id; }
}
public static void main(String[] args) {
Pencil p1 = new Pencil(1);
Pencil p2 = new Pencil(2);
Pencil p3 = new Pencil(3);
Pencil p4 = new Pencil(4);
Pencil p5 = new Pencil(5);
List<Set<Pencil>> matches = new ArrayList<>();
matches.add(new HashSet<>(Arrays.asList(p1, p2, p5))); // First eraser only fits these 3 pencils.
matches.add(new HashSet<>(Arrays.asList(p3, p4))); // Second eraser only fits these 2 pencils.
matches.add(new HashSet<>(Arrays.asList(p3, p5))); // etc
matches.add(new HashSet<>(Arrays.asList(p1, p2, p4)));
matches.add(new HashSet<>(Arrays.asList(p1, p5)));
System.out.println(allocate(matches)); // prints [p2, p4, p3, p1, p5]
}
// Returns null if no solution can be found.
private static List<Pencil> allocate(List<Set<Pencil>> matches) {
return allocate(matches, new ArrayList<>());
}
private static List<Pencil> allocate(List<Set<Pencil>> matches, List<Pencil> solution) {
int size = solution.size();
if (matches.size() == size)
return solution;
for (Pencil pencil : matches.get(size)) {
if (solution.contains(pencil))
continue;
List<Pencil> copy = new ArrayList<>(solution);
copy.add(pencil);
List<Pencil> result = allocate(matches, copy);
if (result != null)
return result;
}
return null;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.