slavawins/mathsolutionfinder

0.2 2023-02-24 12:28 UTC

This package is auto-updated.

Last update: 2024-09-24 15:45:50 UTC


README

MathSolutionFinder

这是一个简单的PHP包,用于处理数学组合优化问题。

使用composer安装

composer require slavawins/mathsolutionfinder

简单示例

我想到的最简单的事情是找到两个乘积数之间的最大值。很明显,答案将是两个变量数。

use MathSolutionFinder\Library\MathSolutionFinder;

        $module = MathSolutionFinder::New()->SetMode()->Max()
            ->AddPropertyRange("one", 1, 100, 6)
            ->AddPropertyRange("two", 1, 5, 10)
            ->SetCallable(function ($data) {
                return $data['one'] * $data['two'];
            });

        $result = $module->Learn();
        dump($result);        
        

结果如下

array:2 [
      0 => 500
      1 => array:2 [
        "one" => 100
        "two" => 5
      ]
]

我们创建一个类,并指定我们想要计算最大值。

接下来,我们使用 ->AddPropertyRange("one", 1, 100, 6) 添加一个需要计算的属性。它的名字叫one,范围从1到100。6表示这个数字需要计算的不同组合数。数字越大,结果越精确,但计算负担也越大。

然后我们使用 ->SetCallable(function ($data) { 在这个函数内部进行的计算将在遍历所有属性组合时执行。}

为了理解计算状态,我们可以使用这样的函数:dump($module->GetStatus());

array:4 [
    "bestResult" => 500
    "maxTry" => 60
    "lastTry" => 59
    "percent" => 98.33
]

它会显示最佳结果bestResult和maxTry,即执行了多少次尝试。

示例:查找特定值。假设我们想要找到使输出为320的属性值。

        $module = MathSolutionFinder::New()->SetMode()->Similar(320.525)
            ->AddPropertyRange("one", 1, 100, 6)
            ->AddPropertyRange("two", 1, 5, 10)
            ->SetCallable(function ($data) {
                return $data['one'] * $data['two'];
            });
        
        $result = $module->Learn();

        dump($result);
        

考虑到步长,我们将得到这样的结果:"bestResult" => 335

增加步长并允许使用非整数

    $module = MathSolutionFinder::New()->SetMode()->Similar(320.525)
        ->AddPropertyRange("one", 1.1, 100.2, 416)
        ->AddPropertyRange("two", 1, 5, 410)
        ->SetCallable(function ($data) {
            return $data['one'] * $data['two'];
        });

    $result = $module->Learn();

然后我们将得到这样的结果
"bestResult" => 320.75769230769
"maxTry" => 170560

是的,检查了170560种组合来解决这个简单方程)

缓存

如果我们使用limit函数,则会启用文件缓存。$module->Limit(10); 在调用Learn()时将检查10种组合。数据会在请求之间保存。可以在cron作业中启动或在控制台中。

缓存和计算优化

这是此包最酷的部分,也是人们下载它的主要原因。这个例子允许你连续多次运行它,它不会从零开始计算,而是从上次停止的地方继续。每次检查10种组合。但除此之外,它还有一个函数 $module->AnalizWeight(); 这个功能会取几个保存的结果,比较它们,并推测应该插入哪些值以获得更好的结果。对于某些计算,这可能会将训练时间缩短几倍!

    $module = MathSolutionFinder::New()->SetMode()->Max()
        ->AddPropertyRange("one", 1.1, 100, 55)
        ->AddPropertyRange("two", 1, 50, 55)
        ->SetCallable(function ($data) {
            return $data['one'] * $data['two'];
        });

    $module->Limit(10);
    $result = $module->Learn();
    $optim = $module->AnalizWeight();

    dump($result);
    dump($optim);
    dump($module->GetStatus());


array:2 [
0 => 3878.8236363636
1 => array:2 [
"one" => 94.605454545455
"two" => 41
]
]
array:5 [
"randData" => array:2 [
"result" => 263.25272727273
"data" => array:2 [
"one" => 15.485454545455
"two" => 17
]
]
"bestData" => array:2 [
"result" => 3878.8236363636
"data" => array:2 [
"one" => 94.605454545455
"two" => 41
]
]
"delta" => array:2 [
"one" => 79.12
"two" => 24
]
"mathDeltaData" => array:2 [
"one" => 100
"two" => 50
]
"mathDeltaResult" => array:2 [
0 => 5000
1 => true
]
]
array:4 [
"bestResult" => 5000
"maxTry" => 3025
"lastTry" => 10
"percent" => 0.33
]
"ok"

我将翻译这些日志中的内容:第一次尝试后找到了数字3878。(因为组合是随机启动的)。然后启动了AnalizWeight,它推测应该插入数字100和50。然后立即解决了问题。在3025次尝试中的10次。

数字预测

dump("UP TRATE");
$data = [
'1 day' => 1001,
'2 day' => 1011,
'3 day' => 1010,
'4 day' => 1070,
'5 day' => 1072,
];
$result = PredictSolutionFinder::PredicatInfo($data);

dump($result);

dump("negatrive TRATE");
$data = [
    '1 day' => 1001,
    '2 day' => 971,
    '3 day' => 950,
    '4 day' => 961,
    '5 day' => 948,
];
$result = PredictSolutionFinder::PredicatInfo($data);