BNU-FZH

fengzhenhua@outlook.com

简介

keysudo.sh是一个用于安全存储和调用 sudo 密码的 Bash 脚本工具,通过 GNOME Keyring 实现敏感信息的加密存储。脚本设计目标是通过密钥环系统减少密码的明文暴露,同时解决 sudo 验证失败导致的账户锁定问题。

主要功能

  • 🔐 自动将 sudo 密码存储至 GNOME Keyring
  • 🔄 支持 3 次验证尝试(可配置)
  • ⚠️ 智能检测系统环境(支持 Arch/RHEL 系)
  • 🔒 密码输入支持 systemd-ask-password 工具
  • 🛡️ 密码错误时自动重置 sudo 失败计数
  • 🚫 杜绝密码明文存储和传输

快速使用

基础用法

1
2
3
4
5
6
# 获取密码(自动触发存储流程)
syndns_password=$(./keysudo.sh)

# 使用示例(建议立即清理变量)
echo $syndns_password | sudo -S your_command
unset syndns_password

安装依赖

1
2
3
4
5
# Arch 系系统
sudo pacman -S pambase libsecret

# RHEL/CentOS 系系统
sudo yum install pam libsecret-tools

卸载密码

1
secret-tool clear syndns_password_key syndns_password

常见问题

Q1: 密码无法存储到密钥环

1
2
3
4
# 检查密钥环服务状态
gnome-keyring-daemon --start
# 验证存储功能
echo "test" | secret-tool store --label="Test" test_key test_value

Q2: sudo 被锁定后如何处理

1
2
3
4
5
# 显示当前失败计数(RHEL系)
sudo pam_tally2 --user $USER

# 强制解锁所有用户(Arch系)
sudo faillock --reset

程序源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#! /bin/bash
#
# Program : keysudo.sh
# Author : Zhen-Hua Feng(冯振华)
# Email : fengzhenhua@outlook.com
# Date : 2025-01-10 20:41
# CopyRight: Copyright (C) 2025--
# License : Distributed under terms of the MIT license.
#
# 定义标识符
SYN_KEY="syndns_password" # 密钥环中的唯一标识符
SYN_SUDO_NUM_MAX="3" # 确保这个数值与您系统中sudo验证次数一致,以免进入死循环
# 检测依赖,确保secret-tool正确安装
if ! command -v secret-tool &>/dev/null; then
echo "错误:需要安装 secret-tool(包名:libsecret-tools)" >&2
exit 1
fi
# 探测系统sud解锁程序
SYN_RES_CMD=""
if command -v faillock &>/dev/null; then
SYN_RES_CMD="faillock --user $USER --reset"
elif command -v pam_tally2 &>/dev/null; then
SYN_RES_CMD="pam_tally2 --user $USER --reset"
else
echo "错误:未找到可用SUDO解锁工具 !" >&2
echo "请安装:Arch系安装pambase,RHEL系安装pam" >&2
exit 1 # 正确终止脚本
fi
# 存储密码到 GNOME Keyring
# 测试密码过程中存在sudo次数限制,如果sudo被锁定了,那本脚本在首次没有完成密码保存的工作后将处于锁定状态
SYN_KEY_GET(){
local SYN_AMT="$SYN_SUDO_NUM_MAX"
while [[ "$SYN_AMT" -gt 0 ]]; do
SYN_KEY_X=$(secret-tool lookup syndns_password_key "$SYN_KEY")
if [[ -z "$SYN_KEY_X" ]]; then
unset SYN_KEY_DATA
# 使用专业密码输入工具
if command -v systemd-ask-password &>/dev/null; then
SYN_KEY_DATA=$(systemd-ask-password --timeout=30 "请求sudo密码:")
else
printf "$0 请求输入sudo密码(30秒超时):" >&2
# 增加超时后的清理逻辑
if ! read -rs -t 30 SYN_KEY_DATA; then
printf "\n输入超时,操作取消。\n" >&2
unset SYN_KEY_DATA
exit 1
fi
fi
if [[ -z "$SYN_KEY_DATA" ]]; then
printf "\n密码不能为空,请重新输入。\n" >&2
else
if printf "%s" "$SYN_KEY_DATA" | secret-tool store --label="Syndns Password" syndns_password_key "$SYN_KEY"; then
sudo -k
if printf "%s" "$SYN_KEY_DATA" | sudo -S -v 2>/dev/null; then
# 存储成功后立即清理
unset SYN_KEY_DATA
printf "\n密码已成功存储到 GNOME Keyring 中。\n" >&2
return 0
else
SYN_AMT=$((SYN_AMT - 1))
SYN_FAIL_RES "警告:当前系统可能需要手动重置失败计数!"
fi
else
printf "\n无法存储密码,请检查 GNOME Keyring 是否可用。\n" >&2
exit 1
fi
fi
else
sudo -k
if ! printf "%s" "$SYN_KEY_X" | sudo -S -v 2>/dev/null; then
SYN_AMT=$((SYN_AMT - 1))
secret-tool clear syndns_password_key "$SYN_KEY" # 清空密码,重新循环才能进入设置
SYN_FAIL_RES "警告:当前系统可能需要手动重置失败计数!"
else
return 0
fi
fi
done
printf "尝试次数已达上限,操作终止。\n" >&2
SYN_FAIL_RES "请切换至ROOT权限解除锁定: $SYN_RES_CMD"
exit 1
}
SYN_FAIL_RES(){
if grep -qi 'arch' /etc/os-release 2>/dev/null; then
faillock --user $USER --reset
else
# 优先显示传入的定制化提示
printf "$1 \n" >&2
# 补充建议命令(带sudo前缀)
[ -n "$SYN_RES_CMD" ] && echo "可尝试执行: sudo $SYN_RES_CMD" >&2
fi
}
sudo -k # 清除sudo缓存
SYN_KEY_GET
echo $SYN_KEY_X

