📜  查找预期交换以对给定数组进行排序,其中交换任何反转对的概率相等

📅  最后修改于: 2022-05-13 01:56:04.695000             🧑  作者: Mango

查找预期交换以对给定数组进行排序,其中交换任何反转对的概率相等

给定一个由前N个自然数的排列组成的数组arr[] ,任务是找到对给定数组进行排序的预期交换次数,其中交换任何反转对的概率和交换任何非反转的概率相等对为 0。

例子:

方法:给定的问题可以在递归和回溯的帮助下使用记忆化来解决,它基于以下观察:

  • 数组中的反转被定义为两个索引(i, j) ,使得i < j 和 arr[i] > arr[j] 。在一次交换每个有效反转的整数并递归调用交换之后的排列直到整个排列被排序之后,可以递归地计算预期的交换次数。
  • 假设当前排列中有K个反转,并且在交换第i反转之后,对排列进行排序的预期交换次数由P i表示。因此,交换所有可能的反转后的预期交换次数将为(P 1 + P 2 + ... + P K )/K

使用上述观察,可以通过以下步骤解决给定问题:

  • 创建一个地图,比如存储给定排列的预期交换次数的备忘录
  • 创建一个递归函数expectedSwaps() ,它将排列作为参数并返回预期的交换次数。
  • expectedSwaps()函数中,如果当前排列的期望交换已经计算,则返回答案。否则,遍历每个有效反转并交换当前反转的索引,并在交换后递归调用排列。
  • 求变量中每次有效交换后预期交换的总和,比如res ,以及变量中的反转计数,比如K
  • 完成以上步骤后,打印res/K的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Stores result of each state of the
// array in a memoization table
map, double> memo;
 
// Recursive function to find expected
// number of swaps to sort given array
double expectedSwaps(vector a)
{
    // The value for the given permutation
    // is already calculated
    if (memo.count(a)) {
        return memo[a];
    }
 
    // Stores the expected number of ways
    double res = 0;
 
    // Stores the total operations done
    int K = 0;
 
    // Iterate for all possible pairs of
    // Inversions
    for (int i = 0; i < a.size(); i++) {
        for (int j = i + 1; j < a.size(); j++) {
 
            // For the current inversion
            // find the expected value
            if (a[i] > a[j]) {
                swap(a[i], a[j]);
 
                // Recursively Call
                res += 1 + expectedSwaps(a);
 
                // Backtrack
                swap(a[i], a[j]);
                K++;
            }
        }
    }
 
    // If permutation is already sorted
    if (K == 0)
        res = 0;
 
    // Calculate expected swaps for
    // current permutation
    else
        res /= K;
 
    // Return answer
    return memo[a] = res;
}
 
// Driver Code
int main()
{
    int N = 3;
    vector arr = { 3, 2, 1 };
 
    cout << expectedSwaps(arr);
 
    return 0;
}


Python3
# Python program for the above approach
# Stores result of each state of the
# array in a memoization table
memo = {}
 
# Recursive function to find expected
# number of swaps to sort given array
def expectedSwaps(a):
   
  # The value for the given permutation
  # is already calculated
  if (tuple(a) in memo):
    return memo[tuple(a)]
   
  # Stores the expected number of ways
  res = 0
 
  # Stores the total operations done
  K = 0
 
  # Iterate for all possible pairs of
  # Inversions
  for i in range(len(a)):
    for j in range(i + 1,len(a)):
       
      # For the current inversion
      # find the expected value
      if (a[i] > a[j]):
        temp = a[i]
        a[i] = a[j]
        a[j] = temp
         
        # Recursively Call
        res += 1 + expectedSwaps(a)
         
        #Backtrack
        temp = a[i]
        a[i] = a[j]
        a[j] = temp
        K += 1
         
  # If permutation is already sorted
  if (K == 0):
    res = 0
 
  # Calculate expected swaps for
  # current permutation
  else:
    res /= K;
 
  # Return answer
  memo[tuple(a)] = res
  return res
 
# Driver Code
N = 3
arr = [ 3, 2, 1 ]
print(expectedSwaps(arr))
 
# This code is contributed by rohitsingh07052.


Javascript


输出
2.33333

时间复杂度: O(N 2 N!)
辅助空间: O(N!)