高レベルのペトリネット エディター/シミュレーターを開発しています。最初に、ここで少し語彙を紹介します
円=場所
長方形 =トランジション
適切な整数 =トークン
遷移中の状態 =ガード
そして、私はトランジションのガードを通過することに行き詰まっています。Guard は、遷移を実行する場合に true にする必要がある条件です。どういうわけかバックトラッキングを使用する必要があることは知っていますが、プログラムの開始前にトランジションに入る場所の数がわからないため、必要なループの数がわからないため、for ループを使用できません。
これが問題を説明する写真です
したがって、1 位から最初のトークンを取得し、2 位から最初のトークンを取得し、ガードを通過した場合はパスし、トークンを保存し、ループを破り、false の場合は 2 位の 2 番目のトークンを続行します..など...最終的に、1 位の最後のトークン (4) と 2 位の最後のトークン (2) でガードをパスします。
これをコーディングする方法を知っているでしょう。遷移に入る場所の数が一定であれば、次のようになります
for token in place 1
for token in place 2
try pass guard
if (passed)
save tokens
break;
しかし、前に言ったように、トランジションに入る場所の数が一定ではないので、このアプローチは使用できません。したがって、基本的には、トークンの組み合わせを試して、ガードを通過するようにする必要があります-ガードを通過するまで、またはすべての組み合わせを試すまで。あなたはなにか考えはありますか ?擬似コードで十分です。ちなみに私はこれらのデータ構造を使用しています
場所のリスト - 通常の Java リスト、場所のリスト = new ArrayList();
各場所には独自のトークンのリストがあります。 List tokens = new ArrayList();
///編集: ガードの形式は次のとおりです。
op1 rel op2、op1 は変数、op2 は定数または変数、rel は関係 (<、>、=、... ) op3 rel op4 ...
- - 編集:
だから私はRushilアルゴリズムを実装しようとしましたが、それはかなりバグが多いので、SSCCEを投稿して試してみて、少し助けてください。
まず、Place クラスを作成します。
public class Place {
public List<Integer> tokens ;
//constructor
public Place() {
this.tokens = new ArrayList<Integer>();
}
}
そして、クラスをテストします:
public class TestyParmutace {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
List<Place> places = new ArrayList<Place>();
Place place1 = new Place();
place1.tokens.add(1);
place1.tokens.add(2);
place1.tokens.add(3);
places.add(place1); //add place to the list
Place place2 = new Place();
place2.tokens.add(3);
place2.tokens.add(4);
place2.tokens.add(5);
places.add(place2); //add place to the list
Place place3 = new Place();
place3.tokens.add(6);
place3.tokens.add(7);
place3.tokens.add(8);
places.add(place3); //add place to the list
//so we have
//P1 = {1,2,3}
//P2 = {3,4,5}
//P3 = {6,7,8}
List<Integer> tokens = new ArrayList<Integer>();
Func(places,0,tokens);
}
/**
*
* @param places list of places
* @param index index of current place
* @param tokens list of tokens
* @return true if we passed guard, false if we did not
*/
public static boolean Func( List<Place> places, int index, List<Integer> tokens)
{
if (index >= places.size())
{
// if control reaches here, it means that we've recursed through a particular combination
// ( consisting of exactly 1 token from each place ), and there are no more "places" left
String outputTokens = "";
for (int i = 0; i< tokens.size(); i++) {
outputTokens+= tokens.get(i) +",";
}
System.out.println("Tokens: "+outputTokens);
if (tokens.get(0) == 4 && tokens.get(1) == 5 && tokens.get(2) == 10) {
System.out.println("we passed the guard with 3,5,8");
return true;
}
else {
tokens.remove(tokens.get(tokens.size()-1));
return false;
}
}
Place p = places.get(index);
for (int i = 0; i< p.tokens.size(); i++)
{
tokens.add(p.tokens.get(i));
//System.out.println("Pridali sme token:" + p.tokens.get(i));
if ( Func( places, index+1, tokens ) ) return true;
}
if (tokens.size()>0)
tokens.remove(tokens.get(tokens.size()-1));
return false;
}
}
このコードの出力は次のとおりです。
Tokens: 1,3,6,
Tokens: 1,3,7,
Tokens: 1,3,8,
Tokens: 3,4,6,
Tokens: 3,4,7,
Tokens: 3,4,8,
Tokens: 4,5,6,
Tokens: 4,5,7,
Tokens: 4,5,8,
Tokens: 2,3,6,
Tokens: 2,3,7,
Tokens: 2,3,8,
Tokens: 3,4,6,
Tokens: 3,4,7,
Tokens: 3,4,8,
Tokens: 4,5,6,
Tokens: 4,5,7,
Tokens: 4,5,8,
Tokens: 3,3,6,
Tokens: 3,3,7,
Tokens: 3,3,8,
Tokens: 3,4,6,
Tokens: 3,4,7,
Tokens: 3,4,8,
Tokens: 4,5,6,
Tokens: 4,5,7,
Tokens: 4,5,8,
ですから、1,3,6 や 1,3,7 のようにいくつかの組み合わせは正しいのですが、4,5,8 はまったくナンセンスです。完全に欠落している組み合わせもあります..2、4、6などのように...誰もがなぜこのようになっているのか分かりますか?
編集:今では正常に動作しています。