ArchLinux是一款备受推崇的Linux发行版,以其滚动更新机制、最新软件包支持和高度可定制性而闻名。然而,在使用Paru从AUR(Arch User Repository)安装软件时,很多用户遇到了因依赖于GitHub上的资源无法访问而导致的问题。为了解决这一挑战,我最初开发了名为“ParuAxel.sh”的脚本,以帮助用户更顺畅地安装软件。

随着进一步的优化升级,我决定采用更为高效的多线程下载工具Aria2,并对脚本进行了全面改进。为了更好地反映这些变化,我将这个新版本的脚本重命名为“Paria.sh”。通过使用Aria2,“Paria.sh”不仅解决了由于网络限制导致的GitHub资源访问问题,还大幅提升了下载速度与稳定性,为用户提供了一个更加流畅可靠的软件包管理体验。

“Paria.sh”专注于增强ArchLinux用户的AUR软件安装过程,使得即使面对复杂的依赖关系或网络波动,也能轻松完成软件的下载与安装。它体现了我对提升用户体验的持续努力,旨在让每一位ArchLinux用户都能享受更加高效便捷的软件管理过程。

Paria.sh脚本及其配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#! /bin/sh
#
# Program: Paria.sh
# Version: V2.0
# Author : Zhen-Hua Feng
# Email : fengzhenhua@outlook.com
# Date : 2025-03-24 11:45
# Copyright (C) 2023-2025 feng <feng@arch>
#
# Distributed under terms of the MIT license.
#
GIT_DOMIN=`echo "$2" | cut -f3 -d'/'`;
GIT_OTHER=`echo "$2" | cut -f4- -d'/'`;
GIT_INIT="https://github.com/"
DNS_SERVERS="1.0.0.1,1.0.0.2,1.0.0.3"
GCF=/home/$USER/.gitconfig
GIT_SIT=($(grep -oP '\[url\s+"\Khttps://[^"]+' $GCF))
mirror_available() {
local url="$1"
if curl -fsL --max-time 5 --head "$url" >/dev/null 2>&1; then
return 0
else
return 1
fi
}
case "$GIT_DOMIN" in
"github.com")
GIT_URL="$2"
echo "Download from mirror $GIT_URL";
/usr/bin/aria2c --async-dns-server="$DNS_SERVERS" --split=12 --max-connection-per-server=15 -k 1M --auto-file-renaming=false -o "$1" "$GIT_URL" ;
if [[ $? -ne 0 ]]; then
echo "[WARN] GitHub 原始地址下载失败,启动镜像检测..."
if [ -e $GCF ]; then
GIT_SIT=($(grep -oP '\[url\s+"\Khttps://[^"]+' $GCF))
for mirror in "${GIT_SIT[@]}"; do
if [[ "${mirror}" =~ "/$" ]]; then
GIT_URL="${mirror}${GIT_PATH}"
else
GIT_URL="${mirror}/${GIT_PATH}"
fi
if mirror_available "${GIT_URL}"; then
/usr/bin/aria2c --split=12 --max-connection-per-server=15 -k 1M --auto-file-renaming=false -o "$1" "$GIT_URL" ;
if [[ $? -eq 0 ]]; then
exit 0 # 下载成功则退出
else
echo "[ERROR] 镜像下载失败: $GIT_URL (状态码: $?)" >&2
fi
fi
done
fi
# 所有镜像失败后直接退出(不回退 GitHub)
echo "[FATAL] 所有下载尝试失败,请检查网络或镜像配置"
exit 1
fi
;;
*)
/usr/bin/aria2c --split=12 --max-connection-per-server=15 -k 1M --auto-file-renaming=false -o "$1" "$2" ;
;;
esac
/etc/makepkg.conf 中对应DLAGENTS部分
1
2
3
4
5
6
DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u'
'ftp::/usr/bin/aria2c -s 15 -x 15 -k 1M --auto-file-renaming=false -o %o %u'
'http::/usr/bin/aria2c -s 15 -x 15 -k 1M --auto-file-renaming=false -o %o %u'
'https::/usr/bin/Paria %o %u'
'rsync::/usr/bin/rsync --no-motd -z %u %o'
'scp::/usr/bin/scp -C %u %o')
install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
#! /bin/sh
#
# 项目:install.sh
# 版本:V1.4
# Copyright (C) 2023 feng <feng@arch>
# Distributed under terms of the MIT license.
#
sudo pacman -S --needed --noconfirm aria &> /dev/null
sudo cp ./makepkg.conf /etc/makepkg.conf
sudo cp ./Paria.sh /usr/bin/Paria
sudo chmod 755 /usr/bin/Paria
echo "Paria 安装成功,paru配置完毕 !! "
exit

