快速找出满足所需比值的一对电阻值 - Python 函数实现

news2024/11/15 18:03:58

常用的5% 和1% 精度电阻的阻值满足E24 数系,基数只能在这个数系里取,再乘上10 的n 次幂。E24 数系如下图:

在这里插入图片描述
之前我都是人肉一个一个试的,凭运气挑,终于忍不住想整个一劳永逸的小工具。

代码

对于给定的比值,用一个python 函数暴力搜索,将所有正好满足比值的组合全部输出,如果没有正好等于的,就只返回一个偏差最小的组合,代码如下:

from typing import List, Tuple

def find_e24_resistor_pair(target_ratio: float) -> List[Tuple[float, float, float]]:
    """
    在 E24 优先数系中找到两个电阻值,使它们的比值最接近给定的比值。
    如果有多个解,返回所有较小值不相等且在 1~10 范围内的解。
    如果没有精确匹配的解,返回偏差最小的一组解。
    每个解都是一个三元组 (r1, r2, diff),其中 r1 和 r2 是电阻值,diff 是偏差。

    :param target_ratio: 目标比值
    :return: 电阻值组合列表
    """
    e24 = [1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7,
            3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8,
            7.5, 8.2, 9.1]
    result = []
    min_diff = float('inf')
    epsilon = 1e-9
    min_exponent = math.floor(math.log10(e24[0] * target_ratio))
    max_exponent = min_exponent + 1
    for r2 in e24:
        for r1_base in e24:
            for i in range(min_exponent, max_exponent + 1):
                r1 = r1_base * (10 ** i)
                ratio = r1 / r2
                diff = abs(ratio - target_ratio)
                if diff < epsilon:
                    result.append((r1,r2,diff))
                elif diff < min_diff:
                    min_diff = diff
                    min_result = (r1,r2,diff)
    if len(result) == 0:
        result.append(min_result)

    return result

这个函数的搜索过程是:先把分子r2 的取值范围固定在10 的0 次幂,也就是1.1, 1.2, … 9.1 这些E24 数系的基数,然后根据给定的比值,计算分母r1 的搜索范围,最后依次遍历分子和分母的所有取值组合。比如,若比值为5,分子最小值为1.0,最大9.1,则分母的取值范围是5 ~ 45.5,也就是10 的0 次幂到1 次幂,而且很显然,无论比值有多大,分母的最大值和最小值最多只能差一个数量级。

如果目标比值为3,这个函数会返回一个列表,里面是精确匹配的四个组合3 / 1、3.3 / 1.1 、3.6 / 1.2、3.9 / 1.3:

[
 (3.0, 1.0, 0.0), 
 (3.3, 1.1, 4.440892098500626e-16),
 (3.6, 1.2, 0.0),
 (3.9, 1.3, 0.0)
]

每组返回三个数字,第三个是偏差的绝对值。其中3.3 / 1.1 有点特殊,偏差并不等于0,这是因为浮点数的精度问题,如下:

>>> 3.3 / 1.1
2.9999999999999996

这个比值并不等于3。所以判断两个浮点数是否相等,不能像整数一样直接比较,而是要把两个浮点作差,如果差值足够小,就判断是相等。上面代码中的变量epsilon 就是这个足够小的差值,1e-9,偏差小于这个值就当0 来看。如果所需的比值为33.55,函数的返回结果是:

[(91.0, 2.7, 0.15370370370370523)]

没有正好匹配的组合,最接近的组合是91 / 2.7。偏差的绝对值是0.1537,误差比例是0.4591%,考虑到实际电阻值本身的误差也有1%,所以这个组合可以接受。再顺便加一个函数,直接把返回结果打印出来,方便使用:

def print_resistor_pair(target_ratio: float):
    resistors = find_e24_resistor_pair(target_ratio)
    if len(resistors) == 1 and resistors[0][2] > 1e-9:
        diff_ratio = resistors[0][2] / (target_ratio) * 100
        print(f"没有两个电阻值的比值等于 {target_ratio:.2f},但是电阻值 {resistors[0][0]:.2f}{resistors[0][1]:.2f} 的比值最接近,误差为 {diff_ratio:.4f}%")
    else:
        print(f"在 E24 数系中,以下电阻值组合的比值等于 {target_ratio:.2f}:")
        for r1, r2, _ in resistors:
            print(f"{r1:.2f}, {r2:.2f}")

