【问题标题】:2D matrix traverse - optimal path memorization2D 矩阵遍历 - 最佳路径记忆
【发布时间】:2013-05-31 18:29:49
【问题描述】:

我有一个函数用于在 2D 矩阵(整数、值和总和的结构)中找到最佳路径,但它不会记住最佳值,它只会返回遍历的最小成本到矩阵的底部。我们应该使用堆栈以某种方式记住这些最佳值,但不幸的是我不知道如何做到这一点。它是一种递归算法,因此很难分析。值用伪随机数(1 到 10)填充,总和初始化为 INT_MAX。这似乎有点类似于三叉树。

堆栈函数原型是:

stack_t stack_new(); // already done in main
void stack_delete(stack_t stack); // -||-
void stack_push(stack_t stack, stack_element_t elem);
stack_element_t stack_pop(stack_t stack);
stack_element_t stack_top(stack_t stack);
int stack_is_empty(stack_t stack);

/* recursively seeks the optimal path in a 2D matrix */

void traverse(struct path **matrix, unsigned row, unsigned col, int path_cost, int *min_cost, int *cnt, stack_t stack, FILE *f)
{
    char buffer[16];
    path_cost += matrix[row][col].value;
    matrix[row][col].sum = path_cost;
    (*cnt)++; // counting calls
    fprintf(f, "call_counter: %d, min_cost: %s, path_cost: %d, value: %d, sum: %d\n", *cnt, *min_cost == INT_MAX ? "Inf" : itoa(*min_cost, buffer, 10), path_cost, matrix[row][col].value, matrix[row][col].sum); // logging
    if(matrix[row][col].sum > *min_cost) // if we've been here before and it wasn't as costly, return
    {
        return;
    }
    if(row == MATRIX_ROW - 1) // if we're at the bottom of the matrix
    {
        if(path_cost < *min_cost)
        {
            *min_cost = path_cost;
        }
        return;
    }
    if (col < MATRIX_COL - 1) // go down and right
        traverse(matrix, row + 1, col + 1, path_cost, min_cost, cnt, stack, f);

    traverse(matrix, row + 1, col, path_cost, min_cost, cnt, stack, f); // go down

    if (col > 0) // go down and left
        traverse(matrix, row + 1, col - 1, path_cost, min_cost, cnt, stack, f);
}

【问题讨论】:

    标签: c matrix stack traversal


    【解决方案1】:

    您可以使用两个堆栈查找路径。 一个是临时堆栈,另一个是 ANSWER 堆栈。

    基本思想是,当你移动时,你将你进入的方向推入堆栈。同样在那个特定移动的“函数调用 ()”之后,你 pop() 那个方向.那么,到达底部的步骤,如果满足以下条件:

    if(path_cost < *min_cost)
    {
      *min_cost = path_cost;
    }
    

    您清空 Answer stack ,并将 Temporary stack 的内容复制到其中。

    stack answer ;
    stack temporary;
    
    /* recursively seeks the optimal path in a 2D matrix */
    
    
    
    void traverse(struct path **matrix, unsigned row, unsigned col, int path_cost, int *min_cost, int *cnt, stack_t stack, FILE *f)
    {
        char buffer[16];
        path_cost += matrix[row][col].value;
        matrix[row][col].sum = path_cost;
        (*cnt)++; // counting calls
        fprintf(f, "call_counter: %d, min_cost: %s, path_cost: %d, value: %d, sum: %d\n", *cnt, *min_cost == INT_MAX ? "Inf" : itoa(*min_cost, buffer, 10), path_cost, matrix[row][col].value, matrix[row][col].sum); // logging
        if(matrix[row][col].sum > *min_cost) // if we've been here before and it wasn't as costly, return
        {
            return;
        }
        if(row == MATRIX_ROW - 1) // if we're at the bottom of the matrix
        {
            if(path_cost < *min_cost)
            {
                *min_cost = path_cost;
                
                /*
                
                just empyty teh Answer stack here;
                then copy the Temp stack into answer stack
                
                */
                
            }
            return;
        }
        
        // 1 for (row +1 ,col +1 )
        // 2 for (row +1 ,col )
        // 3 for (row +1 ,col -1 )
        
        if (col < MATRIX_COL - 1) // go down and right
        {
            temporary.push(1);
            traverse(matrix, row + 1, col + 1, path_cost, min_cost, cnt, stack, f);
            temporary.pop(1);
        }
        
        temporary.push(2);  
        traverse(matrix, row + 1, col, path_cost, min_cost, cnt, stack, f); // go down
        temporary.pop(2);
        
        if (col > 0) // go down and left
        {
            temporary.push(3);      
           traverse(matrix, row + 1, col - 1, path_cost, min_cost, cnt, stack, f);
           temporary.pop(3);
        }
    }
    

    编辑:

    pop() 和 push() 来自临时堆栈。每次找到“潜在”解决方案时都会更新答案堆栈。另外我没有时间进行参数传递。临时堆栈“必须”是本地的。根据需要使用答案堆栈。

    【讨论】:

    • 我不确定我是否遵循这一点 - 我应该在移动时弹出哪个堆栈?它们是否应该像您预期的那样在全球范围内可见?我已经传递给函数的那个​​呢?请澄清。
    • 由于您正在迭代所有可能的解决方案,我们尝试做的是保留我们在当前递归调用跟踪中“遇到”的元素的堆栈。
    • Push() - 表示当前元素记录在我们的路径中。如果它是最佳路径的组成部分,它将保留在该堆栈中,直到调用结束。
    • Pop() - 函数调用完成后,当前方向,如果需要(即最优),将在到达底部时记录在答案堆栈中。现在如果我们不 pop()访问了方向,而不是 push() 其他方向,从技术上讲,这将意味着在一步中,我们采取了 2 条路径,我希望你理解是错误的!
    • 如果您仍然遇到问题,请给我评论一个指向您实施的最终解决方案的链接。
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多