注意为了方便您的使用,请将上述三个脚本文件放置在同一个目录下,然后赋于执行权限,运行./intsll.sh即可完成安装。

ParuAxel 与 Paria 功能对比

特性 ParuAxel.sh (V1.4) Paria.sh (V2.0)
下载工具 curl(单线)或axel(多线程) aria2c(多线程,默认启用)
镜像检测逻辑 优先遍历镜像,失败后回退 GitHub 先尝试原始地址,失败后遍历镜像,不自动回退
URL 拼接处理 简单拼接,可能产生双斜杠或路径错误 检查结尾斜杠,确保路径拼接正确
DNS 配置 自定义 DNS 服务器(Cloudflare)
错误处理 简单回退,无详细日志 详细错误分级(WARN/ERROR/FATAL),明确退出码
镜像检测方法 wget --spider curl --head
代码结构 字符串处理复杂,多次替换 使用正则提取配置,逻辑更简洁

Git克隆修改为SSH

由于在执行依赖安装时,有时候Paru会调用git clone 命令,但是默认是从 https://github.com 克隆仓库,而当它无法访问时可以尝试配置好ssh后采用ssh方法来克隆,于是全局修改https://github.comgit@github.com:github.com.

~/.gitconfig
1
2
3
4
5
6
7
[user]
email = YourEmail
name = YourName
[url "git@github.com:"]
insteadOf = https://github.com/
[init]
defaultBranch = main

通过浏览器登录路由的方法

  1. 确保连接:首先,确保你的设备(如电脑或手机)已经连接到你想要管理的网络。

  2. 打开浏览器:在你的设备上打开一个网页浏览器(如Chrome、Firefox等)。

  3. 输入IP地址:在浏览器的地址栏中输入图片中显示的默认路由IP地址 192.168.50.1,然后按回车键。

  4. 登录界面:你会看到一个登录界面,要求你输入用户名和密码。这些信息通常可以在路由器的说明书上找到,或者使用默认的用户名和密码(如 admin/admin)。如果你之前修改过这些信息,那么请输入你之前设置的用户名和密码。

  5. 进入管理界面:成功登录后,你将进入路由器的管理界面,在这里你可以进行各种设置,如更改无线网络名称(SSID)、设置密码、调整安全设置等。

如果你不确定如何操作,建议参考路由器的用户手册或联系制造商的技术支持。其中第3步中的IP地址应当替换成你自己的电脑的默认网关。

查询默认路由

在不同操作系统中,可以通过图形界面(GUI)轻松查询默认路由(即默认网关), 具体操作步骤:

  • Windows:通过“网络和共享中心” → 当前连接 → “详细信息” 查看默认网关。
  • Linux:通过网络设置 → 当前连接 → IPv4 设置 查看默认网关。
  • macOS:通过“网络”设置 → 当前连接 → “高级” → “TCP/IP” 查看路由器地址。

通过这些图形界面操作,你可以轻松找到默认路由(即路由器的 IP 地址)。

Linux发行版的基本使用

发行版 流行程度 安装命令 删除命令(保留/删除配置) 发行规则
Ubuntu ★★★★★ sudo apt install ... sudo apt remove ...(✓)
sudo apt purge ...(🗑️)
❌(定期)
Debian ★★★★☆ sudo apt install ... sudo apt remove ...(✓)
sudo apt purge ...(🗑️)
❌(定期)
Fedora ★★★☆☆ sudo dnf install ... sudo dnf remove ...(✓)
删除配置 ❗(需手动)
❌(定期)
Arch Linux ★★★☆☆ sudo pacman -S ... sudo pacman -R ...(✓)
sudo pacman -Rns ...(🗑️)
✅(滚动)
Linux Mint ★★★☆☆ sudo apt install ... sudo apt remove ...(✓)
sudo apt purge ...(🗑️)
❌(定期)
CentOS ★★★☆☆ sudo dnf install ... sudo dnf remove ...(✓)
删除配置 ❗(需手动)
❌(定期)
Manjaro ★★★☆☆ sudo pacman -S ... sudo pacman -R ...(✓)
sudo pacman -Rns ...(🗑️)
✅(滚动)
openSUSE ★★☆☆☆ sudo zypper install ... sudo zypper remove ...(✓)
删除配置 ❗(需手动)
❌/✅
Red Hat ★★★☆☆ sudo yum install ... sudo yum remove ...(✓)
删除配置 ❗(需手动)
❌(定期)
Kali Linux ★★☆☆☆ sudo apt install ... sudo apt remove ...(✓)
sudo apt purge ...(🗑️)
❌(定期)
Void Linux ★★☆☆☆ sudo xbps-install ... sudo xbps-remove ...(✓)
删除配置 ❗(需手动)
✅(滚动)

注意:openSUSE 分为Leap版定期和Tumbleweed版滚动)

Linux发行版性能对比(截至2024年)

一、通用性能(基于AMD锐龙9 9950X)

发行版 星级(★) 说明
Clear Linux ★★★★★ 英特尔深度优化,性能提升最高16%,适合高性能计算和服务器场景。
CachyOS ★★★★☆ 轻量快速,基于Arch Linux,适合现代硬件和桌面用户。
Arch Linux ★★★★☆ 滚动更新,硬件兼容性好,性能接近前沿但需手动优化。
Fedora ★★★☆☆ 内核前沿但稳定性稍弱,适合开发测试。
Ubuntu 24.10 ★★★☆☆ 非LTS版本性能较好,但Snaps可能影响部分应用。
Ubuntu LTS ★★☆☆☆ 稳定性最佳但性能最弱,适合长期稳定需求。

二、服务器性能(企业级场景)

发行版 星级(★) 说明
Rocky Linux ★★★★★ RHEL兼容,稳定性与性能最佳,适合企业级服务器和云计算。
AlmaLinux ★★★★★ 与Rocky Linux同级,社区驱动,性能与稳定性并重。
Clear Linux ★★★★☆ 适合高性能计算任务,但需特定硬件优化。
Debian ★★★☆☆ 极稳定但软件较旧,适合长期运行服务。
Ubuntu LTS ★★★☆☆ 社区支持强,适合Web服务器和通用企业场景。
Fedora ★★☆☆☆ 开发测试用,不适合长期生产环境。

三、桌面/开发性能

发行版 星级(★) 说明
CachyOS ★★★★☆ 启动快、低延迟,适合游戏和日常使用。
Arch Linux ★★★★☆ 滚动更新,硬件支持最佳,适合开发者。
Manjaro ★★★★☆ 基于Arch,新手友好,性能接近Arch但更稳定。
Ubuntu LTS ★★★☆☆ 平衡性最佳,新手首选,但Snaps可能影响部分应用。
Fedora ★★★☆☆ 开发工具链前沿,适合测试新功能。
Kali Linux ★★☆☆☆ 安全工具优化,但非通用场景性能无优势。

四、其他关键性能维度

硬件兼容性

发行版 星级(★) 说明
Arch Linux ★★★★★ 滚动更新,支持最新硬件驱动。
Clear Linux ★★★★☆ 英特尔深度优化,兼容性极佳。
Ubuntu LTS ★★★☆☆ 社区支持强,但旧版本可能兼容性不足。

