由于零而始终将滑块求和到 100% 失败的算法

2024-02-26

这是(应该是)一个函数,它确保多个滑块值的总和always总计为globalTotal.

用户可以手动更改滑块值changer.value然后当将此函数应用于other滑块,它可以确定它们的新或endVal.

它需要startVal需要更改的滑块的值以及更改后的滑块的原始值changerStartVal并可以通过加权确定其他人的新值。

问题和我的问题是。有时remainingStartVals can be zero(当滑块变化一直移动到最大时)或startVal can be zero(当滑块变化移动到零,然后移动另一个滑块时)。当这种情况发生时,我分别得到一个被零除或乘以零的结果。两者都是不好的并且会导致不正确的结果。有一个简单的方法可以解决这个问题吗?

func calcNewVal(startVal: Float, changerStartVal: Float) -> Float {

    let remainingStartVals = globalTotal - changerStartVal

    let remainingNewVals = globalTotal - changer.value

    let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals

    return endVal

}

这是一个数学问题,而不是与 Swift 或任何特定编程语言相关的问题,因此我将用数学公式和解释而不是代码片段来回答。

我也不太明白你的算法。例如在这一行中:

let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals

您首先乘以 100,然后除以 100,因此您可以首先将所有这 100 个因数排除在外!


但是,我想我理解你想要实现的目标,问题是is没有通用的解决方案。在编写算法之前,您必须定义exactly你希望它如何表现,包括所有边缘情况.

让我们定义一下:

  • vi as the value of the i-th slider and
  • Δi as the change of the i-th slider's value

那么你必须考虑以下情况:


Case 1:

0 < vi ≤ 1 for all sliders (other than the one you changed)

This is probably the common case you were thinking about. In this case you want to adjust the values of your unchanged sliders so that their total change is equal to the change Δchanged of the slider you changed. In other words:

i Δi = 0

如果您有 3 个滑块,则这会减少为:

  • Δ1 + Δ2 + Δ3 = 0

如果更改的滑块是带有i = 1那么这个要求将是:

  • Δ1 = – (Δ2 + Δ3)

You want the sliders to adjust proportionally which means that this change Δ1 should not be distributed equally on the other sliders but depending on their current value:

  • Δ2 = – w2 * Δ1
  • Δ3 = – w3 * Δ1

标准化权重因子为

  • w2 = v2 / (v2 + v3)
  • w3 = v3 / (v2 + v3)

由此我们得到:

  • Δ2 = – v2 / (v2 + v3) * Δ1
  • Δ3 = – v3 / (v2 + v3) * Δ1

这些是适用于这种特殊情况的公式。

但是,还有很多其他情况不适用于此方法:


Case 2:

vi = 0 for at least one, but not all of the sliders (other than the one you changed)

在这种情况下,方法来自case 1仍然有效(而且这是合乎逻辑的事情)。但是,如果滑块的值为零,则它的值永远不会改变。所有更改都将分布在值 > 0 的滑块上。


Case 3:

vi = 0 for all sliders (other than the one you changed)

在这种情况下,比例更改不起作用,因为根本没有信息如何在滑块上分配更改。他们都是零!这实际上是你的零除问题:如果我们有 3 个滑块并且滑块 1 发生变化,我们会得到

v2 + v3 = 0

This is only another manifestation of the fact that the weight factors wi are simply undefined. Thus, you'll have to manually define what will happen in this case.

在这种情况下,最合理的做法是分发更改evenly在所有滑块上:

Δi = – (1 / n) * Δ1

where n is the 滑块数量(不包括已更改的!)。按照这种逻辑,每个滑块都会获得“相同份额”的变化。


现在我们已经清楚了我们的算法,您可以在代码中实现这些情况。这里以一些伪代码为例:

if sum(valuesOfAllSlidersOtherThanTheSliderThatChanged) == 0 {
    for allUnchangedSliders {
        // distribute change evenly over the sliders
        Δi = – (1 / n) * Δ_changedSlider
    }
}
else {
    for allUnchangedSliders {
        // use weight factor to change proportionally
        Δi = – v_i / ∑(v_i) * Δ_changedSlider
    }
}

Please be aware that you must cache the values of the current state of your sliders at the beginning or (even better) first compute all the changes and then apply all the changes in a batch. Otherwise you will use a value v2' that you just computed for determining the value v3' which will obviously result in incorrect values.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

由于零而始终将滑块求和到 100% 失败的算法 的相关文章

