我正在为6-6-3模式数据库方法创建模式数据库来解决15个难题,我的代码很好地为3个tile生成所有可能的模式但是为6个tile花费了太多时间但是在生成之后崩溃了节点更少。到目前为止我的代码如下 -
-(void)createAndInsertPatterns{
FifteenPuzzle *startingPuzzle=[[FifteenPuzzle alloc]init];
startingPuzzle.pattern=[self getPatternString:startingPattern];
startingPuzzle.cost=0;
[self enqueue:startingPuzzle];
//[self insertIntoDB:startingPuzzle.pattern:0];
FifteenPuzzle* currentPuzzle;
while((currentPuzzle =[self dequeue])!=nil){
if(![self isAlreadyAdded:currentPuzzle.pattern]){
NSString *patternString=[NSString stringWithString:currentPuzzle.pattern];
NSInteger cost=currentPuzzle.cost;
[self insertIntoDB:currentPuzzle.pattern:cost];
NSMutableArray *allPatterns = [self allNeighborForPattern:[self getArrayFromString:patternString]];
for (NSMutableArray *obj in allPatterns) {
FifteenPuzzle *p=[[FifteenPuzzle alloc]init];
p.pattern=[self getPatternString:obj];
p.cost=cost+1;
[self enqueue:p];
}
}else{
//NSLog(@"Pattern already added");
}
}
}
-(void)insertIntoDB :(NSString*)patternString :(int)no_of_moves{
[patternQueue setObject:@"YES" forKey:patternString];
sqlite3_stmt *statement;
NSString *querySQL = [NSString stringWithFormat:@"insert into data values (\"%@\",\"%d\")",patternString,no_of_moves];
if(sqlite3_prepare_v2(database, [querySQL UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
}
if(sqlite3_step(statement) != SQLITE_DONE )
{
NSLog( @"Error: %s", sqlite3_errmsg(database) );
sqlite3_finalize(statement);
}else {
//NSLog(@"Query executed");;
}
sqlite3_reset(statement);
}
-(BOOL)isAlreadyAdded:(NSString*)patternString{
if ([[patternQueue objectForKey:patternString]isEqualToString:@"YES"])
return YES;
else
return NO;
}
-(void)enqueue:(FifteenPuzzle*)puzzle {
if(![self isAlreadyAdded:puzzle.pattern])
[queue addObject:puzzle];
}
-(FifteenPuzzle*)dequeue{
if (queue.count==0) {
return nil;
}
FifteenPuzzle *puzzle=[queue objectAtIndex:0];
[queue removeObjectAtIndex:0];
return puzzle;
}
-(NSMutableArray*)allNeighborForPattern :(NSMutableArray*)pattern{
NSMutableArray *allNeighborPatterns=[[NSMutableArray alloc]init];
for (int v=0; v<16;v++) {
int value=[[pattern objectAtIndex:v]intValue];
if (value==0)
continue;
int row=v/4;
int col=v%4;
if (col-1>=0) {//left
if ([[pattern objectAtIndex:v-1]intValue]==0) {
NSMutableArray *left=[[NSMutableArray alloc]initWithArray:pattern];
[left exchangeObjectAtIndex:v withObjectAtIndex:v-1];
if([patternQueue objectForKey:[self getPatternString:left]]==nil)
[allNeighborPatterns addObject:left];
}
}
if (col+1<4) {//right
if ([[pattern objectAtIndex:v+1]intValue]==0) {
NSMutableArray *right=[[NSMutableArray alloc]initWithArray:pattern];
[right exchangeObjectAtIndex:v withObjectAtIndex:v+1];
if([patternQueue objectForKey:[self getPatternString:right]]==nil)
[allNeighborPatterns addObject:right];
}
}
if (row-1>=0) {//top
if ([[pattern objectAtIndex:v-4]intValue]==0) {
NSMutableArray *top=[[NSMutableArray alloc]initWithArray:pattern];
[top exchangeObjectAtIndex:v withObjectAtIndex:v-4];
if([patternQueue objectForKey:[self getPatternString:top]]==nil)
[allNeighborPatterns addObject:top];
}
}
if (row+1<4) {//bottom
if ([[pattern objectAtIndex:v+4]intValue]==0) {
NSMutableArray *bottom=[[NSMutableArray alloc]initWithArray:pattern];
[bottom exchangeObjectAtIndex:v withObjectAtIndex:v+4];
if([patternQueue objectForKey:[self getPatternString:bottom]]==nil)
[allNeighborPatterns addObject:bottom];
}
}
}
return allNeighborPatterns;
}
其中patternQueue
用于保存已添加到数据库的所有模式,队列保存要扩展的模式。我正在使用广度优先搜索来扩展节点。一个6个磁贴组合数据库将容纳16!/(16-10)!= 5765760个模式(节点)但我的代码在生成较少的节点后崩溃,这些节点在5分钟内大约为200000个。
请建议可以提高速度或避免崩溃机会的变化。