【问题标题】:How to translate this Math Formula in Haskell or Python? (Was translated in PHP)如何在 Haskell 或 Python 中翻译这个数学公式? (已用 PHP 翻译)
【发布时间】:2012-01-26 04:07:21
【问题描述】:

我正在尝试将数学公式转换为 PHP 代码。

您可以在此处查看已接受答案中的公式:Applying a Math Formula in a more elegant way (maybe a recursive call would do the trick)

我不是专业的编码员,所以我正在尽力翻译它,但我的技能有限,并且遇到了一些问题。

让我们开始吧。

有一个包含玩家堆栈的向量:我认为二维数组应该在这里完成工作。我会添加一个密钥来识别每个玩家。

$array = array(1 => 2000, 3 => 5000 ...);

现在他想创建一个值矩阵,我进行了研究,发现了一个名为 Math_Matrix 的 PEAR 包,安装了它,但我想知道如何创建这种矩阵。

我担心我无法翻译整个代码,因为他使用了递归调用等高级方法。

你能帮帮我吗?

编辑:旧赏金奖励

我尝试了您的建议,但由于我的编程技能差,我觉得浪费了我的时间。

如果有人想通过在 PHP 中翻译该公式来帮助我,我决定提供 50 赏金。

请注意,如果您认为用 Python 进行翻译更容易/更合适/其他,请提供一种将 Python 脚本包含在 PHP 脚本中的方法,因为我计划在网站中使用此公式。

【问题讨论】:

  • 我只能说是哇.....这是对非数学编程语言的一些严肃数学。
  • 你认为有人可以用 PHP 解决这个问题吗?
  • 或者我可以用PHP实现的哪种语言可以解决这个问题?
  • 我说我不知道​​它是否可以在 PHP 中解决。我倾向于说这很可能是可能的。但是还有其他编程语言,例如 Haskell 和 Python(我知道我在这里遗漏了一些其他语言,这些只是我知道的),它们是更好的面向数字和数学的语言。我还想 PHP 中的解决方案可能很长并且运行缓慢。
  • 数组数组也可以看作一个矩阵。这实际上是大多数计算器、库等实现它的方式。

标签: php python math haskell matrix


【解决方案1】:

我想最大的问题是你打算用这个做什么。最后,我真的建议不要使用 PHP。它不是为这种类型的工作而设计的,你以后会为自己做很多工作。

如果您只是在寻找一种计算方法,我建议您使用 Octave(MATLAB 的开源版本)如果您真的想围绕它构建一个程序,您应该使用 NumPy 模块研究 Python:@987654321 @


如果你有能力,我会推荐使用 mod_python 来运行 NumPy 来处理这个问题。这可能是最简单的方法,因为 NumPy 可以原生处理矩阵。除此之外,您应该查看以下用于在 PHP 中处理矩阵的类。有些人开发了一些专门用于处理矩阵的类。

http://www.phpkode.com/scripts/item/matrix-new/ http://www.phpclasses.org/package/2859-PHP-Perform-operations-with-matrices.html

【讨论】:

  • 我想创建一个这样的网站:icmpoker.com/Calculator.aspx 它似乎使用类似的算法来计算股票。
  • 继续并添加了更多特定于您所追求的信息以及一些专门为 PHP 中的矩阵数学设计的类的链接。我仍然认为 Python 会更好地处理它,但是根据您对虚拟主机的控制,它的实现有点困难。
  • 谢谢你,我会做一些研究以在 PHP 中实现这一点,因为我不知道 Python 并且在网站中实现它应该会使它更加复杂......
【解决方案2】:

给你。

我将此代码放入公共域。

# Function to make an array of 'width' zeros
function makerow($width){
 $row=array();
 for($x=0;$x<$width;$x++){
   $row[$x]=0;
 }
 return $row;
}

# Function to make a width*height matrix
function makematrix($width,$height){
 $matrix=array();
 for($y=0;$y<$height;$y++){
  $matrix[$y]=array();
  for($x=0;$x<$width;$x++){
   $matrix[$y][$x]=0;
  }
 }
 return $matrix;
}

# Adds one matrix to another
function matrixadd(&$matrixdest,&$matrixsrc){
 for($i=0;$i<count($matrixdest);$i++){
  for($j=0;$j<count($matrixdest[$i]);$j++){
   $matrixdest[$i][$j]+=$matrixsrc[$i][$j];
  }
 }
}

# Multiplies a matrix by a scalar
function matrixmultiply(&$matrix,$scalar){
 for($i=0;$i<count($matrix);$i++){
  for($j=0;$j<count($matrix[$i]);$j++){
   $matrix[$i][$j]*=$scalar;
  }
 }
}

