作业-蒙特卡罗-判断矩阵互逆

蒙特卡罗-判断矩阵互逆

题目描述

给定 \(2\)\(n×n\)矩阵 \(A\)\(B\), 试设计一个判定 \(A\)\(B\) 是否互逆的蒙特卡罗算法, 算法的计算时间应为 \(O(n^2)\). 设计一个蒙特卡罗算法, 对于给定的矩阵 \(A\)\(B\), 判定其是否互逆.

Input:

输入的第一行有 \(1\) 个正整数 \(n\), 表示矩阵 \(A\)\(B\)\(n×n\) 矩阵. 接下来的 \(2n\) 行, 每行有 \(n\) 个实数, 分别表示矩阵 \(A\)\(B\) 中的元素.

Output:

矩阵 \(A\)\(B\) 互逆则输出 YES, 否则输出 NO

Sample Input:

3
1 2 3
2 2 3
3 3 3

-1 1 0
1 -2 1
0 1 -0.666667

Sample Output:

YES

题解

首先根据矩阵互逆定义知道:

\[AB = I \]

也就是两个矩阵相乘为单位矩阵, 单位矩阵特点就是对角线元素为 \(1\), 其他未知元素为 \(0\) ; 根据这个特点, 我们设计蒙特卡罗算法, 随机选取矩阵的 \(A\) 的第 \(J\) 行, 随机选取矩阵 \(B\) 的第 \(K\) 列, 对应元素相乘并进行累加 \(ans = A_{J1}\times B_{1k} + A_{J2} \times B_{2k} + ... + A_{JN} \times B_{Nk}\), 如果 \(J==k\), 则表示对角线上元素为 \(1\), 即判断 \(ans\) 是否为 \(1\); 如果 \(J!=K\) , 判断 \(ans\) 是否为 \(0\).

CODE

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;

double A[maxn][maxn], B[maxn][maxn];
int main()
{
    srand(time(NULL));
    int n; cin >> n;
    for(int i = 1; i <= n; i++) 
    {
        for(int j = 1; j <= n; j++) cin >> A[i][j];
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++) cin >> B[i][j];
    }
    int flag = 0;
    for(int i = 1; i <= n; i++)
    {
        int  J = rand() % n + 1, K = rand() % n + 1; // 蒙特卡罗随机选择
        double cur = 0;
        for(int j = 1; j <= n; j++)
        {
            cur += (A[J][j] * B[j][K]);
        }
        if(J == K)
        {
            if(cur - 1 <= 1e-6) continue;
            else flag = 1;
        }
        else
        {
            if(cur <= 1e-6) continue;
            else flag = 1;
        } 
    }
    if(flag) cout << "NO" << endl;
    else cout << "YES" << endl;
    return 0;
}

posted @ 2022-01-05 10:36  owo_owo  阅读(620)  评论(1编辑  收藏  举报