2016-06-23 12 views
3

無向グラフ上の単純な重複していないサイクルをすべて見つける必要があります。アルゴリズムの上無向グラフのすべての重複していないサイクルの検索

Finding all cycles in undirected graphs

@interface HSValue : NSObject 
@property (nonatomic, assign) CGPoint point; 
@end 
@implementation HSValue 
@end 


@interface CyclesFinder() 
@property (nonatomic, strong) NSMutableArray <NSArray<HSValue *>*> *cycles; 
@property (nonatomic, strong) NSArray <NSArray<HSValue*>*> *edges; 
@end 

@implementation CyclesFinder 

-(void)findCyclesInGraph:(NSArray <NSArray<HSValue*>*> *)edges { 
    self.edges = edges; 
    for (NSInteger i=0; i < self.edges.count; i++) { 
     for (NSInteger j=0; j < self.edges[i].count; j++) { 
      [self findNewCycles:@[self.edges[i][j]]]; 
     } 
    } 
} 

-(void)findNewCycles:(NSArray <HSValue *> *)path { 

    HSValue *startNode = path[0]; 
    HSValue *nextNode; 
    NSArray <HSValue *> *sub; 

    for (NSInteger i=0; i < self.edges.count; i++) { 
     NSArray <HSValue *> *edge = self.edges[i]; 
     if ([edge containsObject:startNode]) { 
      if ([edge[0] isEqual:startNode]) { 
       nextNode = edge[1]; 
      } 
      else { 
       nextNode = edge[0]; 
      } 
     } 
     else { 
      nextNode = nil; 
     } 

     if (![path containsObject:nextNode] && nextNode) { 
      sub = @[nextNode]; 
      sub = [sub arrayByAddingObjectsFromArray:path]; 
      [self findNewCycles:sub]; 
     } 
     else if (path.count > 2 && [nextNode isEqual:path.lastObject]) { 
      if (![self cycleExist:path]) { 
       [self.cycles addObject:path]; 
       break; 
      } 
     } 
    } 
} 

-(BOOL)cycleExist:(NSArray <HSValue*> *)path { 
    path = [path sortedArrayUsingSelector:@selector(compare:)]; 
    for (NSInteger i=0; i < self.cycles.count; i++) { 
     NSArray <HSValue *> *cycle = [self.cycles[i] sortedArrayUsingSelector:@selector(compare:)]; 
     if ([cycle isEqualToArray:path]) { 
      return TRUE; 
     } 
    } 

    return FALSE; 
} 

正常に動作します(それは非常に効率的でない場合であっても)、それがすべて見つかった:私はここで見つけるアルゴリズムのObjective-Cのバージョンが作られた既存のすべてのサイクルを検索するには添付画像上のグラフから可能なサイクル(下図を参照してください):

ABHGFDEA(有効)

BCIHB(有効)

(有効)

FGKJF(有効)

GHILKG

FGHILKJF(無効)

ABCIHGFDEA(無効)(無効)

ABCIHG

ABCILKJFDEA - KJFDEA(無効)

ABHILKGFDEA(無効)

ABHGKJFDEA(無効)

ABCILKGFDEA(無効)

BCILKGHB(無効)

BCILKJFGHB(無効)しかし、私は上記のアルゴリズムを実行したとき、私はのみで終わるしたい

私が色のついたポリゴンで強調表示したサイクルを左側の例に示します。私が望まないのは、右側の例のようなサイクルです。

enter image description here

私が最初に考えたのは、サイクルを重ねることは、他のサイクルからのすべての点を含んサイクルになるということでしたが、これは常に真ではありません。誰かが私を正しい方向に向けることができますか?上記のアルゴリズムを変更して、重複していないサイクルだけを見つけることができますか、またはそれらをフィルタリングするためにすべてのサイクルを見つけた後に何をすべきですか?

+0

私は2つの数字の間に表示される唯一の違いは色です。それらについて有効で無効なものを説明できますか? – Avi

+0

色はグラフ上のサイクルを表します。したがって、私はそれが(F-G-K-J-F)と(G-H-I-L-K-J-F)と重なり合って除去したいサイクル(F-G-H-I-L-K-J-F)の1つを強調しています。左の写真の色は私が最終的に目指すすべてのサイクルを表しています。 – Guferos

+0

私はその情報を質問に追加すべきだと思います。 – Avi

答えて

2

どのサイクルがどれであるかを判断するには、無向グラフ自体の情報が不足しています。たとえば、以下の2つの図は、同一の無向グラフが得られることを考慮してください。

A-----B  E-------------F 
|  |  \   /
C-----D  \ A-----B/
|  |   \|  |/ 
E-----F   C-----D 

しかし、右図のために、あなたはサイクルをしたいしながら、左図のために、あなたは、サイクルABDCAとCDFECをしたいABDCAおよびEFDBACE。したがって、ダイアグラムから推測された無向グラフは十分ではありません。元のダイアグラムの空間情報を何らかの形で組み込む必要があります。

+0

実際に私のグラフ上のノードは私のアプリのデカルト平面上の点です。したがって、私は平面上の各点の座標を持っています。これらの座標を使用して、重複するサイクルを排除することはできますか? – Guferos

+0

ダイアグラムにエッジ交差がなく、次数1の頂点がない場合、グラフの各エッジには、それぞれの側に1つずつ境界がある厳密に2つの異なる領域が存在する必要があると考えます( "外側"を領域あまりにも)。各領域iについて、領域iを2つの辺のうちの1つに持つすべての辺をまとめて収集する - これらの辺は、サイクル境界領域を構成する必要があります(ある順序で)私。 ... –

+0

...しかし、どのようにこれらの領域を特定するのですか?よりエレガントな方法があると確信していますが、1つの方法は、図のビットマップを作成し、白いピクセルを繰り返し探すことです。見つかったら、そのポイントからフラッドフィルを開始し、この洪水フィルのエッジはどちらのエッジに接触します。 –

0

私はこの同じ問題に取り組んでいます。多くのご意見、特にすべてのエッジには両面に領域があるというコメントが役に立ちました。したがって、各エッジには「左領域」と「右領域」があると言えます。

すべてのグラフのエッジを任意の順序でキューに追加できます。最初のエッジを見て、その頂点を原点に近づけます。最も反時計回りの隣に移動します。開始頂点に達するまでこれを続けます。これらのエッジのすべてが最初の領域に繋がっています。私はそれに一意のIDを与え、それらのエッジの「左領域」プロパティに割り当てます。

キューの最初のエッジをピークし、「左側の領域」があるかどうかを確認します。それが時計回りに進まず、正しい領域を見つけたら「正しい領域」を持っているかどうかをチェックします。両方の領域にデキューが割り当てられている場合は、次の領域を取得します。

はO(e + v)にする必要があります。

これは意識の少し流れですが、私はそれを書き留めたいと思いました。私は私の実際のアプリのアルゴリズムを書いているだろうし、私はそれに問題を見つけるように微調整を行います。

もちろん、私はフィードバックや提案に公開しています:)

関連する問題