mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-24 04:54:21 +08:00
Change project structure to a Maven Java project + Refactor (#2816)
This commit is contained in:

committed by
GitHub

parent
8e533d2617
commit
9fb3364ccc
@ -0,0 +1,22 @@
|
||||
package com.thealgorithms.divideandconquer;
|
||||
|
||||
public class BinaryExponentiation {
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println(calculatePower(2, 30));
|
||||
}
|
||||
|
||||
// Function to calculate x^y
|
||||
// Time Complexity: O(logn)
|
||||
public static long calculatePower(long x, long y) {
|
||||
if (y == 0) {
|
||||
return 1;
|
||||
}
|
||||
long val = calculatePower(x, y / 2);
|
||||
val *= val;
|
||||
if (y % 2 == 1) {
|
||||
val *= x;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
@ -0,0 +1,349 @@
|
||||
package com.thealgorithms.divideandconquer;
|
||||
|
||||
/**
|
||||
* For a set of points in a coordinates system (10000 maximum), ClosestPair
|
||||
* class calculates the two closest points.
|
||||
*/
|
||||
public final class ClosestPair {
|
||||
|
||||
/**
|
||||
* Number of points
|
||||
*/
|
||||
int numberPoints;
|
||||
/**
|
||||
* Input data, maximum 10000.
|
||||
*/
|
||||
private Location[] array;
|
||||
/**
|
||||
* Minimum point coordinate.
|
||||
*/
|
||||
Location point1 = null;
|
||||
/**
|
||||
* Minimum point coordinate.
|
||||
*/
|
||||
Location point2 = null;
|
||||
/**
|
||||
* Minimum point length.
|
||||
*/
|
||||
private static double minNum = Double.MAX_VALUE;
|
||||
|
||||
public static void setMinNum(double minNum) {
|
||||
ClosestPair.minNum = minNum;
|
||||
}
|
||||
|
||||
public static void setSecondCount(int secondCount) {
|
||||
ClosestPair.secondCount = secondCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* secondCount
|
||||
*/
|
||||
private static int secondCount = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
ClosestPair(int points) {
|
||||
numberPoints = points;
|
||||
array = new Location[numberPoints];
|
||||
}
|
||||
|
||||
/**
|
||||
* Location class is an auxiliary type to keep points coordinates.
|
||||
*/
|
||||
public static class Location {
|
||||
|
||||
double x;
|
||||
double y;
|
||||
|
||||
/**
|
||||
* @param xpar (IN Parameter) x coordinate <br>
|
||||
* @param ypar (IN Parameter) y coordinate <br>
|
||||
*/
|
||||
Location(final double xpar, final double ypar) { // Save x, y coordinates
|
||||
this.x = xpar;
|
||||
this.y = ypar;
|
||||
}
|
||||
}
|
||||
|
||||
public Location[] createLocation(int numberValues) {
|
||||
return new Location[numberValues];
|
||||
}
|
||||
|
||||
public Location buildLocation(double x, double y) {
|
||||
return new Location(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* xPartition function: arrange x-axis.
|
||||
*
|
||||
* @param a (IN Parameter) array of points <br>
|
||||
* @param first (IN Parameter) first point <br>
|
||||
* @param last (IN Parameter) last point <br>
|
||||
* @return pivot index
|
||||
*/
|
||||
public int xPartition(final Location[] a, final int first, final int last) {
|
||||
|
||||
Location pivot = a[last]; // pivot
|
||||
int i = first - 1;
|
||||
Location temp; // Temporarily store value for position transformation
|
||||
for (int j = first; j <= last - 1; j++) {
|
||||
if (a[j].x <= pivot.x) { // Less than or less than pivot
|
||||
i++;
|
||||
temp = a[i]; // array[i] <-> array[j]
|
||||
a[i] = a[j];
|
||||
a[j] = temp;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
temp = a[i]; // array[pivot] <-> array[i]
|
||||
a[i] = a[last];
|
||||
a[last] = temp;
|
||||
return i; // pivot index
|
||||
}
|
||||
|
||||
/**
|
||||
* yPartition function: arrange y-axis.
|
||||
*
|
||||
* @param a (IN Parameter) array of points <br>
|
||||
* @param first (IN Parameter) first point <br>
|
||||
* @param last (IN Parameter) last point <br>
|
||||
* @return pivot index
|
||||
*/
|
||||
public int yPartition(final Location[] a, final int first, final int last) {
|
||||
|
||||
Location pivot = a[last]; // pivot
|
||||
int i = first - 1;
|
||||
Location temp; // Temporarily store value for position transformation
|
||||
for (int j = first; j <= last - 1; j++) {
|
||||
if (a[j].y <= pivot.y) { // Less than or less than pivot
|
||||
i++;
|
||||
temp = a[i]; // array[i] <-> array[j]
|
||||
a[i] = a[j];
|
||||
a[j] = temp;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
temp = a[i]; // array[pivot] <-> array[i]
|
||||
a[i] = a[last];
|
||||
a[last] = temp;
|
||||
return i; // pivot index
|
||||
}
|
||||
|
||||
/**
|
||||
* xQuickSort function: //x-axis Quick Sorting.
|
||||
*
|
||||
* @param a (IN Parameter) array of points <br>
|
||||
* @param first (IN Parameter) first point <br>
|
||||
* @param last (IN Parameter) last point <br>
|
||||
*/
|
||||
public void xQuickSort(final Location[] a, final int first, final int last) {
|
||||
|
||||
if (first < last) {
|
||||
int q = xPartition(a, first, last); // pivot
|
||||
xQuickSort(a, first, q - 1); // Left
|
||||
xQuickSort(a, q + 1, last); // Right
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* yQuickSort function: //y-axis Quick Sorting.
|
||||
*
|
||||
* @param a (IN Parameter) array of points <br>
|
||||
* @param first (IN Parameter) first point <br>
|
||||
* @param last (IN Parameter) last point <br>
|
||||
*/
|
||||
public void yQuickSort(final Location[] a, final int first, final int last) {
|
||||
|
||||
if (first < last) {
|
||||
int q = yPartition(a, first, last); // pivot
|
||||
yQuickSort(a, first, q - 1); // Left
|
||||
yQuickSort(a, q + 1, last); // Right
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* closestPair function: find closest pair.
|
||||
*
|
||||
* @param a (IN Parameter) array stored before divide <br>
|
||||
* @param indexNum (IN Parameter) number coordinates divideArray <br>
|
||||
* @return minimum distance <br>
|
||||
*/
|
||||
public double closestPair(final Location[] a, final int indexNum) {
|
||||
|
||||
Location[] divideArray = new Location[indexNum];
|
||||
System.arraycopy(a, 0, divideArray, 0, indexNum); // Copy previous array
|
||||
int divideX = indexNum / 2; // Intermediate value for divide
|
||||
Location[] leftArray = new Location[divideX]; // divide - left array
|
||||
// divide-right array
|
||||
Location[] rightArray = new Location[indexNum - divideX];
|
||||
if (indexNum <= 3) { // If the number of coordinates is 3 or less
|
||||
return bruteForce(divideArray);
|
||||
}
|
||||
// divide-left array
|
||||
System.arraycopy(divideArray, 0, leftArray, 0, divideX);
|
||||
// divide-right array
|
||||
System.arraycopy(divideArray, divideX, rightArray, 0, indexNum - divideX);
|
||||
|
||||
double minLeftArea; // Minimum length of left array
|
||||
double minRightArea; // Minimum length of right array
|
||||
double minValue; // Minimum lengt
|
||||
|
||||
minLeftArea = closestPair(leftArray, divideX); // recursive closestPair
|
||||
minRightArea = closestPair(rightArray, indexNum - divideX);
|
||||
// window size (= minimum length)
|
||||
minValue = Math.min(minLeftArea, minRightArea);
|
||||
|
||||
// Create window. Set the size for creating a window
|
||||
// and creating a new array for the coordinates in the window
|
||||
for (int i = 0; i < indexNum; i++) {
|
||||
double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x);
|
||||
if (xGap < minValue) {
|
||||
ClosestPair.setSecondCount(secondCount + 1); // size of the array
|
||||
} else {
|
||||
if (divideArray[i].x > divideArray[divideX].x) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// new array for coordinates in window
|
||||
Location[] firstWindow = new Location[secondCount];
|
||||
int k = 0;
|
||||
for (int i = 0; i < indexNum; i++) {
|
||||
double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x);
|
||||
if (xGap < minValue) { // if it's inside a window
|
||||
firstWindow[k] = divideArray[i]; // put in an array
|
||||
k++;
|
||||
} else {
|
||||
if (divideArray[i].x > divideArray[divideX].x) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
yQuickSort(firstWindow, 0, secondCount - 1); // Sort by y coordinates
|
||||
/* Coordinates in Window */
|
||||
double length;
|
||||
// size comparison within window
|
||||
for (int i = 0; i < secondCount - 1; i++) {
|
||||
for (int j = (i + 1); j < secondCount; j++) {
|
||||
double xGap = Math.abs(firstWindow[i].x - firstWindow[j].x);
|
||||
double yGap = Math.abs(firstWindow[i].y - firstWindow[j].y);
|
||||
if (yGap < minValue) {
|
||||
length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2));
|
||||
// If measured distance is less than current min distance
|
||||
if (length < minValue) {
|
||||
// Change minimum distance to current distance
|
||||
minValue = length;
|
||||
// Conditional for registering final coordinate
|
||||
if (length < minNum) {
|
||||
ClosestPair.setMinNum(length);
|
||||
point1 = firstWindow[i];
|
||||
point2 = firstWindow[j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ClosestPair.setSecondCount(0);
|
||||
return minValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* bruteForce function: When the number of coordinates is less than 3.
|
||||
*
|
||||
* @param arrayParam (IN Parameter) array stored before divide <br>
|
||||
* @return <br>
|
||||
*/
|
||||
public double bruteForce(final Location[] arrayParam) {
|
||||
|
||||
double minValue = Double.MAX_VALUE; // minimum distance
|
||||
double length;
|
||||
double xGap; // Difference between x coordinates
|
||||
double yGap; // Difference between y coordinates
|
||||
double result = 0;
|
||||
|
||||
if (arrayParam.length == 2) {
|
||||
// Difference between x coordinates
|
||||
xGap = (arrayParam[0].x - arrayParam[1].x);
|
||||
// Difference between y coordinates
|
||||
yGap = (arrayParam[0].y - arrayParam[1].y);
|
||||
// distance between coordinates
|
||||
length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2));
|
||||
// Conditional statement for registering final coordinate
|
||||
if (length < minNum) {
|
||||
ClosestPair.setMinNum(length);
|
||||
}
|
||||
point1 = arrayParam[0];
|
||||
point2 = arrayParam[1];
|
||||
result = length;
|
||||
}
|
||||
if (arrayParam.length == 3) {
|
||||
for (int i = 0; i < arrayParam.length - 1; i++) {
|
||||
for (int j = (i + 1); j < arrayParam.length; j++) {
|
||||
// Difference between x coordinates
|
||||
xGap = (arrayParam[i].x - arrayParam[j].x);
|
||||
// Difference between y coordinates
|
||||
yGap = (arrayParam[i].y - arrayParam[j].y);
|
||||
// distance between coordinates
|
||||
length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2));
|
||||
// If measured distance is less than current min distance
|
||||
if (length < minValue) {
|
||||
// Change minimum distance to current distance
|
||||
minValue = length;
|
||||
if (length < minNum) {
|
||||
// Registering final coordinate
|
||||
ClosestPair.setMinNum(length);
|
||||
point1 = arrayParam[i];
|
||||
point2 = arrayParam[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = minValue;
|
||||
}
|
||||
return result; // If only one point returns 0.
|
||||
}
|
||||
|
||||
/**
|
||||
* main function: execute class.
|
||||
*
|
||||
* @param args (IN Parameter) <br>
|
||||
*/
|
||||
public static void main(final String[] args) {
|
||||
|
||||
// Input data consists of one x-coordinate and one y-coordinate
|
||||
ClosestPair cp = new ClosestPair(12);
|
||||
cp.array[0] = cp.buildLocation(2, 3);
|
||||
cp.array[1] = cp.buildLocation(2, 16);
|
||||
cp.array[2] = cp.buildLocation(3, 9);
|
||||
cp.array[3] = cp.buildLocation(6, 3);
|
||||
cp.array[4] = cp.buildLocation(7, 7);
|
||||
cp.array[5] = cp.buildLocation(19, 4);
|
||||
cp.array[6] = cp.buildLocation(10, 11);
|
||||
cp.array[7] = cp.buildLocation(15, 2);
|
||||
cp.array[8] = cp.buildLocation(15, 19);
|
||||
cp.array[9] = cp.buildLocation(16, 11);
|
||||
cp.array[10] = cp.buildLocation(17, 13);
|
||||
cp.array[11] = cp.buildLocation(9, 12);
|
||||
|
||||
System.out.println("Input data");
|
||||
System.out.println("Number of points: " + cp.array.length);
|
||||
for (int i = 0; i < cp.array.length; i++) {
|
||||
System.out.println("x: " + cp.array[i].x + ", y: " + cp.array[i].y);
|
||||
}
|
||||
|
||||
cp.xQuickSort(cp.array, 0, cp.array.length - 1); // Sorting by x value
|
||||
|
||||
double result; // minimum distance
|
||||
|
||||
result = cp.closestPair(cp.array, cp.array.length);
|
||||
// ClosestPair start
|
||||
// minimum distance coordinates and distance output
|
||||
System.out.println("Output Data");
|
||||
System.out.println("(" + cp.point1.x + ", " + cp.point1.y + ")");
|
||||
System.out.println("(" + cp.point2.x + ", " + cp.point2.y + ")");
|
||||
System.out.println("Minimum Distance : " + result);
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
package com.thealgorithms.divideandconquer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @author dimgrichr
|
||||
* <p>
|
||||
* Space complexity: O(n) Time complexity: O(nlogn), because it is a divide and
|
||||
* conquer algorithm
|
||||
*/
|
||||
public class SkylineAlgorithm {
|
||||
|
||||
private ArrayList<Point> points;
|
||||
|
||||
/**
|
||||
* Main constructor of the application. ArrayList points gets created, which
|
||||
* represents the sum of all edges.
|
||||
*/
|
||||
public SkylineAlgorithm() {
|
||||
points = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return points, the ArrayList that includes all points.
|
||||
*/
|
||||
public ArrayList<Point> getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main divide and conquer, and also recursive algorithm. It gets an
|
||||
* ArrayList full of points as an argument. If the size of that ArrayList is
|
||||
* 1 or 2, the ArrayList is returned as it is, or with one less point (if
|
||||
* the initial size is 2 and one of it's points, is dominated by the other
|
||||
* one). On the other hand, if the ArrayList's size is bigger than 2, the
|
||||
* function is called again, twice, with arguments the corresponding half of
|
||||
* the initial ArrayList each time. Once the flashback has ended, the
|
||||
* function produceFinalSkyLine gets called, in order to produce the final
|
||||
* skyline, and return it.
|
||||
*
|
||||
* @param list, the initial list of points
|
||||
* @return leftSkyLine, the combination of first half's and second half's
|
||||
* skyline
|
||||
* @see Point
|
||||
*/
|
||||
public ArrayList<Point> produceSubSkyLines(ArrayList<Point> list) {
|
||||
|
||||
// part where function exits flashback
|
||||
int size = list.size();
|
||||
if (size == 1) {
|
||||
return list;
|
||||
} else if (size == 2) {
|
||||
if (list.get(0).dominates(list.get(1))) {
|
||||
list.remove(1);
|
||||
} else {
|
||||
if (list.get(1).dominates(list.get(0))) {
|
||||
list.remove(0);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// recursive part of the function
|
||||
ArrayList<Point> leftHalf = new ArrayList<>();
|
||||
ArrayList<Point> rightHalf = new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (i < list.size() / 2) {
|
||||
leftHalf.add(list.get(i));
|
||||
} else {
|
||||
rightHalf.add(list.get(i));
|
||||
}
|
||||
}
|
||||
ArrayList<Point> leftSubSkyLine = produceSubSkyLines(leftHalf);
|
||||
ArrayList<Point> rightSubSkyLine = produceSubSkyLines(rightHalf);
|
||||
|
||||
// skyline is produced
|
||||
return produceFinalSkyLine(leftSubSkyLine, rightSubSkyLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* The first half's skyline gets cleared from some points that are not part
|
||||
* of the final skyline (Points with same x-value and different y=values.
|
||||
* The point with the smallest y-value is kept). Then, the minimum y-value
|
||||
* of the points of first half's skyline is found. That helps us to clear
|
||||
* the second half's skyline, because, the points of second half's skyline
|
||||
* that have greater y-value of the minimum y-value that we found before,
|
||||
* are dominated, so they are not part of the final skyline. Finally, the
|
||||
* "cleaned" first half's and second half's skylines, are combined,
|
||||
* producing the final skyline, which is returned.
|
||||
*
|
||||
* @param left the skyline of the left part of points
|
||||
* @param right the skyline of the right part of points
|
||||
* @return left the final skyline
|
||||
*/
|
||||
public ArrayList<Point> produceFinalSkyLine(ArrayList<Point> left, ArrayList<Point> right) {
|
||||
|
||||
// dominated points of ArrayList left are removed
|
||||
for (int i = 0; i < left.size() - 1; i++) {
|
||||
if (left.get(i).x == left.get(i + 1).x && left.get(i).y > left.get(i + 1).y) {
|
||||
left.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
// minimum y-value is found
|
||||
int min = left.get(0).y;
|
||||
for (int i = 1; i < left.size(); i++) {
|
||||
if (min > left.get(i).y) {
|
||||
min = left.get(i).y;
|
||||
if (min == 1) {
|
||||
i = left.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dominated points of ArrayList right are removed
|
||||
for (int i = 0; i < right.size(); i++) {
|
||||
if (right.get(i).y >= min) {
|
||||
right.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
// final skyline found and returned
|
||||
left.addAll(right);
|
||||
return left;
|
||||
}
|
||||
|
||||
public static class Point {
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
/**
|
||||
* The main constructor of Point Class, used to represent the 2
|
||||
* Dimension points.
|
||||
*
|
||||
* @param x the point's x-value.
|
||||
* @param y the point's y-value.
|
||||
*/
|
||||
public Point(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return x, the x-value
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return y, the y-value
|
||||
*/
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the skyline theory, it checks if the point that calls the
|
||||
* function dominates the argument point.
|
||||
*
|
||||
* @param p1 the point that is compared
|
||||
* @return true if the point wich calls the function dominates p1 false
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean dominates(Point p1) {
|
||||
// checks if p1 is dominated
|
||||
return (this.x < p1.x && this.y <= p1.y) || (this.x <= p1.x && this.y < p1.y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It is used to compare the 2 Dimension points, based on their x-values, in
|
||||
* order get sorted later.
|
||||
*/
|
||||
class XComparator implements Comparator<Point> {
|
||||
|
||||
@Override
|
||||
public int compare(Point a, Point b) {
|
||||
return Integer.compare(a.x, b.x);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
package com.thealgorithms.divideandconquer;
|
||||
|
||||
// Java Program to Implement Strassen Algorithm
|
||||
// Class Strassen matrix multiplication
|
||||
public class StrassenMatrixMultiplication {
|
||||
|
||||
// Method 1
|
||||
// Function to multiply matrices
|
||||
public int[][] multiply(int[][] A, int[][] B) {
|
||||
int n = A.length;
|
||||
|
||||
int[][] R = new int[n][n];
|
||||
|
||||
if (n == 1) {
|
||||
R[0][0] = A[0][0] * B[0][0];
|
||||
} else {
|
||||
// Dividing Matrix into parts
|
||||
// by storing sub-parts to variables
|
||||
int[][] A11 = new int[n / 2][n / 2];
|
||||
int[][] A12 = new int[n / 2][n / 2];
|
||||
int[][] A21 = new int[n / 2][n / 2];
|
||||
int[][] A22 = new int[n / 2][n / 2];
|
||||
int[][] B11 = new int[n / 2][n / 2];
|
||||
int[][] B12 = new int[n / 2][n / 2];
|
||||
int[][] B21 = new int[n / 2][n / 2];
|
||||
int[][] B22 = new int[n / 2][n / 2];
|
||||
|
||||
// Dividing matrix A into 4 parts
|
||||
split(A, A11, 0, 0);
|
||||
split(A, A12, 0, n / 2);
|
||||
split(A, A21, n / 2, 0);
|
||||
split(A, A22, n / 2, n / 2);
|
||||
|
||||
// Dividing matrix B into 4 parts
|
||||
split(B, B11, 0, 0);
|
||||
split(B, B12, 0, n / 2);
|
||||
split(B, B21, n / 2, 0);
|
||||
split(B, B22, n / 2, n / 2);
|
||||
|
||||
// Using Formulas as described in algorithm
|
||||
// M1:=(A1+A3)×(B1+B2)
|
||||
int[][] M1
|
||||
= multiply(add(A11, A22), add(B11, B22));
|
||||
|
||||
// M2:=(A2+A4)×(B3+B4)
|
||||
int[][] M2 = multiply(add(A21, A22), B11);
|
||||
|
||||
// M3:=(A1−A4)×(B1+A4)
|
||||
int[][] M3 = multiply(A11, sub(B12, B22));
|
||||
|
||||
// M4:=A1×(B2−B4)
|
||||
int[][] M4 = multiply(A22, sub(B21, B11));
|
||||
|
||||
// M5:=(A3+A4)×(B1)
|
||||
int[][] M5 = multiply(add(A11, A12), B22);
|
||||
|
||||
// M6:=(A1+A2)×(B4)
|
||||
int[][] M6
|
||||
= multiply(sub(A21, A11), add(B11, B12));
|
||||
|
||||
// M7:=A4×(B3−B1)
|
||||
int[][] M7
|
||||
= multiply(sub(A12, A22), add(B21, B22));
|
||||
|
||||
// P:=M2+M3−M6−M7
|
||||
int[][] C11 = add(sub(add(M1, M4), M5), M7);
|
||||
|
||||
// Q:=M4+M6
|
||||
int[][] C12 = add(M3, M5);
|
||||
|
||||
// R:=M5+M7
|
||||
int[][] C21 = add(M2, M4);
|
||||
|
||||
// S:=M1−M3−M4−M5
|
||||
int[][] C22 = add(sub(add(M1, M3), M2), M6);
|
||||
|
||||
join(C11, R, 0, 0);
|
||||
join(C12, R, 0, n / 2);
|
||||
join(C21, R, n / 2, 0);
|
||||
join(C22, R, n / 2, n / 2);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
// Method 2
|
||||
// Function to subtract two matrices
|
||||
public int[][] sub(int[][] A, int[][] B) {
|
||||
int n = A.length;
|
||||
|
||||
int[][] C = new int[n][n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
C[i][j] = A[i][j] - B[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
return C;
|
||||
}
|
||||
|
||||
// Method 3
|
||||
// Function to add two matrices
|
||||
public int[][] add(int[][] A, int[][] B) {
|
||||
|
||||
int n = A.length;
|
||||
|
||||
int[][] C = new int[n][n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
C[i][j] = A[i][j] + B[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
return C;
|
||||
}
|
||||
|
||||
// Method 4
|
||||
// Function to split parent matrix
|
||||
// into child matrices
|
||||
public void split(int[][] P, int[][] C, int iB, int jB) {
|
||||
for (int i1 = 0, i2 = iB; i1 < C.length; i1++, i2++) {
|
||||
for (int j1 = 0, j2 = jB; j1 < C.length; j1++, j2++) {
|
||||
C[i1][j1] = P[i2][j2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method 5
|
||||
// Function to join child matrices
|
||||
// into (to) parent matrix
|
||||
public void join(int[][] C, int[][] P, int iB, int jB) {
|
||||
for (int i1 = 0, i2 = iB; i1 < C.length; i1++, i2++) {
|
||||
for (int j1 = 0, j2 = jB; j1 < C.length; j1++, j2++) {
|
||||
P[i2][j2] = C[i1][j1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method 5
|
||||
// Main driver method
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Strassen Multiplication Algorithm Implementation For Matrix Multiplication :\n");
|
||||
|
||||
StrassenMatrixMultiplication s = new StrassenMatrixMultiplication();
|
||||
|
||||
// Size of matrix
|
||||
// Considering size as 4 in order to illustrate
|
||||
int N = 4;
|
||||
|
||||
// Matrix A
|
||||
// Custom input to matrix
|
||||
int[][] A = {{1, 2, 5, 4},
|
||||
{9, 3, 0, 6},
|
||||
{4, 6, 3, 1},
|
||||
{0, 2, 0, 6}};
|
||||
|
||||
// Matrix B
|
||||
// Custom input to matrix
|
||||
int[][] B = {{1, 0, 4, 1},
|
||||
{1, 2, 0, 2},
|
||||
{0, 3, 1, 3},
|
||||
{1, 8, 1, 2}};
|
||||
|
||||
// Matrix C computations
|
||||
// Matrix C calling method to get Result
|
||||
int[][] C = s.multiply(A, B);
|
||||
|
||||
System.out.println("\nProduct of matrices A and B : ");
|
||||
|
||||
// Print the output
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = 0; j < N; j++) {
|
||||
System.out.print(C[i][j] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user