slavawins / mathsolutionfinder
扩展
Requires
- php: ^7.3|^8.0
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);