簡體   English   中英

匹配算法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM