关于那些奇葩的排序算法……

~~机房划水~~

一、猴子排序

基于无限猴子定理的排序算法,

1.0、简单介绍

爱丁顿在1929年阐述过一个“无限猴子理论”,就是说“如果许多猴子任意敲打打字机键,最终可能会写出大英博物馆所有的书”。

书可以看作是字母的组合,大英博物馆所有的书作为有限集是包含在字母的组合这个无限集之中的。有限集在无限集中出现的概率不为零,这也是你说“概率肯定不为零”的原因。问题就在于“字母的组合”和“许多猴子任意敲打打字机键”两个无限集是否等价。

如果这些猴子都打出的是同样而且重复的东西,能打出现大英博物馆所有的书吗?如果说没有条件可以保证猴子都打出的是同样而且重复的东西,那么有条件可以保证猴子打出东西的不是同样而且不重复吗?额,这只是一个悖论。

另,千万不要小看无限猴子定理,在大模型的训练中,无限猴子是可以转换成序列猴子,为大模型训练提供了无限可能,感兴趣参考无限猴子定理:大模型训练的无限可能性 - 知乎 (zhihu.com)

2.0、代码实现

时间复杂度可以说是十分的不稳定,复杂度范围呢?额,大概在O(1)O(\infty)。也就是说,猴子可能运气很好,只用了一秒就打印出了正确的字符串,反之,猴子可能从宇宙诞生时开始打,到2024年依然在打根本没打对有点惨啊……

下面给出排序代码:

# author: code lin
# datetime: 2024/5/19 11:21
# function: 猴子排序算法

import random
import time


def is_sorted(arr):
    # 检查数组是否已排序
    for i in range(1, len(arr)):
        if arr[i - 1] > arr[i]:
            return False
    return True


def monkey_sort(arr):
    attempts = 0
    start_time = time.time()

    while not is_sorted(arr):
        random.shuffle(arr)  # 随机打乱列表
        attempts += 1  # 尝试数+1
        print(f'第{attempts}次:' + str(arr))

    end_time = time.time()
    elapsed_time = end_time - start_time  # 耗时

    return arr, attempts, elapsed_time


if __name__ == "__main__":
    # 生成一个随机数组,作为排序的输入
    input_array = [random.randint(1, 1000) for _ in range(10)]

    sorted_array, attempts, elapsed_time = monkey_sort(input_array)

    print("原始数组:", input_array)
    print("排序后的数组:", sorted_array)
    print("排序尝试次数:", attempts)
    print("排序耗时(秒):", elapsed_time)

下面是Java :

package top.caituotuo.sortUtil;

import com.google.common.primitives.Ints;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 * author: code lin
 * datetime: 2024/5/19 12:04
 * function: Collections.shuffle()、Ints api应用
 */
public class MonkeySort {
    public static void main(String[] args) {
        // 生成一个包含10个随机整数的数组(范围在1到1000之间)
        int[] inputArray = new int[10];
        Random rand = new Random();
        for (int i = 0; i < inputArray.length; i++) {
            inputArray[i] = rand.nextInt(1000) + 1;
        }

        System.out.println("原始数组: " + Arrays.toString(inputArray));
        monkeySort(inputArray);
    }

    public static void monkeySort(int[] nums) {
        int attempts = 0;
        long startTime = System.currentTimeMillis();
        out:
        while (true) {
            List<Integer> tempList = Ints.asList(nums);
            Collections.shuffle(tempList);
            int[] result = Ints.toArray(tempList);

            for (int i = 1; i < result.length; i++) {
                if (result[i - 1] > result[i]) {
                    attempts++;
                    System.out.printf("第%s次: %s%n", attempts, Arrays.toString(result));
                    continue out;
                }
            }

            attempts++;
            System.out.printf("第%s次: %s%n", attempts, Arrays.toString(result));

            // 将排好序的结果复制回 nums 数组
            System.arraycopy(result, 0, nums, 0, result.length);
            break;
        }

        long endTime = System.currentTimeMillis();
        double elapsedTime = (endTime - startTime) / 1000.0;

        System.out.println("排序后的数组: " + Arrays.toString(nums));
        System.out.println("排序尝试次数: " + attempts);
        System.out.println("排序耗时(秒): " + elapsedTime);
    }
}

要算多久看你运气。

二、睡眠排序

1.0、简单介绍

睡眠排序算法是一个奇特而有趣的概念,其做法就是根据数字数组创建多个线程,并使每个线程休眠的时间与其对应的数字值成正比,数值越小的线程就会越早‘醒’来,数值越大的线程就会越晚醒来,这样就完成了对数据的排序。

听起来是不是很有趣,但实际上,睡眠排序面临许多问题,包括线程创建和管理的开销,以及对于小数值和相同数值的处理。因此,它实际上并不是一个可行的排序算法,而是一种有趣的编程挑战和思考实验。

2.0、代码实现

tips:下面代码并没有考虑负数懒得写

Java:

package top.caituotuo.sortUtil;

/**
 * author: code lin
 * datetime: 2024/5/19 12:10
 * function: 睡眠排序算法
 */

import java.util.Arrays;
import java.util.Random;

public class SleepSort {
    public static void sleepSortAndPrint(final int[] nums) {
        final int[] sortedArray = new int[nums.length];
        final int[] index = {0};

        long startTime = System.currentTimeMillis();

        for (int num : nums) {
            new Thread(() -> {
                try {
                    Thread.sleep(num); // 休眠时间为当前数字的值
                    sortedArray[index[0]++] = num;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

        // 等待所有线程完成
        while (index[0] < nums.length) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        long endTime = System.currentTimeMillis();
        double elapsedTime = (endTime - startTime) / 1000.0;

        System.out.println("排序后的数组: " + Arrays.toString(sortedArray));
        System.out.println("排序耗时(秒): " + elapsedTime);
    }

    public static void main(String[] args) {
        // 生成一个包含10个随机整数的数组(范围在1到100之间)
        int[] inputArray = new int[10];
        Random rand = new Random();
        for (int i = 0; i < inputArray.length; i++) {
            inputArray[i] = rand.nextInt(100) + 1;
        }
        System.out.println("原始数组: " + Arrays.toString(inputArray));
        sleepSortAndPrint(inputArray);
    }
}

Python:

# author: code lin
# datetime: 2024/5/19 12:15
# function: 睡眠排序算法
import random
import threading
import time


def sleep_sort(nums):
    sorted_array = []

    def sleep_and_append(num):
        time.sleep(num)
        sorted_array.append(num)

    # 记录开始时间
    start_time = time.time()

    threads = []
    for num in nums:
        thread = threading.Thread(target=sleep_and_append, args=(num,))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    print("排序后的数组:", sorted_array)
    # 计算时间差
    print("排序耗时(秒):", time.time() - start_time)


if __name__ == "__main__":
    input_array = [random.randint(1, 10) for _ in range(5)]
    print("原始数组:", input_array)
    sleep_sort(input_array)

三、总结

看完了这两个神奇沙雕的算法,你有什么看法呢?这应该也是人类智慧的一种体现吧。

以上,完。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值