📜  法雷序列

📅  最后修改于: 2021-04-29 10:24:38             🧑  作者: Mango

Farey序列是针对n阶生成的序列。该序列具有在[0/0到1/1]范围内的所有有序数,并按升序排序,以使分母小于或等于n,并且所有数均采用简化形式,即4/4不可能存在减少到1/1。

例子:

F1 = 0/1, 1/1
F2 = 0/1, 1/2, 1/1
F3 = 0/1, 1/3, 1/2, 2/3, 1/1
.
.
F7 = 0/1, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 2/5,
     3/7, 1/2, 4/7, 3/5, 2/3, 5/7, 3/4, 4/5,
     5/6, 6/7, 1/1

Farey序列用于无理数,福特圆和
在黎曼假设中(有关更多详细信息,请参见此信息)

如何生成给定顺序的Farey序列?
这个想法很简单,我们考虑从1/1到n / n的每个可能的有理数。对于每个生成的有理数,我们检查它是否为简化形式。如果是,则将其添加到Farey序列。如果分子和分母的GCD为1,则有理数为简化形式。

下面是基于以上思想的实现。

C++
// C++ program to print Farey Sequence of given order
#include 
using namespace std;
  
// class for x/y (a term in farey sequence
class Term {
public:
    int x, y;
  
    // Constructor to initialize x and y in x/y
    Term(int x, int y)
        : x(x), y(y)
    {
    }
};
  
// Comparison function for sorting
bool cmp(Term a, Term b)
{
    // Comparing two ratio
    return a.x * b.y < b.x * a.y;
}
  
// GCD of a and b
int gcd(int a, int b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
  
// Function to print Farey sequence of order n
void farey(int n)
{
    // Create a vector to store terms of output
    vector v;
  
    // One by one find and store all terms except 0/1 and n/n
    // which are known
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j)
  
            // Checking whether i and j are in lowest term
            if (gcd(i, j) == 1)
                v.push_back(Term(i, j));
    }
  
    // Sorting the term of sequence
    sort(v.begin(), v.end(), cmp);
  
    // Explicitly printing first term
    cout << "0/1 ";
  
    // Printing other terms
    for (int i = 0; i < v.size(); ++i)
        cout << v[i].x << "/" << v[i].y << " ";
  
    // explicitely printing last term
    cout << "1/1";
}
  
// Driver program
int main()
{
    int n = 7;
    cout << "Farey Sequence of order " << n << " is\n";
    farey(n);
    return 0;
}


Python3
# Python3 program to print
# Farey Sequence of given order
  
# class for x/y (a term in farey sequence
class Term:
  
    # Constructor to initialize
    # x and y in x/y
    def __init__(self, x, y):
        self.x = x
        self.y = y
  
# GCD of a and b
def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)
  
# Function to print 
# Farey sequence of order n
def farey(n):
  
    # Create a vector to 
    # store terms of output
    v = []
  
    # One by one find and store 
    # all terms except 0/1 and n/n
    # which are known
    for i in range(1, n + 1):
        for j in range(i + 1, n + 1):
  
            # Checking whether i and j
            # are in lowest term
            if gcd(i, j) == 1:
                v.append(Term(i, j))
  
    # Sorting the term of sequence
    for i in range(len(v)):
        for j in range(i + 1, len(v)):
            if (v[i].x * v[j].y > v[j].x * v[i].y):
                v[i], v[j] = v[j], v[i]
  
    # Explicitly printing first term
    print("0/1", end = " ")
  
    # Printing other terms
    for i in range(len(v)):
        print("%d/%d" % (v[i].x, 
                        v[i].y), end = " ")
  
    # explicitely printing last term
    print("1/1")
  
# Driver Code
if __name__ == "__main__":
    n = 7
    print("Farey sequence of order %d is" % n)
    farey(n)
  
# This code is contributed by
# sanjeev2552


C++
// Efficient C++ program to print Farey Sequence of order n
#include 
using namespace std;
  
// Optimized function to print Farey sequence of order n
void farey(int n)
{
    // We know first two terms are 0/1 and 1/n
    double x1 = 0, y1 = 1, x2 = 1, y2 = n;
  
    printf("%.0f/%.0f %.0f/%.0f", x1, y1, x2, y2);
  
    double x, y = 0; // For next terms to be evaluated
    while (y != 1.0) {
        // Using recurrence relation to find the next term
        x = floor((y1 + n) / y2) * x2 - x1;
        y = floor((y1 + n) / y2) * y2 - y1;
  
        // Print next term
        printf(" %.0f/%.0f", x, y);
  
        // Update x1, y1, x2 and y2 for next iteration
        x1 = x2, x2 = x, y1 = y2, y2 = y;
    }
}
  
