Как быстро и безопасно создать базу данных шаблонов для 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 минут.

Пожалуйста, предложите изменения, которые могут увеличить скорость или избежать аварий.

0 ответов

Другие вопросы по тегам