【发布时间】:2015-07-19 05:08:12
【问题描述】:
出于学习目的,我正在开发一个在现实生活中基本上可以像Quartz Composer 或最近的Vuo 一样工作的应用程序。 我正在基于核心数据框架构建节点图。
基本上我有一个 Node 实体与 Input 和 Output 实体有一对多关系(一个节点可以有多个输入和多个输出)。 Input 与 Connection 实体是一对一的关系,而 Output 与后者是一对多的关系(输入只能有一个连接,而一个输出可以有多个)。
为了阅读图表,我使用了拓扑排序算法(Kahn 的算法),描述为here。代码如下:
/**
* Get all nodes.
*/
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Node"];
NSMutableArray *nodes = [[[_document managedObjectContext] executeFetchRequest:request error:nil] mutableCopy];
/**
* Reset the nodes 'visited' flag.
*/
[self reset:nodes];
/**
* Get sources: predicate for nodes without input ports or with input ports without connections.
*/
[request setPredicate:[NSPredicate predicateWithFormat:@"inputs == nil OR ALL inputs.connection == nil"]];
NSMutableArray *sources = [[[_document managedObjectContext] executeFetchRequest:request error:nil] mutableCopy];
/**
* Perform a topological sort.
*/
while ([sources count] > 0) {
/**
* While there are sources.
*/
NSManagedObject *node = [sources lastObject];
/**
* Add the node to the tail of the final graph (NSMutableArray).
*/
[_graph addObject:node];
[node setValue:@([_graph count] - 1) forKey:@"kNodeExecutionIndex"];
[sources removeLastObject];
/**
* Outputs.
*/
NSMutableSet *outputs = [node valueForKey:@"outputs"];
for (NSManagedObject *output in outputs) {
/**
* Get output connections.
*/
NSMutableSet *connections = [output valueForKey:@"connections"];
for (NSManagedObject *connection in connections) {
/**
* Set the connection as already visited.
*/
[connection setValue:@(YES) forKey:@"kConnectionVisited"];
NSManagedObject *n = [[connection valueForKey:@"destination"] valueForKey:@"node"];
/**
* Set the 'source' flag to YES by default.
*/
BOOL isNewSource = YES;
/**
* Get connected inputs.
*/
NSMutableSet *inputs = [n valueForKey:@"inputs"];
for (NSManagedObject *input in inputs) {
/**
* Check if one of the input connections was visited.
* If not, then we need to process this connection and
* don't add it to sources for next pass.
*/
if ([[[input valueForKey:@"connection"] valueForKey:@"kConnectionVisited"] isEqualTo:@(NO)]) {
isNewSource = NO;
break;
}
}
if (isNewSource) {
[sources addObject:n];
}
}
}
}
如果可能的话,我试图了解我必须如何(以及在此代码中的位置)计算每个节点(因此每个输入)实体的可达性的逻辑。
我的问题是:
- 是否可以在卡恩算法中计算节点的可达性?
- 如果合适,在哪里以及如何做,所以我可以理解它为什么起作用?
谢谢。
【问题讨论】:
标签: objective-c algorithm core-data graph visual-programming