如果参数是33.55,调用后会输出:

>>> print_resistor_pair(33.55)
没有两个电阻值的比值等于 33.55,但是电阻值 91.002.70 的比值最接近,误差为 0.4581%

GUI 窗口

再实现一个简单的GUI 吧,方便用:

在这里插入图片描述

完整代码如下,保存为.pyw格式的文件,然后双击运行:

import tkinter as tk
import io
import sys

from typing import List, Tuple


def find_e24_resistor_pair(target_ratio: float) -> List[Tuple[float, float, float]]:
    """
    在 E24 优先数系中找到两个电阻值,使它们的比值最接近给定的比值。
    如果有多个解,返回所有较小值不相等且在 1~10 范围内的解。
    如果没有精确匹配的解,返回偏差最小的一组解。
    每个解都是一个三元组 (r1, r2, diff),其中 r1 和 r2 是电阻值,diff 是偏差。

    :param target_ratio: 目标比值
    :return: 电阻值组合列表
    """
    e24 = [1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7,
            3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8,
            7.5, 8.2, 9.1]
    result = []
    min_diff = float('inf')
    epsilon = 1e-9
    min_exponent = math.floor(math.log10(e24[0] * target_ratio))
    max_exponent = min_exponent + 1
    for r2 in e24:
        for r1_base in e24:
            for i in range(min_exponent, max_exponent + 1):
                r1 = r1_base * (10 ** i)
                ratio = r1 / r2
                diff = abs(ratio - target_ratio)
                if diff < epsilon:
                    result.append((r1,r2,diff))
                elif diff < min_diff:
                    min_diff = diff
                    min_result = (r1,r2,diff)
    if len(result) == 0:
        result.append(min_result)

    return result


def print_resistor_pair(target_ratio: float):
    resistors = find_e24_resistor_pair(target_ratio)
    if len(resistors) == 1 and resistors[0][2] > 1e-9:
        diff_ratio = resistors[0][2] / (target_ratio) * 100
        print(f"没有两个电阻值的比值等于 {target_ratio:.2f},但是电阻值 {resistors[0][0]:.2f}{resistors[0][1]:.2f} 的比值最接近,误差为 {diff_ratio:.4f}%")
    else:
        print(f"在 E24 数系中,以下电阻值组合的比值等于 {target_ratio:.2f}:")
        for r1, r2, _ in resistors:
            print(f"{r1:.2f}, {r2:.2f}")


def on_submit(event=None):
    value_str = entry.get()
    if not value_str:
        return
    text.tag_remove("highlight", "1.0", "end")
    try:
        value = float(value_str)
    except ValueError:
        text.insert(tk.END, "错误:请输入一个有效的浮点数\n")
        text.tag_add("highlight", "end-2l linestart", "end-1l lineend")
        text.yview_moveto(1)
        return
    # 重定向标准输出到字符串缓冲区
    sys.stdout = io.StringIO()
    print_resistor_pair(value)
    # 获取缓冲区中的文本并显示在文本框中
    s = sys.stdout.getvalue()
    text.insert(tk.END, s)
    line_count = s.count('\n')
    text.tag_add("highlight", f"end-{line_count + 1}l linestart", "end-1l lineend")
    text.yview_moveto(1)
    # 恢复标准输出
    sys.stdout = sys.__stdout__

root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
label = tk.Label(frame, text="输入一个参数")
label.pack(side=tk.LEFT)
entry = tk.Entry(frame)
entry.pack(side=tk.LEFT)
entry.bind("<Return>", on_submit)
entry.focus_set()
submit = tk.Button(frame, text="计算", command=on_submit)
submit.pack(side=tk.LEFT)
text = tk.Text(root)
text.pack()
text.tag_config("highlight", background="yellow", foreground="red")
text.tag_config("gray", foreground="gray")
root.mainloop()

总结

性能大概算不上快速,但是能用,而且这种寻找最优组合的问题,基本上也只有暴力搜索这一条路可走吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/452679.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机是怎么跑起来的】基础:计算机三大原则

