Как быстро и безопасно создать базу данных шаблонов для 6 плиток для подхода 663, чтобы решить 15 головоломок?
Я создаю базы данных шаблонов для подхода 6-6-3 базы данных шаблонов, чтобы решить 15 задач, мой код хорошо работает для генерации всех возможных шаблонов для 3 плиток, но занимает слишком много времени для 6 плиток, но между ними происходит сбой после генерации меньшего количества узлов. Мой код до сих пор, как показано ниже
-(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 шаблонов (узлов), но мой код вылетает после генерации меньшего количества узлов, которые примерно равны 200000 за 5 минут.
Пожалуйста, предложите изменения, которые могут увеличить скорость или избежать аварий.