回溯法求解拉丁矩阵问题

问题描述:

  如图所示,一个4阶Latin方是一个4X4的方格,在它的每个方格内填入1,2,3或4,并使得每个数字在每行、每列都恰好出现一次。用回溯法求出所有第一行为1,2,3,4的所有4阶Latin方。将每个解的第2行到第4行的数字从左到右写成一个序列。如图中的解是<3,4,1,2,4,3,2,1,2,1,4,3>。

1 2 3 4
3 4 1 2
4 3 2 1
2 1 4 3

  

  本打算随便弄几行代码应付上去,没想到最后给编出来了。回溯算法思想以及实现过程都不是太难。

  个人觉得比较重要的部分是递归函数中的for循环,即分别对每个小格每种颜色都做一次尝试,成功就尝试下一个格,否则就换一种颜色,再不行(即这一个格不能涂上合适的颜色)就直接退出递归程序,回到上一层递归。

程序清单:

#include<iostream>

#define MAX 4

using std::cin;
using std::cout;
using std::endl;

bool LatinCheck(int x[MAX][MAX],int k,int row,int line)
{
    for(int i=0;i<row;i++)
        if(x[i][line] == k) return false;
    for(int i=0;i<line;i++)
        if(x[row][i] == k) return false;
    return true;
}

void LatinMartix(int x[MAX][MAX],int row,int line)
{
    if((row==4)&&(line==4)) return;
    for(int color=0;color<4;color++)
    {
        if(LatinCheck(x,color,row,line))
        {
            x[row][line] = color;
            if(line<3) LatinMartix(x,row,line+1);
            else if((line == 3)&&(row!=3)) LatinMartix(x,row+1,0);
        }
    }
    if((line==3)&&(row==3))
    {
        for(int i=0;i<4;i++)
        {
            for(int j=0;j<4;j++)
            {
                cout << x[i][j]+1 << " ";
            }
        }
        cout << endl;
        return;
    }
}

int main()
{
    int x[MAX][MAX]={0,1,2,3};
    LatinMartix(x,1,0);

    return 0;
}
时间: 2024-10-11 06:39:50

回溯法求解拉丁矩阵问题的相关文章

利用回溯法求解背包问题

最近看完了利用回溯法求八皇后问题,最后成功求解到92种解法,然后在看利用贪心求解背包问题,突然想到其实也可以利用回溯法求解背包问题,本质上回溯法是一个穷举的方式在求. 回溯法求解出的结果肯定是正确的,这也可以验证自己所写的贪心算法的正确性. 问题描诉: 设定Wmax为最大重量,W[](0~n-1)为编号0~n-1的货物重量,V[](0~n-1)为其价值,x[]为其中解, 在wn=ΣXi*Wi<Wmax的条件下,求Vmax=ΣXi*Vi. 代码如下: //全局变量最大价值int maxvalue=

回溯法求解数独算法(C语言)

没有对输入的待解数独进行一般性验证(同一行.一列以及同一个小九宫格都不能出现重复数字) 算法利用回溯的思想: 从第一个空白处开始,找到其候选解(排除同行.同列以及同一小九宫格的所有出现过的数字,剩下未出现的数字都是候选解)的第一个值填入数独. 对第二个空白执行第一步(前面所填入的数字对此空白处有影响). 当出现某个空白的候选解个数为0时,就开始回溯,找到第一个候选解多于一个的,将其在使用的候选解设为不可取(本程序取值为-1),找到其下一个候选解,继续上面的步骤! 直到所有空白处填满,运算完成,输

回溯法——求解0-1背包问题

以前研究过一个简单的N皇后问题,对回溯法也有了个模糊的认识,大致理解就是:先一直做某件事,当完成某个条件时或者是触犯某个条件时,再返回到最近的一个类似还原点的地方. 在用回溯法求解0-1背包问题的时候,主要遇到三个相对难解决的问题:1,什么是界限函数:2,什么时候用它:3,回溯到哪儿. 什么是界限函数? 如下图: 当我们身在一棵搜索空间树中,站在一个K点举棋不定的时候,我们可以用它估算如果我们继续向下走,我们走完本段路会获得的总价值.假设我们现在有一个最大解,当我用界限函数算出一个价值后和我当前

回溯法求解N皇后问题

问题描述: 在n*n格的棋盘上放置彼此不受攻击的n个皇后(按照国际象棋的规则),即任意两个皇后不能处在同一行或同一列或同一斜线上. 实现: /* *回溯法,N皇后问题 *author: [email protected] */ #include <iostream> #include <vector> #include <cmath> using namespace std; struct Point{ Point(int _x, int _y): x(_x), y(_

回溯法求解八皇后问题---(初步、未优化)

首先介绍一下回溯算法: 定义来自<百度百科>......名字着很高大上,实际上就是试探法,逐步试错找到最终的可行解. 重要的一点是解空间通常是在搜索可行解过程中动态产生的,所以程序中通常利用到递归的算法,如后面介绍的八皇后问题.这点区别与于前段时间所写的模拟退火算法,模拟退火是首先确定解空间,然后以一定的概率接受当前发现的次优解,从而有更大的可能避免局部最优而得到全局最优. 简单介绍一下八皇后问题: 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或

回溯法——求解N皇后问题

问题描述 八皇后问题是十九世纪著名数学家高斯于1850年提出的.问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上.可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行.同一列或同一斜线上. 问题分析 我们以最简单的4皇后问题分析,显然,为了使皇后不相互攻击,首先考虑每一行只能放一个皇后,我们以X[1,2,3-.N]代表此问题的解数组,X[N]代表在第N行第X[N]列放了一个皇后,例如,X[2

迷宫问题(MazePath)的求解——利用回溯法(backtracking)

迷宫问题(MazePath)的求解--利用回溯法(backtracking) 1. 迷宫问题的提法 迷宫问题是典型的图的搜索问题. 假设一个迷宫,只有一个入口和一个出口.如果从迷宫的入口到达出口,途中不出现行进方向错误,则得到一条最佳路线. 为此,用一个二维数组maze[m][p]来表示迷宫. (1)当数组元素maze[i][j]=1 (0≤i≤m-1,1≤j≤p-1),表示该位置是墙壁,不能通行. (2)当数组元素maze[i][j]=0 (0≤i≤m-1,1≤j≤p-1),表示该位置是通路,

回溯法求迷宫问题

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”.本文使用回溯法求解迷宫问题迷宫问题,有一个m行n列的矩阵代表迷宫,1代表此路不通,0代表此路通.指定入口和出口,判断是否能从入口进,从出口走出.此程序只判断从路口到出口是否能走通,找到的路不一定是最短路(最短路的程序在下一篇中使用BFS算法给出),注意:从入口到

回溯法 -数据结构与算法

1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能性.即避免不必要的搜索.这种方