【计算机是怎么跑起来的】基础&#xff1a;计算机三大原则 计算机的三个根本性基础1.计算机是执行输入&#xff0c;运算&#xff0c;输出的机器输入&#xff0c;运算&#xff0c;输出 2. 软件是指令和数据的集合指令数据 3. 计算机的处理方式有时与人们的思维习惯不同对计算机来…

格式工厂将视频导出Maya需要的图像序列帧

目录 一、格式工厂影片转序列帧 1、格式工厂下载链接 2、打开需要转换的视频 3、输出配置 4、开始导出序列帧 二、Maya中添加影片序列帧和动画播放 1、打开Maya2016版本软件 2、导入图像 3、序列帧设置 4、播放速度设置 5、Maya中播放序列帧动画 一、格式工厂影片转序列帧…

展会邀请 | 虹科诚邀您4月26-28日前来参观成都国际工业博览会

HONGKE NEWS 2023 成都国际工业博览会精准聚焦中国智能制造&#xff0c;将通过展示自动化和工业机器人技术、新一代信息技术、金属加工、节能与工业配套、新材料等全行业最新技术和解决方案&#xff0c;完美呈现智能工业产业链中的创新技术及产品的有效融合。 2023年4月26日-…

无人机3d可视化系统的应用是怎样实现的?

随着科技的发展&#xff0c;以信息化为支撑的系统化操作将成为未来信息对抗的主要形式&#xff0c;通过人工智能技术赋能感知系统&#xff0c;可以抓住机会控制局面&#xff0c;带动后续环节高效运行&#xff0c;缩短循环求解时间&#xff0c;为信息对抗提供机会和关键支撑。无…

为什么医疗保健需要MFT来帮助保护EHR文件传输

毫无疑问&#xff0c;医疗保健行业需要EHR技术来处理患者&#xff0c;设施&#xff0c;提供者等之间的敏感患者信息。但是&#xff0c;如果没有安全的MFT解决方案&#xff0c;您将无法安全地传输患者文件&#xff0c;从而使您的运营面临遭受数据泄露&#xff0c;尴尬&#xff0…

leetcode 周赛 2386. 找出数组的第 K 大和-java实现

题目所属分类 华为校招 原题链接 给你一个整数数组 nums 和一个 正 整数 k 。你可以选择数组的任一 子序列 并且对其全部元素求和。 数组的 第 k 大和 定义为&#xff1a;可以获得的第 k 个 最大 子序列和&#xff08;子序列和允许出现重复&#xff09; 返回数组的 第 k 大…

【新时代圈友app】为什么要使用MongoDB数据库?— 查询缘分值最高的最佳好友并返回相关信息

目录 一、为什么要使用MongoDB数据库&#xff1f; 二、缘分值最佳好友 思路 一、为什么要使用MongoDB数据库&#xff1f; 本项目涉及到的圈子(动态)功能&#xff0c;用户会对朋友圈进行点赞、评论&#xff1b;那么随着用户的不断增多&#xff0c;评论点赞收藏等信息也会不断…

JS之Map的基本使用

一、Map的基本API 创建&#xff1a; const map new Map()插入&#xff1a;map.set("name", "郑建")读取&#xff1a;map.get("name")判断&#xff1a;map.has("name")删除&#xff1a;map.delete大小&#xff1a;map.size遍历&#…

webhub123 设计师好用的笔刷纹理网站收录​

整理了一些可以免费下载的好用的笔刷和纹理资源网站&#xff0c;收录到 webhub123 设计师好用的笔刷纹理网站收录​http://www.webhub123.com/#/home/detail?projectHashid31645930&ownerUserid21336964 收录效果如下&#xff0c;每个网站显示为一张图片&#xff0c;点击…

【Python基础入门学习】Python基础语法学习

基础认识 1. 注释2. 变量2.1 变量命名规则2.2 变量的类型2.3 不同类型之间的运算规则2.4 变量的输入和输出2.4.1 print 函数使用2.4.2 input 函数使用 2.5 变量的类型转换 3. 分支语句3.1 判断的定义3.2 if 判断语句基本语法3.3 else 处理条件不满足的情况3.4 逻辑运算3.5 if 的…

小红书数据分析:这个夏天,“围炉冰茶”继续刷屏

