📜  分而治之算法|介绍

📅  最后修改于: 2021-04-27 19:48:24             🧑  作者: Mango

在本文中,我们将讨论分而治之技术如何有所帮助以及如何使用DAC技术解决问题。在本节中,我们将讨论以下主题。

1. Introduction to DAC.
2. Algorithms under DAC techniques.
3. Recurrence Relation for DAC algorithm.
4. Problems using DAC technique.

分而治之
此技术可以分为以下三个部分:

  1. 划分:这涉及将问题划分为一些子问题。
  2. 征服:通过递归调用子问题直到子问题解决为止。
  3. 合并:解决子问题,以便我们找到问题的解决方案。

以下是遵循分而治之算法的一些标准算法。

  1. Quicksort是一种排序算法。该算法选择一个枢轴元素,以这样一种方式重新排列数组元素:所有小于所选择的枢轴元素的元素都移到枢轴的左侧,所有更大的元素都移到右侧。最后,该算法对枢轴元素左侧和右侧的子数组进行递归排序。
  2. 合并排序也是一种排序算法。该算法将数组分为两半,然后对它们进行递归排序,最后合并这两个排序后的两半。
  3. 最接近的点对问题是在xy平面中的一组点中找到最接近的点对。通过计算每对点的距离并比较距离以找出最小值,可以在O(n ^ 2)时间内解决该问题。分而治之算法解决了O(nLogn)时间的问题。
  4. Strassen算法是将两个矩阵相乘的高效算法。一个简单的将两个矩阵相乘的方法需要3个嵌套循环,并且为O(n ^ 3)。 Strassen算法在O(n ^ 2.8974)时间内将两个矩阵相乘。
  5. Cooley–Tukey快速傅立叶变换(FFT)算法FFT中最常用的算法。这是一种分治法,可在O(nlogn)时间内使用。
  6. Karatsuba快速乘法算法,最多可对两个n位数字进行乘法运算

3 n ^ {\ log_23} \约3 n ^ {1.585}

一般是一位数的乘法(精确地是

n ^ {\ log_23}

n是2的幂时。因此,它比经典算法要快,经典算法需要n 2个个位数的乘积。特别是,如果n = 2 10 = 1024,则精确计数分别为3 10 = 59、049和(2 10 ) 2 = 1,048、576。

什么不符合“分而治之”的条件:

二进制搜索是一种搜索算法。在每个步骤中,算法都会将输入元素x与数组中中间元素的值进行比较。如果值匹配,则返回中间的索引。否则,如果x小于中间元素,则算法在中间元素的左侧重复,否则在中间元素的右侧重复。与普遍看法相反,这不是“分而治之”的例子,因为每一步中只有一个子问题(“分而治之”必须有两个或多个子问题),因此这是“减少”和“解决”的一种情况。征服。

分而治之算法:

DAC(a, i, j)
{
    if(small(a, i, j))
      return(Solution(a, i, j))
    else 
      m = divide(a, i, j)               // f1(n)
      b = DAC(a, i, mid)                 // T(n/2)
      c = DAC(a, mid+1, j)            // T(n/2)
      d = combine(b, c)                 // f2(n)
   return(d)
}

DAC算法的递归关系:
这是上述程序的重复关系。

O(1) if n is small
T(n) =     f1(n) + 2T(n/2) + f2(n)

例子:
查找给定数组中的最大和最小元素。

Input: { 70, 250, 50, 80, 140, 12, 14 }
Output: The minimum number in a given array is : 12
The maximum number in a given array is : 250

方法:从给定数组中找到最大和最小元素是分而治之的应用。在这个问题中,我们将找到给定数组中的最大和最小元素。在此问题中,我们使用了分而治之的方法(DAC),该方法具有三个步骤:分而治之和合并。

对于最大值:
在这个问题中,我们使用递归方法来找到最大值,在该最大值处将只剩下两个元素,然后我们可以轻松地使用条件,即if(a [index]> a [index + 1]。)
在程序行中,a [index]和a [index + 1])条件将确保仅剩两个元素。

在上述条件下,我们检查了左侧条件以找出最大值。现在,我们将看到右侧条件以找到最大值。
递归函数,用于检查数组当前索引的右侧。

现在,我们将比较条件并在给定数组的当前索引处检查右侧。
在给定的程序中,我们将实现此逻辑以检查当前索引右侧的条件。

最低要求:
在此问题中,我们将实施递归方法以找到最小值。在给定的数组中。

现在,我们将检查给定数组中右侧的条件。

现在,我们将检查条件以在右侧找到最小值。

执行:

C++
// C++ code to demonstrate Divide and
// Conquer Algorithm#include
# include
using namespace std;
 
// function to find the maximum no.
// in a given array.
int DAC_Max(int arr[], int index, int l)
{
    int max;
    if(index >= l - 2)
    {
        if(arr[index] > arr[index + 1])
          return arr[index];
        else
          return arr[index + 1];
    } 
    max = DAC_Max(arr, index + 1, l);   
    if(arr[index] > max)
       return arr[index];
    else
       return max;
}
 
