二维数组的PHP成对组合,作为Christofides算法解决方案的一部分
我正在为旅行推销员问题创建赫里斯托菲德斯算法。在算法的一部分,我需要找到一个奇数度的图的节点,然后计算最小权重。这可以通过Blossom算法来实现,但我选择了另一种方式,通过从2D数组中找到可能的组合的总和来实现,因为我正在努力使用Blossom算法,但不理解它 我有一个2D数组,它在图中存储奇数度顶点之间的权重。例如:二维数组的PHP成对组合,作为Christofides算法解决方案的一部分,php,arrays,algorithm,matrix,traveling-salesman,Php,Arrays,Algorithm,Matrix,Traveling Salesman,我正在为旅行推销员问题创建赫里斯托菲德斯算法。在算法的一部分,我需要找到一个奇数度的图的节点,然后计算最小权重。这可以通过Blossom算法来实现,但我选择了另一种方式,通过从2D数组中找到可能的组合的总和来实现,因为我正在努力使用Blossom算法,但不理解它 我有一个2D数组,它在图中存储奇数度顶点之间的权重。例如: $array = array( 0=> array(0, 2, 20,4), 1=> a
$array = array(
0=> array(0, 2, 20,4),
1=> array(2,0,7,8),
2=> array(20,2,0,12),
3=> array(4,8,12,0)
)
因此,0和1之间的权重为2,如果我选择顶点0和1,则剩下顶点2和3之间的权重,因为已经使用了顶点0和1。然后我需要对数组[0][1]和数组[2][3]的权重求和
我正在努力创建一个返回可能的顶点对组合的算法。例如,在上面的数组中,可能的对是[(0,1)(2,3)],[(0,2)(1,3)],[(0,3)(1,2)]
不能使用(0,0)、(1,1)、(2,2)、(3,3),因为它们之间没有边缘权重。此外,不需要它们的反面([(1,0)(2,3)])
通过这些对,我可以计算出权重的总和,然后选择最小的
任何帮助都将不胜感激。当您只需要一些组合时,您可以使用一些for循环。您可以使用php的array_*函数(我将在下面做)非常快速地实现您提出的要求,但我无意指出,由于以下陈述,目前的解决方案将您限制为仅包含4个顶点的数组: 如果我选择了顶点0和1,则剩下顶点2和3之间的权重,因为已经使用了顶点0和1 如果必须与5个顶点交互,“剩余权重”方面会增加复杂性,因为您拥有的不仅仅是剩余的未使用对。如果您无法修改下面提供的代码(该代码解决了4个顶点的问题),则必须在5个以上顶点的情况下定义所需的行为,以获得更多帮助
<?php
$array = array(
0=> array(0, 2, 20,4),
1=> array(2,0,7,8),
2=> array(20,2,0,12),
3=> array(4,8,12,0)
);
// Use the keys as the list of vertices.
$vertices = array_keys($array);
// Filter out nodes without weights (preserves array keys, which are used as index-relations to other nodes)
$array = array_map('array_filter', $array);
// Create a list of all valid pairs
$fullPairs = array_reduce(array_map(function($vert1, $otherVerts) use ($vertices) {
// For each first vertice, create pair combinations using weighted edge and remaining vertices
return array_map(function($vert2) use ($vert1, $vertices) {
// Because reverse combinations are not desired, we sort the pairings to easily identify dupes
$vert = array($vert1, $vert2);
sort($vert);
$vertPair = array($vert, array_values(array_diff($vertices, $vert)));
usort($vertPair, function($v1, $v2) { return reset($v1) - reset($v2); });
return $vertPair;
}, array_keys($otherVerts));
}, $vertices, $array), 'array_merge', array());
// Unique the list using a string representation of the pairs
$uniqueIndexes = array_unique(array_map('json_encode', $fullPairs));
// Match up the indexes of the unique list against the full pair list to get the pairing structure
$uniquePairs = array_intersect_key($fullPairs, $uniqueIndexes);
// Print the pairings for verification
print_r(array_map('json_encode', $uniquePairs));
// Array
// (
// [0] => [[0,1],[2,3]]
// [1] => [[0,2],[1,3]]
// [2] => [[0,3],[1,2]]
// )