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


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

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

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

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

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

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

<?php
$amount = 3000;
$sizes = array(1300, 1200, 1100, 1000, 950, 900, 800, 700); // 假设已按降序排列

$result = array();
$currentAmount = $amount; // 使用一个临时变量来保存当前待分解的金额

foreach ($sizes as $size) {
    $times = floor($currentAmount / $size);
    if ($times > 0) {
        $result[$size] = $times;
        $currentAmount -= $times * $size;
    }
}

echo '<pre class="brush:php;toolbar:false;">'; print_r($result); echo '
'; ?>

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

Array
(
    [1300] => 2
)

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

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

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

AiTxt 文案助手 AiTxt 文案助手

AiTxt 利用 Ai 帮助你生成您想要的一切文案,提升你的工作效率。

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

实现步骤

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

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

$evaluations = []; // 用于存储所有构成元素的评估结果

foreach ($sizes as $size) {
  $times = (int)floor($amount / $size); // 计算该元素能使用的次数
  $remainder = $amount - $times * $size; // 计算剩余金额

  $evaluations[] = [
      'size' => $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 '<pre class="brush:php;toolbar:false;">'; 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。这正是我们希望通过优化算法找到的结果。

注意事项与扩展

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

总结

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

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


# ai  # 深圳地产网站优化怎么做  # 湖北网络营销推广培训  # 汉中茶产业推广营销  # 能多  # 怎么看  # 评估结果  # 数为  # 排在  # 数据结构  # 遍历  # 最优  # 升序  # 自定义  # 排列  # 软件开发  # php  # 南平律师网站推广公司  # 襄阳网站推广哪家公司好  # seo搜索获客成本  # 推广和营销文案范文  # 温州seo网络推广推荐  # 淘宝单品推广营销技巧  # 竞品流量关键词优化排名 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: Golang如何使用crypto/md5生成哈希_Golang MD5哈希生成方法  餐馆菜篮选购指南  Win10如何关闭操作中心通知 Win10免打扰设置全攻略【清爽】  解决PHP MySQL数据库更新无响应:SQL查询语法错误解析  德邦物流在线查询系统 德邦快递货物运输追踪  Go App Engine 项目结构与包管理深度指南  Python定时发送QQ消息  繁花漫画使用教程  《kimi智能助手》制作ppt教程  在J*a里什么是行为抽象_抽象行为对代码复用的提升作用  掌握产品代码正则表达式:避免常见陷阱与精确匹配  感染了幽门螺杆菌一定会导致胃癌吗?蚂蚁庄园今日答案最新11.30  在Django单元测试中优雅处理信号:基于环境的条件执行策略  路由器DNS怎么设置最快 优化DNS提升上网速度教程  Symfony路由参数转换器:实体存在性验证与错误处理策略  第五人格PC版怎么避免被封号_第五人格PC版防封号注意事项  使用 J*aScript 随机化 CSS Grid 布局中的元素顺序  视频号视频怎么免费保存到相册?保存到相册需要注意什么?  铁路12306怎么申请退票_铁路12306退票申请操作流程  AI图层蒙版怎么用_AI图层蒙版应用技巧与设计实例  Lar*el 中高效执行多列更新:单次查询实现  《大周列国志》皇帝律令功能介绍  Sublime怎么配置YAML文件格式化_Sublime YAML Formatter插件教程  视频号视频怎么提取文案?提取的文案如何优化与使用?  CSS绝对定位与溢出控制:实现背景元素局部显示不触发滚动条  曝《丝之歌》DLC有望开发!开发商还有神秘新企划  漫蛙manwa官网浏览入口_漫蛙漫画网页版访问链接  汽水音乐网页端访问 汽水音乐官方网页直达  C++ priority_queue怎么用_C++优先队列底层实现与自定义比较器  使用VS Code调试Python代码:从入门到精通  抖音怎么解除第三方绑定_抖音解除第三方平台绑定方法介绍  基于键值条件高效映射 Pandas DataFrame 多列数据  如何用mysql开发用户注册登录功能_mysql用户注册登录数据库设计  包子漫画在线观看入口 包子漫画网正版全集链接  如何在CSS中实现盒模型多列间距_grid-gap与padding结合  j*a中ArrayBlockingQueue的使用  抖音猜你想搜能说明对方搜过吗  哈尔滨城市通昵称修改方法  123平台官方登录入口 123邮箱网页端在线沟通工具  《U校园》学生登录入口2025  J*aScript与CSS动画:实现平滑顺序淡入淡出效果并解决显示冲突  sublime怎么在文件中显示代码结构大纲_sublime符号列表功能  我居然低估了 DeepSeek,这次更新它做到了这些!  Excel如何快速合并单元格内容_Excel文本合并与函数操作技巧  Composer如何使用composer-plugin-api开发自定义插件  可米酷漫画在线阅读入口_ 可米酷漫画官网直达链接  使用TinyButStrong生成HTML并结合Dompdf创建PDF教程  斯宾塞称XGP云游戏“蒸蒸日上”:正在构建一个游戏从未如此唾手可得的未来  《杖剑传说》食谱大全  英雄联盟争者留名活动介绍 

 2025-10-30

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.