// Function to find the minimum no.
// in a given array
int DAC_Min(int arr[], int index, int l)
{
    int min;
    if(index >= l - 2)
    {
        if(arr[index] < arr[index + 1])
          return arr[index];
        else
          return arr[index + 1];
    }
     
    min = DAC_Min(arr, index + 1, l);  
    if(arr[index] < min)
       return arr[index];
    else
       return min;
}
 
// Driver code
int main()
{
    int arr[] = {120, 34, 54, 32, 58, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);
    int max, min;
    max = DAC_Max(arr, 0, n);
    min = DAC_Min(arr, 0, n);
    cout << "Maximum: " << max << endl;
    cout << "Minimum: " << min << endl;
    return 0;
}
 
// This code is contributed by probinsah.


C
// C code to demonstrate Divide and
// Conquer Algorithm
#include 
int DAC_Max(int a[], int index, int l);
int DAC_Min(int a[], int index, int l);
 
// function to find the maximum no.
// in a given array.
int DAC_Max(int a[], int index, int l)
{
    int max;
    if (index >= l - 2) {
        if (a[index] > a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // logic to find the Maximum element
    // in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max)
        return a[index];
    else
        return max;
}
 
// Function to find the minimum no.
// in a given array.
int DAC_Min(int a[], int index, int l)
{
    int min;
    if (index >= l - 2) {
        if (a[index] < a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Minimum element
    // in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min)
        return a[index];
    else
        return min;
}
 
// Driver Code
int main()
{
    // Defining the variables
    int min, max, N;
 
    // Initializing the array
    int a[7] = { 70, 250, 50, 80, 140, 12, 14 };
 
    // recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    // recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
    printf("The minimum number in a given array is : %d\n", min);
    printf("The maximum number in a given array is : %d", max);
    return 0;
}
 
// This code is contributed by Ashish Rana (GFG Team)


Java
// Java code to demonstrate Divide and
// Conquer Algorithm
class GFG{
 
// Function to find the maximum no.
// in a given array.
static int DAC_Max(int a[], int index, int l)
{
    int max;
     
    if (index >= l - 2)
    {
        if (a[index] > a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Maximum element
    // in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max)
        return a[index];
    else
        return max;
}
 
// Function to find the minimum no.
// in a given array.
static int DAC_Min(int a[], int index, int l)
{
    int min;
    if (index >= l - 2)
    {
        if (a[index] < a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Minimum element
    // in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min)
        return a[index];
    else
        return min;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Defining the variables
    int min, max;
 
    // Initializing the array
    int a[] = { 70, 250, 50, 80, 140, 12, 14 };
 
    // Recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    // Recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
     
    System.out.printf("The minimum number in " +
                      "a given array is : %d\n", min);
    System.out.printf("The maximum number in " +
                      "a given array is : %d", max);
}
}
 
// This code is contributed by Princi Singh


C#
// C# code to demonstrate Divide and
// Conquer Algorithm
using System;
class GFG
{
 
// Function to find the maximum no.
// in a given array.
static int DAC_Max(int []a, int index, int l)
{
    int max;
     
    if (index >= l - 2)
    {
        if (a[index] > a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Maximum element
    // in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max)
        return a[index];
    else
        return max;
}
 
// Function to find the minimum no.
// in a given array.
static int DAC_Min(int []a, int index, int l)
{
    int min;
    if (index >= l - 2)
    {
        if (a[index] < a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Minimum element
    // in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min)
        return a[index];
    else
        return min;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Defining the variables
    int min, max;
 
    // Initializing the array
    int []a = {70, 250, 50, 80, 140, 12, 14};
 
    // Recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    // Recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
     
    Console.Write("The minimum number in " +
                      "a given array is : {0}\n", min);
    Console.Write("The maximum number in " +
                      "a given array is : {0}", max);
}
}
 
// This code contributed by shikhasingrajput


Python3
# Python3 code to demonstrate Divide and
# Conquer Algorithm
 
# Function to find the maximum no.
# in a given array.
def DAC_Max(a, index, l):
    max = -1;
 
    if (index >= l - 2):
        if (a[index] > a[index + 1]):
            return a[index];
        else:
            return a[index + 1];
 
    # Logic to find the Maximum element
    # in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max):
        return a[index];
    else:
        return max;
 
# Function to find the minimum no.
# in a given array.
def DAC_Min(a, index, l):
    min = 0;
    if (index >= l - 2):
        if (a[index] < a[index + 1]):
            return a[index];
        else:
            return a[index + 1];
 
    # Logic to find the Minimum element
    # in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min):
        return a[index];
    else:
        return min;
 
# Driver Code
if __name__ == '__main__':
   
    # Defining the variables
    min, max = 0, -1;
 
    # Initializing the array
    a = [70, 250, 50, 80, 140, 12, 14];
 
    # Recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    # Recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
    print("The minimum number in a given array is : ", min);
    print("The maximum number in a given array is : ", max);
 
# This code is contributed by 29AjayKumar


输出
Maximum: 120
Minimum: 11