// Driver program
int main()
{
    int n = 7;
    cout << "Farey Sequence of order " << n << " is\n";
    farey(n);
    return 0;
}


Java
// Efficient Java program to print 
// Farey Sequence of order n
class GFG
{
  
// Optimized function to print 
// Farey sequence of order n
static void farey(int n)
{
    // We know first two terms are 0/1 and 1/n
    double x1 = 0, y1 = 1, x2 = 1, y2 = n;
  
    System.out.printf("%.0f/%.0f %.0f/%.0f", x1, y1, x2, y2);
  
    double x, y = 0; // For next terms to be evaluated
    while (y != 1.0) 
    {
        // Using recurrence relation to find the next term
        x = Math.floor((y1 + n) / y2) * x2 - x1;
        y = Math.floor((y1 + n) / y2) * y2 - y1;
  
        // Print next term
        System.out.printf(" %.0f/%.0f", x, y);
  
        // Update x1, y1, x2 and y2 for next iteration
        x1 = x2;
        x2 = x;
        y1 = y2;
        y2 = y;
    }
}
  
// Driver program
public static void main(String[] args)
{
    int n = 7;
    System.out.print("Farey Sequence of order " + n + " is\n");
    farey(n);
}
}
  
// This code is contributed by Rajput-Ji


Python3
# Efficient Python3 program to print
# Farey Sequence of order n
import math
  
# Optimized function to print Farey 
# sequence of order n
def farey(n):
      
    # We know first two terms are 
    # 0/1 and 1/n
    x1 = 0; 
    y1 = 1; 
    x2 = 1; 
    y2 = n;
      
    print(x1, end = "") 
    print("/", end = "")
    print(y1, x2, end = "") 
    print("/", end = "") 
    print(y2, end = " ");
  
    # For next terms to be evaluated
    x = 0;
    y = 0; 
    while (y != 1.0):
          
        # Using recurrence relation to
        # find the next term
        x = math.floor((y1 + n) / y2) * x2 - x1;
        y = math.floor((y1 + n) / y2) * y2 - y1;
  
        # Print next term
        print(x, end = "")
        print("/", end = "")
        print(y, end = " ");
  
        # Update x1, y1, x2 and y2 for 
        # next iteration
        x1 = x2; 
        x2 = x; 
        y1 = y2; 
        y2 = y;
  
# Driver Code
n = 7;
print("Farey Sequence of order", n, "is");
farey(n);
  
# This code is contributed by mits


PHP


C#
// Efficient C# program to print 
// Farey Sequence of order n
using System;
  
public class GFG
{
   
// Optimized function to print 
// Farey sequence of order n
static void farey(int n)
{
    // We know first two terms are 0/1 and 1/n
    double x1 = 0, y1 = 1, x2 = 1, y2 = n;
   
    Console.Write("{0:F0}/{1:F0} {2:F0}/{3:F0}", x1, y1, x2, y2);
   
    double x, y = 0; // For next terms to be evaluated
    while (y != 1.0) 
    {
        // Using recurrence relation to find the next term
        x = Math.Floor((y1 + n) / y2) * x2 - x1;
        y = Math.Floor((y1 + n) / y2) * y2 - y1;
   
        // Print next term
        Console.Write(" {0:F0}/{1:F0}", x, y);
   
        // Update x1, y1, x2 and y2 for next iteration
        x1 = x2;
        x2 = x;
        y1 = y2;
        y2 = y;
    }
}
   
// Driver program
public static void Main(String[] args)
{
    int n = 7;
    Console.Write("Farey Sequence of order " + n + " is\n");
    farey(n);
}
}
  
// This code is contributed by 29AjayKumar


输出:

Farey Sequence of order 7 is
0/1 1/7 1/6 1/5 1/4 2/7 1/3 2/5 3/7 1/2 4/7 
3/5 2/3 5/7 3/4 4/5 5/6 6/7 1/1

上述方法的时间复杂度为O(n 2 Log n),其中O(log n)是Euclid算法用于GCD的时间上限。

Farey序列具有以下属性[有关详细信息,请参见Wiki]

可以使用前两个项来递归地评估项x / y。以下是根据x n + 1 / y n + 1和x n / y n计算x n + 2 / y n + 2的公式。

x[n+2] = floor((y[n]+n) / y[n+1])x[n+1]– x[n]      
y[n+2] = floor((y[n]+n) / y[n+1])y[n+1]– y[n]    

我们可以使用以上属性进行优化。

C++

// Efficient C++ program to print Farey Sequence of order n
#include 
using namespace std;
  
