优化PHP数值构成:最小化余数的元素匹配算法

优化PHP数值构成:最小化余数的元素匹配算法

本文探讨了如何在给定一组预设数值中,为目标数字寻找最佳的单一组成元素及其倍数,以实现最小化余数。通过分析初始贪婪算法的局限性,我们提出并实现了一种基于遍历、计算与自定义排序的优化策略,确保优先匹配无余数或最小余数的组合,从而高效地找到最接近目标值的构成方案。

软件开发中,经常会遇到需要将一个目标数值分解为一系列预设构成元素的问题。例如,计算特定金额可以由哪些面额的钞票组成,或者一个总容量可以由哪些规格的容器填充。一个常见的挑战是,当目标数值不能被某个单一构成元素完美整除时,如何找到最接近的构成方案,即产生最小余数的方案。

问题描述与初始尝试的局限性

假设我们有一个目标金额 $amount (例如 3000),以及一组允许的构成元素 $sizes (例如 [1300, 1200, 1100, 1000, 950, 900, 800, 700])。我们的目标是找出 $sizes 中哪个元素,通过乘以某个整数倍数,能够最接近 $amount,同时使余数最小。

一个直观但存在缺陷的初始方法是采用“贪婪算法”:从最大的构成元素开始,尽可能多地减去它,然后对剩余的金额重复此过程。

 0) {        $result[$size] = $times;        $currentAmount -= $times * $size;    }}echo '
'; print_r($result); echo '

';?>

对于 $amount = 3000,上述代码的输出将是:

立即学习“PHP免费学习笔记(深入)”;

Array(    [1300] => 2)

这个结果表明使用了两个 1300,总计 2600,剩余 400。然而,我们可能期望得到的是使用三个 1000,总计 3000,余数为 0 的方案。这揭示了贪婪算法的局限性:它只关注当前步骤的最优选择,而可能错过全局最优解。在这种情况下,因为它优先使用了最大的 1300,导致无法发现 1000 * 3 这种更优的组合。

优化策略:全面评估与自定义排序

为了克服贪婪算法的局限性,我们需要一种方法来全面评估 $sizes 数组中的每一个构成元素,并根据其产生的余数和使用次数进行排序。核心思路是:

独立评估: 对 $sizes 数组中的每一个构成元素,独立计算它能被目标金额整除的次数,以及由此产生的余数。结果收集: 将每个构成元素的评估结果(包括元素值、使用次数和余数)存储起来。自定义排序: 对收集到的结果进行排序,优先选择余数最小的方案;如果余数相同,则进一步考虑使用次数等其他因素。

实现步骤

我们将使用 PHP 来实现这一优化策略:

定义目标金额和构成元素数组。遍历构成元素数组: 对于每个元素,计算其能“构成”目标金额的次数 (times) 和剩余的金额 (remainder)。存储评估结果: 将每个构成元素的值、计算出的次数和余数作为一个结构化数据(例如关联数组)存储到一个新的结果集中。使用 usort 进行自定义排序:主要排序依据: remainder (升序),即余数越小越优先。次要排序依据: 如果 remainder 相同,则根据 times (升序),即使用次数越少越优先。这个次要排序规则可以根据具体业务需求调整,例如,如果希望在余数相同的情况下尽可能多地使用构成元素,则可以设置为降序。在我们的例子中,选择升序意味着在余数相同时,我们倾向于使用更少的构成元素。

 $size,        // 构成元素的值      'times' => $times,      // 使用次数      'remainder' => $remainder // 剩余金额  ];}// 使用 usort 进行自定义排序usort($evaluations, static function ($item1, $item2): int {  // 首先比较余数:余数小的排在前面  $comparison = $item1['remainder']  $item2['remainder'];  // 如果余数相同,则比较使用次数:次数少的排在前面  return $comparison === 0 ? $item1['times']  $item2['times'] : $comparison;});echo '
'; print_r($evaluations); echo '

';?>

输出分析