导语 去年秋冬开始爆火的“围炉煮茶”&#xff0c;果集千瓜数据显示&#xff1a;近90天来&#xff0c;笔记预估阅读总数达1,038.83万&#xff0c;同比下降80.67%&#xff0c;笔记互动总量61.78万&#xff0c;下降高达76.85%。 图 | 果集千瓜数据 受到时令的影响&#xff0c;围…

算法 - 随机 Coding 刷算法合集 [1]

目录 一.数组中重复的数字 [集合] 1.题目要求 2.题目思路 3.题目实现 二.二维数组中的查找 [数组] 1.题目要求 2.题目思路 3.题目实现 三.替换空格 [字符串] 1.题目要求 2.题目思路 3.题目实现 四.从尾到头打印链表 [链表] 1.题目要求 2.题目思路 3.题目实现 …

电脑技巧:分享浏览器5个小技巧,太实用了

大家在日常办公当中&#xff0c;浏览器可以说占用非常大的比重&#xff0c;比如搜个素材、图片、文档等等&#xff0c;今天就来给大家分享5个浏览器使用的小技巧&#xff0c;希望对大家能有所帮助&#xff01; 1、浏览器常用快捷键梳理 其实Web浏览器快捷键很多&#xff0c;但…

MySQL_第14章_视图

第14章_视图 1. 常见的数据库对象 对象描述表(TABLE) 表是存储数据的逻辑单元&#xff0c;以行和列的形式存在&#xff0c;列就是字段&#xff0c;行就是记录 数据字典 就是系统表&#xff0c;存放数据库相关信息的表。系统表的数据通常由数据库系统维护&#xff0c; 程序…

Java多线程基础-6:线程安全问题及解决措施,synchronized关键字与volatile关键字

线程安全问题是多线程编程中最典型的一类问题之一。如果多线程环境下代码运行的结果是符合我们预期的&#xff0c;即该结果正是在单线程环境中应该出现的结果&#xff0c;则说这个程序是线程安全的。 通俗来说&#xff0c;线程不安全指的就是某一代码在多线程环境下执行会出现b…

【边缘计算】登临(Goldwasser-UL64)BW-BR2边缘设备配置指南

目录 开箱配置激活SDK环境测试cuda兼容性 开箱配置 更改盒子root用户密码&#xff1a; sudo passwd root(密码同为root) 切换到root用户身份&#xff1a; su root查看ssh的状态&#xff0c;没有返回说明没有启动 sudo ps -e|grep ssh此时说明ssh服务已启动。 更改ssh配置文…

Android MediaCodec dump MP4实践小结

1.应用背景 在一些集成了算法SDK的Android APP中&#xff0c;这些APP是取出摄像头实时帧&#xff0c;然后调用视觉算法SDK并产生检测结果。而当测试人员发现某一场景下算法效果欠佳时&#xff0c;需要从摄像头实时原始数据帧dump一段视频&#xff08;mp4格式&#xff09;&#…

【TB作品】MSP430单片机 Proteus仿真 DS18B20温度 LCD1602显示器 温度读取与显示

效果图如下&#xff1a; 首先,让我们先来说说DS18B20集成电路。 • DS18B20是一款采用OneWire通讯协议的集成电路,因此只需要一条线就可以与微控制器通讯。它不需要额外的电源,但是也有外部电源输入端口。 • OneWire设备具有64位的ROM代码。如我们之前所说,这64位的前8位是家…

HDCTF

Welcome To HDCTF 2023 看源码找到game.js 找到这一串 放到控制台运行即可 SearchMaster 题目让post提交一个data 随便传一个在页面执行了 当传入{时他会报错&#xff0c;看报错信息发现 Smarty&#xff0c;猜测Smarty的ssti&#xff0c;数据发送到前端 用{if}标签即可 {…

CHAPTER 5: 《DESIGN CONSISTENT HASHING》 第5章 《设计一致的哈希》

CHAPTER 5: DESIGN CONSISTENT HASHING 为了实现水平扩展&#xff0c;有效且均匀地分发请求/数据是很重要的在服务器上。一致散列是实现这一目标的常用技术。但首先&#xff0c;让我们深入了解一下这个问题。 重组问题 如果您有n个缓存服务器&#xff0c;那么平衡负载的常用…