轻量级性能

发行版 星级(★) 说明
CachyOS ★★★★☆ 系统轻量,资源占用低。
MX Linux ★★★★☆ 基于Debian,适合老旧硬件。
veket ★★★☆☆ 资源高效,针对老旧计算机优化。

安全性能

发行版 星级(★) 说明
Kali Linux ★★★★☆ 专为渗透测试设计,安全工具高度优化。
Debian ★★★☆☆ 源代码高度审查,适合安全敏感场景。

总结建议

  • 极致性能:Clear Linux(x86优化最佳)或 CachyOS(轻量快速)。
  • 通用场景:Ubuntu LTS(新手首选)或 Manjaro(Arch友好版)。
  • 服务器:Rocky Linux/AlmaLinux(RHEL兼容,稳定性最佳)。
  • 开发者:Arch Linux(滚动更新)或 Fedora(前沿技术)。
  • 老旧硬件:MX Linux 或 veket(资源高效)。

星标说明
★★★★★:性能最优,推荐首选;
★★★★☆:性能优秀,适合特定场景;
★★★☆☆:性能中等,平衡性较好;
★★☆☆☆:性能较弱,需谨慎选择。

在Linux环境中,了解如何有效地查询和展示系统信息是非常重要的。无论是为了调试、监控还是单纯地想了解更多关于你正在使用的硬件和软件的信息,下面列出的一系列命令和工具都将对你有所帮助。


符号说明:✅需要安装,❌无需安装,🔑需sudo权限,🔓无需sudo权限。


系统级硬件信息

命令/工具 功能描述 安装 Sudo
lshw 硬件树状信息(支持过滤、XML输出) 🔑
inxi 一键查询系统/硬件综合信息 🔓
dmidecode 主板/BIOS详细信息(需root权限) 🔑
neofetch 图形化系统信息(支持主题) 🔓
screenfetch ASCII艺术系统信息 🔓
fastfetch 高性能跨平台系统信息工具 🔓
hyfetch 支持LGBTQ+主题的系统信息工具 🔓
sysinfo 简单轻量级系统信息工具 🔓

CPU信息

