给定三个矩阵A,B和C,确定C是否为A和B的乘积。
例子:
Input : A = 1 1
1 1
B = 1 1
1 1
C = 2 2
2 2
Output : Yes
C = A x B
Input : A = 1 1 1
1 1 1
1 1 1
B = 1 1 1
1 1 1
1 1 1
C = 3 3 3
3 1 2
3 3 3
Output : No
一个简单的解决方案是找到A和B的乘积,然后检查乘积是否等于C。使用应力矩阵乘法,此方法可能的时间复杂度为O(n 2.8874 )。
Freivalds算法是一种概率随机算法,它在时间O(n 2 )上具有很高的概率。在O(kn 2 )时间中,该算法可以验证失败概率小于2 -k的矩阵乘积。由于输出并不总是正确的,因此它是蒙特卡洛随机算法。
脚步 :
- 生成一个n×1随机0/1向量r⃗ 。
- 计算P⃗= A×(Br)⃗–Cr⃗ 。
- 如果P⃗=(0,0,…,0) T则返回true,否则返回false。
这个想法基于这样一个事实,即如果C实际上是一个乘积,则A×(Br)⃗–Cr⃗的值将始终为0。如果该值不为零,则C不能为乘积。错误条件是即使C不是乘积,该值也可能为0。
下面是上述方法的实现:
C++
// CPP code to implement Freivald’s Algorithm
#include
using namespace std;
#define N 2
// Function to check if ABx = Cx
int freivald(int a[][N], int b[][N], int c[][N])
{
// Generate a random vector
bool r[N];
for (int i = 0; i < N; i++)
r[i] = random() % 2;
// Now comput B*r for evaluating
// expression A * (B*r) - (C*r)
int br[N] = { 0 };
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
br[i] = br[i] + b[i][j] * r[j];
// Now comput C*r for evaluating
// expression A * (B*r) - (C*r)
int cr[N] = { 0 };
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
cr[i] = cr[i] + c[i][j] * r[j];
// Now comput A* (B*r) for evaluating
// expression A * (B*r) - (C*r)
int axbr[N] = { 0 };
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
axbr[i] = axbr[i] + a[i][j] * br[j];
// Finally check if value of expression
// A * (B*r) - (C*r) is 0 or not
for (int i = 0; i < N; i++)
if (axbr[i] - cr[i] != 0)
false;
return true;
}
// Runs k iterations Freivald. The value
// of k determines accuracy. Higher value
// means higher accuracy.
bool isProduct(int a[][N], int b[][N],
int c[][N], int k)
{
for (int i=0; i
Java
// Java code to implement
// Freivald's Algorithm
import java.io.*;
import java.util.*;
import java.math.*;
class GFG {
static int N = 2;
// Function to check if ABx = Cx
static boolean freivald(int a[][], int b[][],
int c[][])
{
// Generate a random vector
int r[] = new int[N];
for (int i = 0; i < N; i++)
r[i] = (int)(Math.random()) % 2;
// Now comput B*r for evaluating
// expression A * (B*r) - (C*r)
int br[] = new int[N];
Arrays.fill(br, 0);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
br[i] = br[i] + b[i][j] * r[j];
// Now comput C*r for evaluating
// expression A * (B*r) - (C*r)
int cr[] = new int[N];
Arrays.fill(cr, 0);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
cr[i] = cr[i] + c[i][j] * r[j];
// Now comput A* (B*r) for evaluating
// expression A * (B*r) - (C*r)
int axbr[] = new int[N];
Arrays.fill(axbr, 0);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
axbr[i] = axbr[i] + a[i][j] * br[j];
// Finally check if value of expression
// A * (B*r) - (C*r) is 0 or not
for (int i = 0; i < N; i++)
if (axbr[i] - cr[i] != 0)
return false;
return true;
}
// Runs k iterations Freivald. The value
// of k determines accuracy. Higher value
// means higher accuracy.
static boolean isProduct(int a[][], int b[][],
int c[][], int k)
{
for (int i = 0; i < k; i++)
if (freivald(a, b, c) == false)
return false;
return true;
}
// Driver code
public static void main(String args[])
{
int a[][] = { { 1, 1 }, { 1, 1 } };
int b[][] = { { 1, 1 }, { 1, 1 } };
int c[][] = { { 2, 2 }, { 2, 2 } };
int k = 2;
if (isProduct(a, b, c, k))
System.out.println("Yes");
else
System.out.println("No");
}
}
/*This code is contributed by Nikita Tiwari.*/
Python3
# Python3 code to implement Freivald’s Algorithm
import random
N = 2
# Function to check if ABx = Cx
def freivald(a, b, c) :
# Generate a random vector
r = [0] * N
for i in range(0, N) :
r[i] = (int)(random.randrange(509090009) % 2)
# Now comput B*r for evaluating
# expression A * (B*r) - (C*r)
br = [0] * N
for i in range(0, N) :
for j in range(0, N) :
br[i] = br[i] + b[i][j] * r[j]
# Now comput C*r for evaluating
# expression A * (B*r) - (C*r)
cr = [0] * N
for i in range(0, N) :
for j in range(0, N) :
cr[i] = cr[i] + c[i][j] * r[j]
# Now comput A* (B*r) for evaluating
# expression A * (B*r) - (C*r)
axbr = [0] * N
for i in range(0, N) :
for j in range(0, N) :
axbr[i] = axbr[i] + a[i][j] * br[j]
# Finally check if value of expression
# A * (B*r) - (C*r) is 0 or not
for i in range(0, N) :
if (axbr[i] - cr[i] != 0) :
return False
return True
# Runs k iterations Freivald. The value
# of k determines accuracy. Higher value
# means higher accuracy.
def isProduct(a, b, c, k) :
for i in range(0, k) :
if (freivald(a, b, c) == False) :
return False
return True
# Driver code
a = [ [ 1, 1 ], [ 1, 1 ] ]
b = [ [ 1, 1 ], [ 1, 1 ] ]
c = [ [ 2, 2 ], [ 2, 2 ] ]
k = 2
if (isProduct(a, b, c, k)) :
print("Yes")
else :
print("No")
# This code is contributed by Nikita Tiwari
C#
// C# code to implement
// Freivald's Algorithm
using System;
class GFG
{
static int N = 2;
// Function to check
// if ABx = Cx
static bool freivald(int [,]a,
int [,]b,
int [,]c)
{
// Generate a
// random vector
Random rand = new Random();
int []r = new int[N];
for (int i = 0; i < N; i++)
r[i] = (int)(rand.Next()) % 2;
// Now compute B*r for
// evaluating expression
// A * (B*r) - (C*r)
int []br = new int[N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
br[i] = br[i] +
b[i, j] * r[j];
// Now compute C*r for
// evaluating expression
// A * (B*r) - (C*r)
int []cr = new int[N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
cr[i] = cr[i] +
c[i, j] * r[j];
// Now compute A* (B*r) for
// evaluating expression
// A * (B*r) - (C*r)
int []axbr = new int[N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
axbr[i] = axbr[i] +
a[i, j] * br[j];
// Finally check if value
// of expression A * (B*r) -
// (C*r) is 0 or not
for (int i = 0; i < N; i++)
if (axbr[i] - cr[i] != 0)
return false;
return true;
}
// Runs k iterations Freivald.
// The value of k determines
// accuracy. Higher value
// means higher accuracy.
static bool isProduct(int [,]a, int [,]b,
int [,]c, int k)
{
for (int i = 0; i < k; i++)
if (freivald(a, b, c) == false)
return false;
return true;
}
// Driver code
static void Main()
{
int [,]a = new int[,]{ { 1, 1 },
{ 1, 1 }};
int [,]b = new int[,]{ { 1, 1 },
{ 1, 1 }};
int [,]c = new int[,]{ { 2, 2 },
{ 2, 2 }};
int k = 2;
if (isProduct(a, b, c, k))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
// This code is contributed
// by Manish Shaw(manishshaw1)
PHP
输出:
Yes