// Optimized function to print Farey sequence of order n
void farey(int n)
{
    // We know first two terms are 0/1 and 1/n
    double x1 = 0, y1 = 1, x2 = 1, y2 = n;
  
    printf("%.0f/%.0f %.0f/%.0f", x1, y1, x2, y2);
  
    double x, y = 0; // For next terms to be evaluated
    while (y != 1.0) {
        // Using recurrence relation to find the next term
        x = floor((y1 + n) / y2) * x2 - x1;
        y = floor((y1 + n) / y2) * y2 - y1;
  
        // Print next term
        printf(" %.0f/%.0f", x, y);
  
        // Update x1, y1, x2 and y2 for next iteration
        x1 = x2, x2 = x, y1 = y2, y2 = y;
    }
}
  
// Driver program
int main()
{
    int n = 7;
    cout << "Farey Sequence of order " << n << " is\n";
    farey(n);
    return 0;
}

Java

// Efficient Java program to print 
// Farey Sequence of order n
class GFG
{
  
// Optimized function to print 
// Farey sequence of order n
static void farey(int n)
{
    // We know first two terms are 0/1 and 1/n
    double x1 = 0, y1 = 1, x2 = 1, y2 = n;
  
    System.out.printf("%.0f/%.0f %.0f/%.0f", x1, y1, x2, y2);
  
    double x, y = 0; // For next terms to be evaluated
    while (y != 1.0) 
    {
        // Using recurrence relation to find the next term
        x = Math.floor((y1 + n) / y2) * x2 - x1;
        y = Math.floor((y1 + n) / y2) * y2 - y1;
  
        // Print next term
        System.out.printf(" %.0f/%.0f", x, y);
  
        // Update x1, y1, x2 and y2 for next iteration
        x1 = x2;
        x2 = x;
        y1 = y2;
        y2 = y;
    }
}
  
// Driver program
public static void main(String[] args)
{
    int n = 7;
    System.out.print("Farey Sequence of order " + n + " is\n");
    farey(n);
}
}
  
// This code is contributed by Rajput-Ji

Python3

# Efficient Python3 program to print
# Farey Sequence of order n
import math
  
# Optimized function to print Farey 
# sequence of order n
def farey(n):
      
    # We know first two terms are 
    # 0/1 and 1/n
    x1 = 0; 
    y1 = 1; 
    x2 = 1; 
    y2 = n;
      
    print(x1, end = "") 
    print("/", end = "")
    print(y1, x2, end = "") 
    print("/", end = "") 
    print(y2, end = " ");
  
    # For next terms to be evaluated
    x = 0;
    y = 0; 
    while (y != 1.0):
          
        # Using recurrence relation to
        # find the next term
        x = math.floor((y1 + n) / y2) * x2 - x1;
        y = math.floor((y1 + n) / y2) * y2 - y1;
  
        # Print next term
        print(x, end = "")
        print("/", end = "")
        print(y, end = " ");
  
        # Update x1, y1, x2 and y2 for 
        # next iteration
        x1 = x2; 
        x2 = x; 
        y1 = y2; 
        y2 = y;
  
# Driver Code
n = 7;
print("Farey Sequence of order", n, "is");
farey(n);
  
# This code is contributed by mits

的PHP


C#

// Efficient C# program to print 
// Farey Sequence of order n
using System;
  
public class GFG
{
   
// Optimized function to print 
// Farey sequence of order n
static void farey(int n)
{
    // We know first two terms are 0/1 and 1/n
    double x1 = 0, y1 = 1, x2 = 1, y2 = n;
   
    Console.Write("{0:F0}/{1:F0} {2:F0}/{3:F0}", x1, y1, x2, y2);
   
    double x, y = 0; // For next terms to be evaluated
    while (y != 1.0) 
    {
        // Using recurrence relation to find the next term
        x = Math.Floor((y1 + n) / y2) * x2 - x1;
        y = Math.Floor((y1 + n) / y2) * y2 - y1;
   
        // Print next term
        Console.Write(" {0:F0}/{1:F0}", x, y);
   
        // Update x1, y1, x2 and y2 for next iteration
        x1 = x2;
        x2 = x;
        y1 = y2;
        y2 = y;
    }
}
   
// Driver program
public static void Main(String[] args)
{
    int n = 7;
    Console.Write("Farey Sequence of order " + n + " is\n");
    farey(n);
}
}
  
// This code is contributed by 29AjayKumar

输出:

Farey Sequence of order 7 is
0/1 1/7 1/6 1/5 1/4 2/7 1/3 2/5 3/7 1/2 4/7 
3/5 2/3 5/7 3/4 4/5 5/6 6/7 1/1

该解决方案的时间复杂度为O(n)

参考:
https://zh.wikipedia.org/wiki/Farey_sequence