命令/工具 功能描述 安装 Sudo
lscpu CPU架构/核心/缓存信息 🔓
/proc/cpuinfo CPU原始参数(型号/频率/物理核心) 🔓
cpufreq-info CPU频率监控(需cpufrequtils 🔓

存储设备

命令/工具 功能描述 安装 Sudo
lsblk 块设备列表(含挂载点/UUID) 🔓
fdisk -l 磁盘分区表(MBR/GPT支持) 🔑
parted -l 分区详细信息(GPT/MBR支持) 🔑
smartctl 硬盘SMART状态(需驱动) 🔑
df 文件系统空间使用统计 🔓
du 目录/文件空间分析 🔓

网络信息

命令/工具 功能描述 安装 Sudo
ip 网络接口/IP/路由表 🔓
ethtool 网卡参数(速度/驱动/链路状态) 🔑
lspci PCI设备列表(含网卡) 🔓
netstat 网络连接/路由统计 🔓
ss 套接字连接状态 🔓
curl 网络资源下载(HTTP/HTTPS/FTP) 🔓

GPU/显卡信息

命令/工具 功能描述 安装 Sudo
lspci 显卡PCI信息(型号/厂商) 🔓
nvidia-smi NVIDIA显卡状态(温度/显存/功耗) 🔓
glxinfo OpenGL/显卡驱动信息 🔓
radeontop AMD GPU实时监控 🔓

主板和BIOS

命令/工具 功能描述 安装 Sudo
dmidecode BIOS/主板硬件信息 🔑
lshw 主板芯片组/总线信息 🔑

USB设备

命令/工具 功能描述 安装 Sudo
lsusb USB设备列表(厂商/速度) 🔓
usb-devices USB设备详细信息(路径/驱动) 🔓

温度和传感器

命令/工具 功能描述 安装 Sudo
sensors CPU/GPU温度/风扇/电压监控 🔑
htop 实时资源监控(含温度) 🔓

其他设备

命令/工具 功能描述 安装 Sudo
lspci -v 详细PCI设备信息(驱动/配置) 🔓
dmesg 系统启动日志(硬件检测/错误) 🔓

系统版本查询

命令/工具 功能描述 安装 Sudo
lsb_release -a 发行版信息(名称/版本/代号) 🔓
cat /etc/os-release 系统版本详细信息(文件) 🔓
uname -a 内核版本及系统信息 🔓

关键说明

  1. Fetch类工具
    • fastfetch:高性能跨平台工具,推荐优先使用。
    • hyfetch:支持主题定制,适合个性化需求。
    • neofetch/screenfetch:经典工具,但前者已停止维护。
  2. 专业检测工具
    • hwinfo:详细硬件检测(需安装,支持传感器)。
    • lshw:综合硬件树状信息(支持XML/HTML输出)。
    • dmidecode:BIOS/主板深度信息(需root权限)。
  3. 网络与存储
    • ethtool:网卡参数调整(需sudo)。
    • smartctl:硬盘健康状态检测(需smartmontools)。
  4. 系统版本
    • /etc/os-release:标准系统版本文件,跨发行版通用。

安装建议

  • 基础工具sudo pacman -S lshw dmidecode neofetch inxi
  • 进阶工具sudo pacman -S hwinfo smartmontools nvidia-smi
  • Fetch类sudo pacman -S fastfetch hyfetch

关于蒙特卡洛方法,我已经连续发布了三篇博文:

在第一篇文章中我们探讨了蒙特卡洛方法使用面积法计算圆周率的经典案例,对MC方法有了一个初步的认识,在第二篇文章中我们在MC方法中使用不同的公式计算圆周率,得到了影响MC方法精度的条件,在第三篇文章中根据第二篇文章得到的条件实现了高精度计算圆周率的一个公式,从而验证了提高MC精度的条件。本文进一步,基于第三篇文章,在程序实现上将写死的程序代码以循环程序自动化。同时,引入mpmath库,实现迭代求根式的精度拓展,但是仍然使用numpy进行随机采样。

Python3 代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#! /usr/bin/env python3
# vim:fenc=utf-8
import numpy as np
from mpmath import mp, mpf
# 修改为 40 位十进制精度
mp.dps = 40

# 定义函数f(x)
def f(x):
return 1/(1-x**2)**0.5

# Monte Carlo方法求积分
def monte_carlo_integral(f, m, b, num_samples=1000):
# 根据半角公式用m设定嵌套次数
count = 0
while count < m:
b = mp.sqrt(1/2-mp.sqrt(1-b**2)/2)
count +=1
# 先用半角公式根据b计算a
a = mp.sqrt(1/2-mp.sqrt(1-b**2)/2)
# 在区间[a, b]内随机生成num_samples个样本点
samples = np.random.uniform(a, b, num_samples)

# 计算这些样本点对应的函数值
y_values = f(samples)

# 根据平均高度估计积分值,乘以区间的宽度得到近似面积
integral_estimate = 2**(m + 3)*(b - a) * np.mean(y_values)

return integral_estimate

# 使用Monte Carlo方法估计积分
estimated_integral = monte_carlo_integral(f,42, mp.sqrt(2)/2)

print("Pi", estimated_integral)

计算结果

  • 运行程序得到的结果: 3.14159265358979313874736836854190094502
  • 资源消耗情况: 0.08s user 0.02s system 98% cpu 0.099 total
  • 按现有资料\(\pi\)的前20位精确结果为3.1415926535 8979323846, 对比可知我们的程序可以精确到小数点后15位, 用时仅0.08s, 所以这是一个不错的结果。

优化的细节

  • 动态精度控制:通过循环,使用参数m灵活调整精度(如m=42时,区间极小,方差极低)。
  • 高效性:样本需求低(1000), 计算速度快。
  • 可拓展性:增加m可进一步提高精度,代码结构清晰,易于维护。

在这四篇博客中,我们从初步了解蒙特卡罗(MC)方法开始,逐步进行优化改进,展示了三种能够计算圆周率的程序。其中,本文介绍的第三个程序以其高效性和灵活性脱颖而出,特别适合需要高精度结果并希望简化手动计算的场景。然而,值得注意的是,m的取值并非越大越好,因为随着m增大,随机点的取值区间(a,b)会减少,加之本程序使用了通常采用双精度浮点数的np.random.uniform 进行随机取样,为了确保精度,m需要保持在一个适当的范围内。此外,np.mean的使用也限制了精度的进一步提升。如果想要进一步提高利用蒙特卡罗方法计算圆周率的精度,可以从调整m的取值和改进均值计算方式这两个方面入手。尽管如此,蒙特卡罗方法的核心价值在于在一定精度下快速提供那些常规方法难以计算或计算量极大的问题的结果,因此本文在这些考量基础上未对精度做进一步优化,但指明了可能的改进路径,以期与读者共同探讨技术细节。

通过文章蒙特卡洛方法计算圆周率:积分公式选择的方差分析, 我们可以得到提高蒙特卡洛方法计算精度的方法:

  1. 确保函数的平滑性,这样可以减少方差,于是每次随机点都更加接近平均值。
  2. 减少积分区间,这样同样的随机点数,采样密度更高,有效点更多,所以误差更小。

半角公式的选择

本文就来验证这两条规则,于是仍然选择反正弦三角函数,但是使用半角公式不断减小积分区间, 于是我们选择了\(\frac{\pi}{24576}\)作为积分值,即取积分:

\[ \pi=24576\int_0^b\frac{1}{\sqrt{1-x^2}}dx\]

其中\(b\)

\[ b=\frac{1}{2}\sqrt{2-\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{2+\sqrt{3}}}}}}}}}}}} \]