运行上述代码,我们将得到一个按优化规则排序的结果数组:

Array(    [0] => Array        (            [size] => 1000            [times] => 3            [remainder] => 0   // 最优结果:余数为0        )    [1] => Array        (            [size] => 950            [times] => 3            [remainder] => 150   // 次优结果        )    [2] => Array        (            [size] => 700            [times] => 4            [remainder] => 200        )    [3] => Array        (            [size] => 900            [times] => 3            [remainder] => 300        )    [4] => Array        (            [size] => 1300            [times] => 2            [remainder] => 400        )    [5] => Array        (            [size] => 1200            [times] => 2         // 与下一个元素的余数相同            [remainder] => 600        )    [6] => Array        (            [size] => 800            [times] => 3         // 余数相同,但使用次数更多,因此排在后面            [remainder] => 600        )    [7] => Array        (            [size] => 1100            [times] => 2            [remainder] => 800        ))

从输出中可以看到,第一个元素 [0] 即为我们寻找的最佳构成方案:使用 1000 这个构成元素 3 次,恰好等于目标金额 3000,余数为 0。这正是我们希望通过优化算法找到的结果。

注意事项与扩展

单类型构成元素: 本文提供的解决方案着重于寻找“单一类型”的最佳构成元素。例如,对于 3000,它会找到 3 个 1000。如果问题要求寻找“多种类型”构成元素的组合(例如,3500 可以由 1200, 1200, 1100 组成),则需要采用更复杂的算法,如动态规划(背包问题或找零问题变种),这超出了本文的范畴。性能考量: 对于较小的 $sizes 数组和 $amount,上述遍历和排序方法效率很高。如果 $sizes 数组非常庞大,或者 $amount 极大导致 $times 很大,可能需要考虑更优的数据结构或算法。排序规则的灵活性: usort 中的比较函数是高度可定制的。您可以根据实际业务需求调整排序逻辑,例如,在余数相同的情况下,是优先选择使用次数多的构成元素,还是使用次数少的构成元素。边界条件处理: 在实际应用中,需要考虑 $sizes 数组为空、$amount 为负数或小于所有 $size 的情况,并添加相应的错误处理或默认逻辑。

总结

通过对目标金额和所有可能构成元素进行全面评估,并结合自定义排序逻辑,我们能够有效地找到在给定构成元素集合中,能以最小余数(或无余数)最接近目标金额的单一构成方案。这种方法避免了贪婪算法可能导致的局部最优解问题,提供了一个更健壮和灵活的数值构成匹配策略。

以上就是优化PHP数值构成:最小化余数的元素匹配算法的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1328791.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月12日 15:03:44
下一篇 2025年12月12日 15:03:55

相关推荐

  • 如何将 API JSON 响应存储到 MySQL 数据库并重新获取

    本文介绍了如何将 API 返回的 JSON 数据存储到 MySQL 数据库中,并从数据库中检索 JSON 数据。通过将 JSON 数据存储在数据库中,可以减少对 API 的重复调用,从而节省 API 调用次数,特别适用于付费 API 或有调用次数限制的 API。文章提供了详细的代码示例,展示了如何使…

    好文分享 2025年12月12日
    000
  • PHP cURL句柄复用与选项重置:深入理解curl_reset()的应用

    当在php中复用curl句柄执行多次请求时,如何有效管理和重置其配置选项,特别是回调函数(如`curlopt_headerfunction`),是一个常见挑战。本文将详细介绍`curl_reset()`函数,阐述其工作原理,并提供最佳实践,确保每次请求都能以预期的配置执行。 cURL句柄复用的优势与…

    2025年12月12日
    000
  • Yii2 REST API 中对关联数据进行升序排序

    本文介绍了如何在 Yii2 REST API 中对通过 `expand` 关联获取的数据进行升序排序。通过在关联模型的 `get` 方法中使用 `orderBy` 子句,可以轻松实现对关联数据的排序,从而满足 API 返回数据的特定排序需求。 在 Yii2 框架中,通过 REST API 获取数据时…

    2025年12月12日
    000
  • Apache Virtual Host 多版本 PHP 配置实践

    本文旨在提供apache virtual host配置多版本php的实用指南,解决本地开发环境中不同项目php版本需求冲突的问题。我们将详细介绍如何利用php-fpm和apache的`mod_proxy_fcgi`或`mod_fastcgi`模块,为每个虚拟主机指定独立的php版本,从而优化开发流程…

    2025年12月12日
    000
  • Laravel 8 中按组ID筛选周报并实现关联创建教程

    本教程详细讲解如何在 laravel 8 应用中实现按特定组id筛选周报的功能,并确保新创建的周报能正确关联到相应的组。通过修改路由定义、blade 模板中的链接生成以及控制器中的数据过滤逻辑,我们将实现用户点击特定组的报告按钮后,仅显示该组的周报,并允许在该上下文下创建新的组内报告。 在 Lara…

    2025年12月12日
    000
  • PHP:高效重塑数组结构——从关联到转置列表

    本文详细介绍了如何在php中将一个嵌套的关联数组转换为转置后的列表数组。通过巧妙结合`array_map()`、`array_filter()`和php 7.4+的展开运算符(spread operator),我们能够高效地实现数组结构的重塑,即使面对子数组长度不一致的情况也能生成整洁、符合目标格式…

    2025年12月12日
    000
  • 深入理解 PHP 类型协变与逆变:解决 PhpStorm 返回值类型不兼容警告

    本文旨在解决 phpstorm 中常见的 ‘return value is expected to be…’ 警告,该警告通常源于 php 面向对象编程中类型协变与逆变规则的违反。我们将深入探讨 php 类型系统在继承中的行为,解释为何会出现此类警告,并提供两种解…

    2025年12月12日
    000
  • php数据库地理查询处理_php数据库空间数据操作方法

    使用MySQL空间函数或Haversine公式可在PHP中实现地理查询,如查找附近地点;通过PostGIS扩展可进行更复杂的地理分析。 如果您需要在PHP中执行地理查询以处理地理位置相关的数据,例如查找附近地点或计算两点间距离,可以通过数据库的空间函数结合PHP代码实现。这类操作通常涉及经纬度字段的…

    2025年12月12日
    000
  • Laravel文件上传:解决数据库存储临时路径而非文件URL的问题

    本文旨在解决laravel文件上传后,数据库中错误存储php临时文件路径而非实际文件url或相对路径的常见问题。通过分析move()方法的返回值,本文将提供一个清晰的解决方案,演示如何正确地将上传文件的公共访问路径存储到数据库,并分享相关的最佳实践,确保文件上传功能稳定可靠。 在Laravel应用中…

    2025年12月12日
    000
  • PHP/Laravel中累加时间字符串(H:i:s)并格式化输出的教程

    本教程详细介绍了如何在php/laravel应用中,将以`h:i:s`格式存储的多个时间字符串(如歌曲时长)进行累加,并最终将总时长转换为易读的`i:s`或`h:i:s`格式输出。通过将时间统一转换为秒进行计算,再反向格式化,实现精确的时间累加与展示。 在开发Web应用时,我们经常会遇到需要处理时间…

    2025年12月12日
    000
  • WooCommerce订单客户备注的高级获取与集成指南

    本教程详细阐述了如何在woocommerce中准确获取订单的客户备注。针对`wc_order::get_customer_note()`可能无法获取到客户作为评论提交的备注的问题,我们提供了一个定制化的数据库查询方案。通过直接查询`wp_comments`和`wp_commentmeta`表,您可以…

    2025年12月12日
    000
  • 优化WooCommerce产品导入:高效管理缺货商品以节省服务器资源

    本教程旨在解决woocommerce每日大量导入产品时,缺货商品占用服务器空间的问题。核心策略是源头管理,通过在导入前筛选csv文件,剔除所有缺货商品,从而避免不必要的图片和数据上传,有效节省存储空间并简化日常维护。 WooCommerce缺货商品管理:从源头优化导入流程 在日常的电子商务运营中,尤…

    2025年12月12日
    000
  • php调用数据库连接池_php调用持久化连接的优化方案

    PHP原生不支持数据库连接池,但可通过持久化连接和外部中间件模拟。在FPM环境下,使用PDO持久连接可复用同一进程内的数据库连接,减少握手开销,需合理配置子进程数、超时时间,并验证连接有效性,避免连接泄漏。更优方案是引入ProxySQL等代理中间件,集中管理连接池,提升性能与稳定性。在Swoole等…

    2025年12月12日
    000
  • PHP中处理嵌套数组与构建SQL IN 子句的实用指南

    本文旨在指导读者如何高效地遍历和处理php中的嵌套数组,特别是当需要从复杂结构中提取特定数值以构建sql查询的`in`子句时。我们将详细解释常见的“array to string conversion”错误,并提供正确的迭代方法和使用`implode`函数生成安全sql过滤条件的完整示例,同时强调s…

    2025年12月12日
    000
  • Laravel中识别与处理同一表单内多个提交按钮的技巧

    本文详细介绍了在laravel应用中,如何有效区分并处理同一html表单内由不同提交按钮触发的多种操作。核心策略是在提交按钮上设置唯一的name和value属性,然后在laravel控制器中通过$request->input()方法获取这些值,从而根据用户点击的按钮执行相应的后端逻辑,实现灵活…

    2025年12月12日
    000
  • PHP cURL句柄复用与选项重置:高效管理回调函数及其他配置

    在php curl中,为了提升性能和复用底层连接,我们经常会重用curl句柄。然而,当特定请求需要设置如`curlopt_headerfunction`等回调函数或一次性选项时,后续请求可能不再需要这些配置。本教程将详细介绍如何利用`curl_reset()`函数彻底清除句柄上的所有旧选项,并结合通…

    2025年12月12日
    000
  • 为什么选择PHP框架开发网站_PHP框架对比原生开发的核心优势

    使用PHP框架提升开发效率、代码质量与可维护性,相比原生PHP更具优势。 选择PHP框架开发网站,核心在于提升开发效率、保障代码质量以及增强项目可维护性。相比原生PHP开发,现代PHP框架如Laravel、Symfony、CodeIgniter等提供了系统化的工具和规范,让开发者能更专注于业务逻辑而…

    2025年12月12日
    000
  • PHP循环中构建字符串的正确姿势:避免变量覆盖与优化函数设计

    本文深入探讨了php循环中如何高效且正确地积累字符串输出,避免因变量重复赋值而导致数据丢失的问题。通过详细介绍字符串连接操作符(`.=`)的用法,并强调在函数设计中应避免使用全局变量,转而采用返回值的方式,旨在指导开发者编写出更健壮、可维护且符合最佳实践的php代码。 在PHP开发中,我们经常需要在…

    2025年12月12日
    000
  • PHP/Laravel中累加时间段并格式化总时长

    本文详细介绍了在php和laravel项目中如何累加以h:i:s格式存储的时间段(如歌曲时长),并将其总和转换为可读的i:s或h:i:s格式。核心方法是将所有时间段转换为秒,累加这些秒数,然后将总秒数格式化为目标时间字符串,提供了具体的php函数和laravel应用示例。 在许多Web应用中,我们经…

    2025年12月12日
    000
  • 将IMAP邮件导入WordPress自定义文章类型教程

    本教程详细指导如何通过php imap功能从邮件服务器提取电子邮件,并将其动态导入至wordpress的自定义文章类型(cpt)中。文章涵盖了imap连接、邮件内容获取以及利用wordpress的`wp_insert_post`函数创建cpt条目的完整流程,旨在帮助开发者构建邮件处理、工单系统或邮件…

    2025年12月12日
    000

发表回复

登录后才能评论
关注微信