随机推荐

  • 在 Windows 上将 PPT 转换为 JPG/PNG

    我想在 Windows 环境中以编程方式转换一组图像中的 ppt 演示文稿 每张幻灯片一个 我尝试修改以下将 ppt 转换为 pdf 的代码 完美工作 但没有成功 谁能帮我 多谢 Option Explicit Sub WriteLine
  • Pandas 显示 Excel 文件的额外未命名列

    我正在开发一个使用 pandas 库的项目 其中我需要读取一个包含以下列的 Excel 文件 invoiceid locationid timestamp customerid discount tax total subtotal pro
  • 桌面应用程序.net中的视频通话

    我正在开发一个 wpf 应用程序 该应用程序应该具有视频通话功能 所以我寻求 Skype 为我提供解决方案 我正在使用 Skype4COM 库来做到这一点 我的应用程序中包含了 Skype 的所有朋友 我可以给朋友打电话 甚至可以进行视频通
  • 判断文件中是否存在字符串

    我有一个字符串列表 例如 John John Doe 彼得潘 在 txt 文件中 我想创建一个循环来检查某个名称是否存在 但是 如果我搜索 Peter 并且只存在 Peter Pan 我不希望这是真的 每行都必须完全匹配 哈哈 ep0的回答
  • 警告 C4267“参数”:从“size_t”转换为“DWORD”,可能会丢失数据

    我正在将代码从 32 位 vs2012 迁移到 64 位 vs2015 我在程序中遇到了以下函数调用 CryptHashData hHash BYTE AUTH ENCRYPTION KEY wcslen AUTH ENCRYPTION K
  • 删除 Meshlab 或 vcglib 中的自相交

    如何使用 Meshlab 应用程序或 vcglib 消除网格的自相交 这超出了范围 但 CGAL 中有一些函数 这仍然是实验性的 没有记录 但您可以使用该功能remove self intersections https github co
  • 不包含适合入口点的静态“main”方法

    我今天开始将代码组织到单独的 cs 文件中 为了允许与 UI 一起使用的方法继续这样做 我将在相同的命名空间和公共部分类名下创建 cs 代码 以便这些方法可以可互操作 我的标头在四个文件中看起来像这样 包括调用的主核心文件 public s
  • 内存警告但活动字节较小

    在我的应用程序中 在重复某些操作 选择图片 处理 多次后 我收到级别 1 的内存警告 然后收到级别 2 的内存警告 然后崩溃 泄漏工具没有显示任何泄漏 我还关注 Instruments 中的分配工具 我的实时字节大约为 4 MB 总共分配了
  • sqldf:从数据帧创建表错误:“没有这样的表”。并创建了两张表而不是一张

    我最近升级了 R RSQLite 和 sqldf 以下版本 通常情况下 sqldf create table foo as select from bar db test db 应该在附加的 sqlite 数据库中创建一个名为 foo 的表
  • 在 Reactjs 中迭代数组

    const cal days Sun Mon Tue Wed Thu Fri Sat const cal months Jan Feb March April May June July August Sept Oct Nov Dec co
  • 组合 Group-Object 和 ForEach-Object?

    我正在开发一个名为Merge Xsd可以合并相似的 XML 模式 它需要一个路径列表 加载模式 合并它们 并生成一个XMLDocument作为输出 特定文件名的所有模式都被认为是 相似的 所以我正在做的就是获取特定目录结构中的所有子项 根据
  • 使用useEffect获取数据时避免使用旧数据

    我的问题是 当自定义挂钩使用useEffect with useState 例如 为了获取数据 在依赖项更改之后但在 useEffect 被触发之前 自定义挂钩会返回过时的数据 来自状态 您能建议一种正确 惯用的方法来解决这个问题吗 我正在
  • 针对具有大量聚合的大型集群的 ElasticSearch 设置

    背景和当前状态 我们正在将集群从 Cassandra 迁移到完整的 ElasticSearch 集群 我们平均索引文档为每秒约 250 300 个文档 在 ElasticSearch 1 2 0 中 它代表每天约 8Go generic i
  • Android 如何避免内存不足错误

    我有很多图像 大约有 500 张分布在 20 个左右的片段中 这些图像都非常小 并且加载得很好 但是我给用户提供了 3 种不同类型的图像的选择 现在如果用户更改图像我收到 OOM 错误 所以我认为这是我处理图像的方式 我认为我需要先回收旧图
  • 基于另一个字段更改 SSRS 中值字符串中特定值文本颜色的表达式

    我的 SSRS 报告中有一个字段 其中包含一串用逗号分隔的数字 来自 SQL 中的合并选择 它看起来像 12 91 160 171 223 如果该值也在报告的另一个字段中 我只想更改该字段中一个特定值 例如 160 的文本颜色 我已经有了这
  • 使用 BigDecimal 计算小数点后的最大位数

    小数点后最多可以有多少位BigDecimalJava 中的值 它 几乎 是无限的 如果将比例设置为整数的最大值 则可以存储大约 20 亿位小数点后的数字 但如果尝试这样做 可能会耗尽内存 如果您需要存储如此多的数字以至于限制成为问题 那么您
  • 如何将UIImage插入到UITextView中

    我正在开发一个可编辑的笔记本类型项目 它随时由一些文本和图像组成 在UITextView如果我们将图像添加为子视图 则帧是固定的 但我有editable选项 所以我必须将图像另存为NSString格式为UITextView 但它应该在 ui
  • AutoMapper 4.2 和 Ninject 3.2

    我正在更新我的一个项目以使用 AutoMapper 4 2 并且遇到了重大更改 当我seem为了解决上述更改 我并不完全相信我已经以最合适的方式做到了这一点 在旧代码中 我有一个NinjectConfiguration 和AutoMappe
  • Android 2.1 WebView 中的 SIGSEGV

    在 Android 2 1 中使用 WebView 时 我间歇性地收到 SIGSEGV SIGSEGV 位于 system lib libwebcore so 内 此 WebView 实现是否存在已知问题 我可以解决该问题以避免 SEGV
  • 由于零而始终将滑块求和到 100% 失败的算法

    这是 应该是 一个函数 它确保多个滑块值的总和always总计为globalTotal 用户可以手动更改滑块值changer value然后当将此函数应用于other滑块 它可以确定它们的新或endVal 它需要startVal需要更改的滑