ios - 在无向图中查找所有非重叠循环

标签 ios objective-c algorithm graph cycle

我需要在无向图上找到所有简单的非重叠循环。为了找到所有现有的循环,我制作了我在此处找到的算法的 Objective-C 版本:

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;
}

上述算法工作正常(即使它不是很有效)并且它从附图上的图中找到所有可能的循环(请参见下图):

A-B-H-G-F-D-E-A(有效)

B-C-I-H-B(有效)

G-H-I-L-K-G(有效)

F-G-K-J-F(有效)

F-G-H-I-L-K-J-F(无效)

A-B-C-I-H-G-F-D-E-A(无效)

A-B-C-I-L-K-J-F-D-E-A(无效)

A-B-C-I-H-G--K-J-F-D-E-A(无效)

A-B-H-I-L-K-G-F-D-E-A(无效)

A-B-H-G-K-J-F-D-E-A(无效)

A-B-C-I-L-K-G-F-D-E-A(无效)

B-C-I-L-K-G-H-B(无效)

B-C-I-L-K-J-F-G-H-B(无效)

但是,当我运行上述算法时,我只想得到在左侧示例中用彩色多边形突出显示的那些循环。我不想要的是右侧示例中的循环。

enter image description here

我的第一个想法是重叠循环将是一个包含任何其他循环的所有点的循环,但这并不总是正确的。有人能指出我正确的方向吗?是否可以修改上述算法,使其仅找到非重叠循环,或者如果不能,在找到所有循环以过滤它们后我应该做什么?

最佳答案

仅在无向图中本身没有足够的信息来确定哪些循环是哪些。例如,考虑以下 2 个图产生相同的无向图:

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

但对于左图,您需要循环 ABDCA 和 CDFEC,而对于右图,您需要循环 ABDCA 和 EFDBACE。因此,从图表中推断出的无向图是不够的——您需要以某种方式合并来自原始图表的空间信息。

关于ios - 在无向图中查找所有非重叠循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37987356/

相关文章:

objective-c - 如何检查地址簿中特定用户的电话号码是否存在

ios - 截取屏幕截图然后将其发布到 Twitter,不保存。 iOS

iphone - iPhone 导航栏神秘失灵!

c++ - 在 C++ 的 cmd 中显示 Pascal 的三角形

javascript - 我需要有关此回文代码的帮助

jquery - UIWebview 在 jquery 部分不滚动

objective-c - 如何使用 Objective C 在 OSX 上实现分布式对象?

ios - 使用应用程序上下文从 iPhone 向 WatchOS 发送数据时遇到问题

ios - 如何在 Objective-C 中将对象类型转换为另一个类

c# - .NET 几何库