Python代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#! /usr/bin/env python3
# vim:fenc=utf-8
import numpy as np

# 定义函数f(x)
def f(x):
return 1/(1-x**2)**0.5

# Monte Carlo方法求积分
def monte_carlo_integral(f, a, b, num_samples=1000):
# 在区间[a, b]内随机生成num_samples个样本点
samples = np.random.uniform(a, b, num_samples)

# 计算这些样本点对应的函数值
y_values = f(samples)

# 根据平均高度估计积分值,乘以区间的宽度得到近似面积
integral_estimate = (b - a) * np.mean(y_values)

return 24576*integral_estimate

# 使用Monte Carlo方法估计积分
a, b = 0, np.sqrt(2-np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(2+np.sqrt(3)))))))))))))/2 # 定义积分区间
estimated_integral = monte_carlo_integral(f, a, b)

print("Pi", estimated_integral)

上述程序计算了\(\frac{\pi}{6}\)\(\frac{1}{2^{12}}\), 随机点只取了1000, 运行结果为 3.1415926538918395, 这个精度已经相当高了,计算量也急剧下降。所以对比之前的文章我们通过半角公式降低的计算量的同时,有效提高了计算精度。这个例子说明,对于同一个物理或数学问题,设计不同的算法,给出不同的公式是相当重要的事情。

在使用蒙特卡洛方法计算圆周率时,选择积分公式的关键在于方差的大小实现的效率。本文通过数学推导和实验验证,对比两种常见积分公式的优劣。


1. 积分公式的数学等价性

两个积分的数学结果均为π,但被积函数特性不同:

  • 公式1
    \[ 2 \int_0^1 \frac{1}{\sqrt{1 - x^2}} \, dx = \pi \]
    被积函数 \(f_1(x) = \frac{1}{\sqrt{1 - x^2}}\)\(x \to 1\) 时发散,导致数值计算的不稳定性。

  • 公式2
    \[ 2 \int_{-1}^1 \sqrt{1 - x^2} \, dx = \pi \]
    被积函数 \(f_2(x) = \sqrt{1 - x^2}\) 在区间 \([-1, 1]\) 上有界且连续,方差更小。


2. 蒙特卡洛方法的方差分析

2.1 公式1的方差问题

  • 发散特性
    \(f_1(x)\)\(x \to 1\) 处趋向无穷大,导致蒙特卡洛采样时方差显著增大。例如,当 \(x = 0.99\) 时,\(f_1(x) \approx 7\),远高于平均值 \(\pi/2 \approx 1.57\),极端值会严重干扰估计结果。

  • 实现挑战
    需要均匀采样 \(x \in [0, 1]\),但靠近 \(x = 1\) 的点对结果贡献极大,易引入噪声。

2.2 公式2的方差优势

  • 有界性
    \(f_2(x)\) 的值域为 \([0, 1]\),方差远小于公式1。例如,\(N=10^6\) 次采样时,公式2的估计误差通常比公式1低一个数量级。

  • 数值稳定性
    无需处理函数发散问题,所有采样点的贡献均在可控范围内。


3. 实验验证:方差的量化对比

假设使用 \(N\) 次采样:

  • 公式1
    由于 \(f_1(x)\) 的发散性,方差 \(D_1 \propto \int_0^1 \left( \frac{1}{\sqrt{1-x^2}} \right)^2 dx = \infty\)(发散)。

  • 公式2
    方差 \(D_2 = \int_{-1}^1 \left( \sqrt{1-x^2} \right)^2 dx - \left( \frac{\pi}{2} \right)^2 = \frac{\pi}{2} - \frac{\pi^2}{4} \approx 0.43\),远小于公式1。


