很抱歉,如果标题令人困惑。
我在数组中有几个字符串表达式,如下所示:
var1 <= 6 && var1 > 3
var1 > 2
var1 > 4.5
var2 < 22.5
var2 >= 14.25
var2 < 16
如何评估所有表达式以确定:
var1 min
var1 max
var2 min
var2 max
我理解,对于不是“或等于”的表达式,我将无法获得确切的值。没关系。
答案 0 :(得分:3)
您正在尝试进行简单的线性编程。 SimplexInPHP在PHP中实现线性编程,您可以使用它。在行动here中查看。
另一种选择是自己实施解决方案。使用split()
将每个不等式拆分为令牌。对于每个变量,通过从[-inf,inf]范围开始计算最小值/最大值,并为每个不等式更新它。如果运算符以<
开头,则将max更新为max(cur_max, value)
;否则将min更新为min(cur_min, value)
。
您还必须跟踪终点是包含还是排他。这可以使用布尔值is_min_inclusive
和is_max_inclusive
来完成。如果操作员以=
结束,则新的终点是包含的,否则它是独占的。请务必处理x < 1
和 x <= 1
(两个订单中)的情况,这应该会导致x < 1
。
答案 1 :(得分:2)
<?php
$string = "var1 <= 6 && var1 > 0 && var2 >= 4 && var2 < 200";
//creates an array with the key 'name' and 'min OR 'max'
function parseExpression($expression){
$parts = preg_split("|( )+|", $expression,3,PREG_SPLIT_NO_EMPTY);
$result = array('name'=>$parts[0]);
switch ($parts[1]){
case '<':
$parts[2]-=1;
//NO BREAK <x same as <=(x-1)
case '<=':
$result['max'] = $parts[2];
break;
case '>':
$parts[2]+=1;
//NO BREAK >x same as >=(x+1)
case '>=':
$result['min'] = $parts[2];
break;
default:
throw new Exception("format not supported");
}
return $result;
}
$expressions = explode("&&", $string);
$vars = array();
foreach ($expressions as $expression){
$parsed = parseExpression($expression);
$name = array_shift($parsed);
foreach ($parsed as $key => $value){
if (array_key_exists($key,$vars[$name])){
switch ($key){
case 'min':
$vars[$name][$key] = min($vars[$name][$key],$value);
break;
case 'max':
$vars[$name][$key] = max($vars[$name][$key],$value);
break;
default:
}
throw new Exception("format not supported");
}
else{
$vars[$name][$key] = $value;
}
}
}
var_dump($vars);
?>
答案 2 :(得分:1)
因此,在您的示例中,您希望最小var1为> 4.5,最大值为&lt; = 6?您是否考虑过更改数据结构?
例如,如果您的数据结构如下所示:
$limits=array('lte'=>array(6), 'lt'=>array(),'gte'=>array(),'gt'=>(2,4.5);
然后解析变得微不足道。 gt和gte数组的最大值将是最小值,使用&gt;或&gt; =取决于它来自哪个阵列。 lt和lte数组的最小值将是最大值。
答案 3 :(得分:1)
<?php
$arr = array("var1 <= 6",
"var1 > 2",
"var1 > 4.5",
"var2 < 22.5",
"var2 >= 14.25",
"var2 < 16");
function find_min_max($arr, $variable) {
$min = '-inf';
$max = 'inf';
while (list($i, $v) = each($arr)) {
list($var, $rel, $value) = preg_split('/\s+/', $v);
if ($var != $variable) continue;
if ($rel == "<" || $rel == "<=") {
if ($value < $max)
$max = $value;
}
else if ($rel == ">" || $rel == ">=") {
if ($value > $min)
$min = $value;
}
}
return array($min, $max);
}
list($min, $max) = find_min_max($arr, "var1");
echo "var1 $min - $max \n";
list($min, $max) = find_min_max($arr, "var2");
echo "var3 $min - $max \n";
?>
答案 4 :(得分:-1)
我猜......
http://php.net/manual/en/function.max.php
http://php.net/manual/en/function.min.php
在示例中,它们显示了数字字符串表达式(因此不仅仅是铸造的浮点数或整数)