拉丁矩阵问题 利用回溯法的C++实现方案

Posted 枯萎的海风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拉丁矩阵问题 利用回溯法的C++实现方案相关的知识,希望对你有一定的参考价值。

这两天正好在赶算法设计的作业,这里把做的几个需要写代码的题放上来,方便以后查看。
1.题目要求

2.算法思想
这个题目基本思想是 利用回溯法,对于 m 行 n 列, 本质上就是一个二维数组, 我们可以将问题的解写成 x[1],x[2],x[3] … x[m*n], 那么对于每个点 x[i] 的取值实际上是 [1, n], 套用回溯法的算法框架,这里的 约束条件 ,就是同行,同列 没有相同的取值, 并且这里没有优化目标,只要类似 N后问题找出所有解就可以了。

另外,回溯时候的边界条件,需要特别注意一下,由于我们把二维数组当作一维数组进行实现, 下标从 0 开始, 理论上到 m*n-1就应该结束了,一开始没怎么注意,导致调试了好久 *23333333333*

3.算法实现源码:

3.1 LatiMatrix.h

// -------------------------【chp 5 HW 拉丁矩阵 宝石排列 】----------------------
// @ author         :       zhyh2010
// @ date           :       20150524
// @ version        :       1.0
// @ description    :       有n种不同形状的宝石,每种都足够多,现要求将他们排列成
//                      m行 n 列 的矩阵 (m <= n) 使每行,每列 中的宝石形状不同
//                      求, 给定 m,n 时候有多少种算法
// @ idea           :       回溯法
// -----------------------------------【end tip】-------------------------------

#pragma once
class CLatiMatrix

public:
    CLatiMatrix();
    ~CLatiMatrix();

    int solve();

private:
    void BackTrace(int id);
    void output();
    bool isOK(int row, int col);

    void ReadFile();
    void WriteFile();

private:
    int m_m;
    int m_n;
    int ** m_matrix;

    int m_solution_num;
;

3.2.LatiMatrix.cpp

#include "LatiMatrix.h"
#include <cstdio>
#include <cstdlib>
#include <fstream>


CLatiMatrix::CLatiMatrix()

    m_m = 0;
    m_n = 0;
    m_matrix = NULL;

    m_solution_num = 0;



CLatiMatrix::~CLatiMatrix()

    for (int i = 0; i != m_n; i++)
    
        if (m_matrix[i])
            delete m_matrix[i];
    

    if (m_matrix)
        delete [] m_matrix;


void CLatiMatrix::BackTrace(int id)

    // ===============【这里一开始写的时候没有加 = 号 导致出问题】=================
    if (id >= m_m * m_n)
    
        output();
        return;
    

    int row = id / m_n;
    int col = id % m_n;

    for (int k = 0; k != m_n; k++)
           
        m_matrix[row][col] = k;

        if (isOK(row, col))
        
            id++;
            BackTrace(id);
            id--;
        
    


void CLatiMatrix::output()

    m_solution_num++;


bool CLatiMatrix::isOK(int row, int col)

    int k = m_matrix[row][col];

    for (int i = 0; i != col; i++)
        if (k == m_matrix[row][i])
            return false;

    for (int i = 0; i != row; i++)
        if (k == m_matrix[i][col])
            return false;

    return true;


void CLatiMatrix::ReadFile()

    std::ifstream infile("input.txt");
    infile >> m_m >> m_n;

    m_matrix = new int *[m_m];
    for (int i = 0; i != m_n; i++)
    
        m_matrix[i] = new int[m_n];
        memset(m_matrix[i], 0, sizeof(m_matrix[i]));
    


void CLatiMatrix::WriteFile()

    std::ofstream outfile("output.txt");
    outfile << m_solution_num << std::endl;


int CLatiMatrix::solve()

    ReadFile();

    BackTrace(0);

    WriteFile();

    return m_solution_num;

3.3.Main.cpp

// -------------------------【chp 5 HW 拉丁矩阵 宝石排列】----------------------
// @ author         :       zhyh2010
// @ date           :       20150524
// @ version        :       1.0
// @ description    :       有n种不同形状的宝石,每种都足够多,现要求将他们排列成
//                      m行 n 列 的矩阵 (m <= n) 使每行,每列 中的宝石形状不同
//                      求, 给定 m,n 时候有多少种算法
// @ idea           :       回溯法
// -----------------------------------【end tip】-------------------------------

#include "LatiMatrix.h"
#include <iostream>

void main()

    CLatiMatrix instance;
    int res = instance.solve();
    std::cout << "res = " << res << std::endl;

以上是关于拉丁矩阵问题 利用回溯法的C++实现方案的主要内容,如果未能解决你的问题,请参考以下文章

回溯法

回溯法

c++利用邻接矩阵存储方法实现图的存储与输出。

C++ 回溯排列

牛顿法与拟牛顿法的区别与联系

回溯法