# Calculates the equity of each place. Rows indicate players;
# columns indicate places (0 is 1st place, 1 is second, and so on)
# The parameter 'places' is optional.  If not given, uses the 
# number of stacks.
function equitymatrix(&$stacks, $places=-1){
 if($places==-1){
  # replace places with the stack count
  $places=count($stacks);
 }
 if(count($stacks)<=1){
  return array(array(1));
 }  
 $totalStacks=0;
 for($i=0;$i<count($stacks);$i++){
  $totalStacks+=$stacks[$i];
 }
 # Optimize for case where there is only one place
 if($places==1){
  $matrix=makematrix(1,count($stacks));
  for($i=0;$i<count($stacks);$i++){
   $matrix[$i][0]=$stacks[$i]*1.0/$totalStacks;
  }
  return $matrix;
 }
 # Optimize for case where there are two places
 if($places==2){
  $matrix=makematrix(2,count($stacks));
  for($i=0;$i<count($stacks);$i++){
   $matrix[$i][0]=$stacks[$i]*1.0/$totalStacks;
  }
  for($i=0;$i<count($stacks);$i++){
   for($j=0;$j<count($stacks);$j++){
    if($i!=$j){
     $matrix[$i][1]+=$matrix[$j][0]*($stacks[$i]*1.0/($totalStacks-$stacks[$j]));
    }
   }
  }
  return $matrix;
 }
 # Calculate the probabilities of each player getting first place
 $probabilities=array();
 for($i=0;$i<count($stacks);$i++){
  $probabilities[$i]=$stacks[$i]*1.0/$totalStacks;
 }
 #echo(count($stacks)." ".$places."\n");
 $subequities=array();
 for($i=0;$i<count($stacks);$i++){
  $substacks=array();
  # Assume that player i would be in first place
  # Create a new array with i's stack removed
  for($j=0;$j<count($stacks);$j++){
   if($j!=$i){
    array_push($substacks,$stacks[$j]);
   }
  }
  # Find the subequity of the remaining players
  $subequities[$i]=equitymatrix($substacks,
    min($places,count($substacks)));
  for($j=0;$j<count($subequities[$i]);$j++){
   array_unshift($subequities[$i][$j],0);
  }
  # Add player i back
  $newrow=makerow($places);
  $newrow[0]=1;
  array_splice($subequities[$i],$i,0,array($newrow));
 }
 $equities=makematrix($places,count($stacks));
 for($i=0;$i<count($stacks);$i++){
  # Multiply the probabilities
  matrixmultiply($subequities[$i],$probabilities[$i]);
  # Add the subequity
  matrixadd($equities,$subequities[$i]);
 }
 return $equities;
}

例子:

$mystacks=array(10,40,30,20);
print_r(equitymatrix($mystacks));

关于矩阵的使用:

在 PHP 中,矩阵可以表示为数组的数组。你可以看到 在函数makematrix中,它返回一个长度为height的数组, 每个元素都是width 零的数组。您的问题使用以下内容 矩阵运算,两者都很简单:

  • 添加两个矩阵 (matrixadd)。在这里,只需将一个矩阵的元素添加到 另一个矩阵的对应元素。
  • 简单地将矩阵乘以单个数字(标量)(matrixmultiply) 涉及将矩阵的每个元素乘以该数字。

【讨论】:

  • 我已经分析了你的代码,它太棒了! :) 唯一的问题在于数学算法本身:太慢了。是否可以通过仅计算确定数量的场所权益来加快代码速度?我的意思是:在有 6 名玩家的情况下,上面的代码将计算每个位置上每个玩家的胜率,直到第 6 名。如果我们只需要他们在第一和第二名的胜率,我们可以跳过剩余代码,不是吗?拥有类似 print_r(equitymatrix($mystacks,2)); 之类的东西会很有用。数字保留在我们要计算权益的地方。
  • 我已经编辑了答案中的代码,按照您的建议添加了一个额外的参数,并在需要一两个位置的情况下添加优化。但是,很难针对两个以上的地方优化此解决方案,因为复杂性与 玩家 的数量有关,而不是与所需地点的数量有关。
  • 我已将您的答案作为已接受的答案授予您,并将 50 代表奖金归功于您。感谢您的努力。
【解决方案3】:

如果你安装了 Matlab,带有符号数学工具箱,

您可以使用ccode 函数将此公式(或任何其他公式)转换为 c 代码(与 php 非常相似)。

【讨论】:

    猜你喜欢
    • 2012-09-25
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多