私は検索アルゴリズムとバックトラックプログラミングにかなり興味を持っています。今のところ、正確なカバーの問題を解決するために、アルゴリズムX(私の他の投稿:Determine conflict-free sets?を参照)を実装しました。これは非常にうまくいくが、私は今、バックトラックのより基本的な変種でこれを解決することに興味がある。私はこれをどうやって行うことができないのか分かりません。問題の説明は前と同じです:?
あなたは一組の束を持っているとしますが、各組にはいくつかの部分集合があります。
セット1 = {(バナナ、パイナップル、オレンジ)、(リンゴ、ケール、キュウリ)、(タマネギ、ニンニク)}
SET2 = {(バナナ、キュウリ、ニンニク)、(アボカド、トマト)}各サブセットは、競合他の選択されたサブセットとの自由でなければならないのに対し
... = {...}
目標
SETNは現在(各セットからの1つのサブセットを選択するために、1つの要素であります他の選択されたサブセットのいずれにも含まれない)。
例として、私は2つのJavaクラスを書いています。セットは単一の文字で識別され、要素はプレーン・ナンバーです。
私は特に二つの問題があります(最小の要素、最小のコスト、...とのサブセットを選択)ヒューリスティックの使用が可能であるように、全てのセット/サブセットを反復処理する方法
- を
- 選択したセット+サブセットとその含まれた要素を維持する方法。
私が見つけることができる他のすべての例は、数独またはn-Queensであり、すべて固定ループを使用しています。それに加えて、私は、選択されたパス/セットが前に選択されたサブセット/要素と矛盾している可能性があるかどうかをチェックするために、関数 "isPossiblePartialSolution"を使用することができる、かなり一般的なアプローチについて考えていました。ここで
は、2つのJavaクラスです:import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Set> allSets = buildRandomTest();
for(Set r : allSets) {
System.out.print("Set with id: " + r.id + " is subset in collection: " + r.name + " and contains: ");
for(Integer n : r.listOfElements) {
System.out.print(" " + n + " ");
}
System.out.println();
}
}
public static int myRandomRange(int low, int high) {
return (int) (Math.random() * (++high - low) + low);
}
public static ArrayList<Set> buildRandomTest() {
ArrayList<Set> mySet = new ArrayList<Set>();
int numberOfSets = myRandomRange(10, 12);
for(int i=0; i<numberOfSets; i++) {
String nameOfSet = Character.toString((char) myRandomRange(65, 67));
Set tmp = new Set(nameOfSet, i);
ArrayList<Integer> listOfElements = new ArrayList<Integer>();
int elementsInList = myRandomRange(2, 4);
for(int j=0; j<elementsInList; j++) {
listOfElements.add(myRandomRange(1,30));
}
tmp.listOfElements = listOfElements;
mySet.add(tmp);
}
return mySet;
}
}
と
import java.util.ArrayList;
public class Set {
public String name;
public int id;
public ArrayList<Integer> listOfElements;
public Set(String name, int id) {
this.name = name;
this.id = id;
listOfElements = new ArrayList<Integer>();
}
}
バックトラックの考え方は非常に一般的であり、多くの問題に適用できます。ダンスリンクは正確なカバー問題にのみ適用できます。これを「通常の」バックトラッキング手法を使用して実装することは可能です(私は知っています、これはDLXと比較して遅くなります)。私の理解からは、以前の決定と矛盾があるかどうかを私たちに知らせる関数が必要です。これに加えて、異なるヒューリスティックを使用することができます。 – user26372
私は達成しようとしている別の発見的方法を使用しています。ちょうどイメージ、1セットまたは別のものを購入することはより安いです(ダンスリンクとは異なり、最小のコストで、最小の要素で1つのセットを選びません)。ダンスリンクを使ってこれを行うことはできません。 – user26372
@ user26372ダンスリンク*典型的には、ヒューリスティックな "最初に最も少ない列をチェックアウトする"(すなわち、最も難しい制約を最初に満たす行を試してみる)ヒューリスティックを使用しますが、そのようなものはありません。 [Cの私自身のダンスリンクの実装、こちら](http://www.club.cc.cmu.edu/~ajo/free-software/snippets/dance.c)を参照してください。 '#if USE_HEURISTIC'は異なるヒューリスティックを使用します。 – Quuxplusone