Algorithm 矩阵排序的所有解

Algorithm 矩阵排序的所有解,algorithm,sorting,Algorithm,Sorting,这个问题如下: 在上一个问题中,OP询问如何对矩阵进行排序,例如对行和列进行排序(M[i][j]这将是回溯生成的最有效解决方案,但是,由于有许多方法,我提出了以下算法(在伪C++中) int mat[n][m]={-1};//用-1初始化所有单元格 int sortedArray[n*m];//所有数字的排序数组,递增顺序 void generateAllSolutions(设置前端、整数深度){ 如果(深度==n*m){ printMatrix(); 返回; } 用于(成对单元:前){ mat

这个问题如下:


在上一个问题中,OP询问如何对矩阵进行排序,例如对行和列进行排序(M[i][j]这将是回溯生成的最有效解决方案,但是,由于有许多方法,我提出了以下算法(在伪C++中)

int mat[n][m]={-1};//用-1初始化所有单元格
int sortedArray[n*m];//所有数字的排序数组,递增顺序
void generateAllSolutions(设置前端、整数深度){
如果(深度==n*m){
printMatrix();
返回;
}
用于(成对单元:前){
mat[cell.first][cell.second]=sorteddarray[depth];
newFront=front;
newFront。移除(单元);
如果(第一个单元格
我所做的是保留所有可能候选下一个最小数字的单元格的“前端”。这些单元格基本上是所有的单元格,它们的左上邻域已经填充了较小的数字

由于我提出的算法可以优化,以使用所有解决方案中所有单元数量的操作,因此对于您的任务来说,这应该是最佳的可能解决方案性能


如果你只想计算所有可能的解决方案,我想知道是否有聪明的解决方案(我可以立即设计一个O级的解决方案(min(mn,nm))

这将是生成的最有效的解决方案,但是,由于有许多方法,我提出了以下算法(在伪C++中)

int mat[n][m]={-1};//用-1初始化所有单元格
int sortedArray[n*m];//所有数字的排序数组,递增顺序
void generateAllSolutions(设置前端、整数深度){
如果(深度==n*m){
printMatrix();
返回;
}
用于(成对单元:前){
mat[cell.first][cell.second]=sorteddarray[depth];
newFront=front;
newFront。移除(单元);
如果(第一个单元格
我所做的是保留所有可能候选下一个最小数字的单元格的“前端”。这些单元格基本上是所有的单元格,它们的左上邻域已经填充了较小的数字

由于我提出的算法可以优化,以使用所有解决方案中所有单元数量的操作,因此对于您的任务来说,这应该是最佳的可能解决方案性能


如果你只想计算所有可能的解,我想知道是否有聪明的解决方案(我可以立即设置一个O(min(mn,nm))量级的解)

一些修剪以改进回溯算法:

注意,例如在5*4排序矩阵M中

M[0][0]
是所有元素集
S
的最小值,
M[4][3]
是最大值

M[0][1]
M[1][0]
S-({M[0][0]}中的两个最小值∪{M[4][3]}
,而

M[3][3]
M[4][2]
是其中的两个最大值

只有2*2例


类似地,
M[1][1]
是最小值,
M[3][2]
S-{M[0][0]、M[4][3]、M[0][1]、M[1][0]、M[3][3]、M[4][2]}
中的最大值,这是确定的。

回溯算法改进的一些剪枝:

注意,例如在5*4排序矩阵M中

M[0][0]
是所有元素集
S
的最小值,
M[4][3]
是最大值

M[0][1]
M[1][0]
S-({M[0][0]}中的两个最小值∪{M[4][3]}
,而

M[3][3]
M[4][2]
是其中的两个最大值

只有2*2例


类似地,
M[1][1]
是最小值,
M[3][2]
S-{M[0][0]、M[4][3]、M[0][1]、M[1][0]、M[3][3]、M[4][2]中的最大值
,这是肯定的。

如果元素都是不同的,那么我相信您可以使用计算解决方案,但我不确定如何将其扩展到具有重复条目的情况。如果元素都是不同的,那么我相信您可以使用计算解决方案,但我不确定如何将其扩展到具有重复条目的情况e重复条目。
0 0 1 2 
2 2 3 3 
3 5 5 6 
6 6 6 6 
7 7 9 9 
0 2 3 6
0 2 5 6
1 3 5 6
2 3 6 6
7 7 9 9
0 2 3 6
0 2 5 6
1 3 5 7
2 3 6 7
6 6 9 9
0 2 3 6
0 2 5 6
1 3 5 7
2 3 6 9
6 6 7 9
int mat[n][m] = {-1}; // initialize all cells with -1
int sortedArray[n * m]; // the sorted array of all numbers, increasing order

void generateAllSolutions(set<pair<int, int> > front, int depth) {
    if (depth == n * m) {
        printMatrix();
        return;
    }

    for (pair<int, int> cell : front) {
         mat[cell.first][cell.second] = sortedArray[depth];
         newFront = front;
         newFront.remove(cell);
         if (cell.first < n - 1 &&
              (cell.second == 0 || mat[cell.first + 1][cell.second - 1] != -1)) {
             newFront.add(<cell.first + 1, cell.second>);
         }
         if (cell.second < m - 1 &&
              (cell.first == 0 || mat[cell.first - 1][cell.second + 1] != -1))
             newFront.add(<cell.first, cell.second + 1>);
         }
         generateAllSolutions(newFront, depth + 1);
         mat[cell.first][cell.second] = -1; // backing the track
    }
}

void solve() {
   set<pair<int, int> > front = {<0, 0>}; // front initialized to upper left cell
   generateAllSolutions(front, 0);
}