4. 代码实现对比

4.1 公式2的C++实现(高效且低方差)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import random
import math

def estimate_pi(n):
count = 0
for _ in range(n):
x = random.uniform(-1, 1) # 生成x ∈ [-1, 1]
y = random.uniform(0, 1) # 生成y ∈ [0, 1]
if y <= math.sqrt(1 - x**2): # 判断是否在半圆内
count += 1
# 计算公式:2 * (积分值) = 2 * (count/N * 矩形面积)
return 2.0 * (count * 2.0 / n) # 矩形面积为2(宽2×高1)

# 示例:使用100万个样本
print(f"Estimated π: {estimate_pi(1000000)}")

4.2 公式1的Python实现(高方差问题)

1
2
3
4
5
6
7
8
9
10
import numpy as np

def monte_carlo_formula1(n):
x = np.random.uniform(0, 1, n)
f = 1 / np.sqrt(1 - x**2)
integral = np.mean(f)
return 2 * integral

# 测试示例(方差极大)
print(monte_carlo_formula1(1000000)) # 结果可能波动明显

5. 结论

公式2(\(2\int_{-1}^{1} \sqrt{1 - x^2} \, dx\))是更优选择,原因如下:

  1. 方差更小:被积函数 \(\sqrt{1 - x^2}\) 在区间 \([-1, 1]\) 上有界且连续,使得蒙特卡洛方法的收敛速度更快。
  2. 数值稳定性:无需处理函数发散问题(如公式1中 \(\frac{1}{\sqrt{1-x^2}}\)\(x \to 1\) 处的发散),避免极端值对估计结果的干扰。
  3. 计算效率:在相同采样次数下,公式2的估计误差显著低于公式1,且计算过程更稳定。

选择积分公式时,应优先考虑被积函数的有界性光滑性,以降低蒙特卡洛方法的方差,从而提升计算效率。

如果 TeXstudio 出现问题无法打开或闪退,你可以尝试恢复其默认设置。TeXstudio 将其设置存储在一个名为 texstudio.ini 的配置文件中。要恢复默认设置,你需要删除或重命名这个文件,这样 TeXstudio 在下次启动时会生成一个新的默认配置文件。

操作步骤

1. 关闭 TeXstudio

确保 TeXstudio 已经完全关闭。如果它因为错误而无法正常关闭,请通过任务管理器强制结束它的进程。

2. 找到配置文件

  • Windows: 通常位于用户目录下的 AppData\Roaming\texstudio\texstudio.ini。注意 AppData 文件夹是隐藏的,你可能需要在资源管理器中显示隐藏的文件和文件夹才能看到它。
  • macOS: 配置文件一般位于 ~/Library/Preferences/texstudio.ini
  • Linux: 对于大多数发行版来说,配置文件可以在 ~/.config/texstudio/texstudio.ini 找到。

3. 删除或重命名配置文件

为了安全起见,你可以先尝试重命名该文件(例如,添加 .bak 后缀),而不是直接删除它。这样,如果你发现新的默认设置有问题,还可以恢复原来的配置。

4. 重新启动 TeXstudio

现在再次启动 TeXstudio,程序将会使用默认设置启动。

5. 验证更改

检查是否所有的问题都得到了解决,并根据需要重新配置你的偏好设置。

注意:此过程将删除所有自定义设置,包括快捷键、语法高亮设置等。如果你有重要的自定义设置,建议在执行上述步骤前备份相关的配置信息。

LibreOffice是一款开源的办公软件套件,能够提供文字处理、电子表格、演示文稿、绘图、数据库等多种功能,适用于Windows、MacOS以及Linux等多种操作系统。然而我在ArchLinux使用LibreOffice时遇到一些问题,本文记录这些问题的解决方案。

取消表格选中时高对比度

2025年03月14日星期五阴北京市, 当安装好LibreOffice, 默认开启了高对比度,这导致每次选中表格的单元格时都是黑色的,相当不雅观。解决方法为:工具选项LibreOffice无障碍辅助高对比度禁用.

工具栏图标模糊的解决方法

2025年03月14日星期五阴北京市, 在4k显示器使用ArchLinux系统,LibreOffice默认开启的工具栏图标不是svg格式,这导致了工具栏图标模糊,解决方法为:工具选项LibreOffice视图主题选择任何一款svg图标.