You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

屋顶计算场景下Symfony ExpressionLanguage依赖变量公式求解算法咨询

屋顶计算应用公式求解算法实现

核心思路

将每个公式抽象为目标变量-依赖变量-计算表达式的结构化数据,通过迭代方式逐步用已知变量求解可计算的目标变量,直到所有变量都被求解,或判定无法完成求解时抛出异常。

算法步骤

  • 定义公式元数据:为每个公式记录目标变量、依赖变量列表、Symfony ExpressionLanguage兼容的表达式字符串。
  • 初始化已知变量集合:包含用户输入的初始值(如a或Hr,以及A、B等固定参数)。
  • 区分已求解/未求解变量集合:初始时已求解集合等于已知变量,未求解集合为所有公式目标变量减去已知变量。
  • 循环迭代求解:
    • 遍历所有未求解变量,检查当前已求解变量是否覆盖该变量的所有依赖项。
    • 对满足条件的变量,用ExpressionLanguage计算其值,加入已求解集合并从未求解集合移除。
    • 若一轮迭代中无新变量被求解,说明无法继续,抛出异常。
  • 当未求解集合为空时,返回所有已求解变量。

PHP代码实现示例

首先安装Symfony ExpressionLanguage组件:

composer require symfony/expression-language

实现代码:

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

class RoofCalculator
{
    private $expressionLanguage;
    // 公式元数据:键为目标变量,值包含依赖列表和计算表达式
    private $formulas = [
        'a' => [
            'deps' => ['Hr', 'B'],
            'expr' => 'atan(Hr / B)'
        ],
        'Hr' => [
            'deps' => ['B', 'a'],
            'expr' => 'B * tan(a) / 2'
        ],
        'R' => [
            'deps' => ['A', 'Hr'],
            'expr' => '(A - (Hr / tan(90)))'
        ],
        'X' => [
            'deps' => ['Hr', 'R', 'a'],
            'expr' => 'Hr * R + cos(a)'
        ]
    ];

    public function __construct()
    {
        $this->expressionLanguage = new ExpressionLanguage();
    }

    public function calculate(array $initialVariables): array
    {
        $solved = $initialVariables;
        $unsolved = array_diff(array_keys($this->formulas), array_keys($solved));

        $hasNewSolved = true;
        while ($hasNewSolved && !empty($unsolved)) {
            $hasNewSolved = false;
            $newlySolved = [];

            foreach ($unsolved as $variable) {
                $formula = $this->formulas[$variable];
                // 检查是否缺少依赖变量
                $missingDeps = array_diff($formula['deps'], array_keys($solved));
                if (empty($missingDeps)) {
                    // 计算变量值(注意PHP三角函数使用弧度)
                    $value = $this->expressionLanguage->evaluate($formula['expr'], $solved);
                    $newlySolved[$variable] = $value;
                    $hasNewSolved = true;
                }
            }

            $solved = array_merge($solved, $newlySolved);
            $unsolved = array_diff($unsolved, array_keys($newlySolved));
        }

        if (!empty($unsolved)) {
            throw new \RuntimeException(sprintf('无法求解以下变量:%s', implode(', ', $unsolved)));
        }

        return $solved;
    }
}

// 使用示例
try {
    $calculator = new RoofCalculator();
    // 示例:初始给定a(弧度)、A、B
    $result = $calculator->calculate(['a' => deg2rad(30), 'A' => 10, 'B' => 5]);
    print_r($result);
} catch (\RuntimeException $e) {
    echo $e->getMessage();
}

关键注意事项

  • 角度单位:PHP内置三角函数默认使用弧度,若用户输入为角度,需用deg2rad()转换;输出角度则用rad2deg()转换。
  • 公式扩展性:新增公式只需在$formulas数组中添加对应条目,确保依赖变量准确即可。
  • 异常场景:当存在无法通过现有变量推导的变量时,会抛出明确的异常信息,便于排查问题。

内容的提问来源于stack exchange,提问作者shineability

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 03:17:23