【问题标题】:Find best way to pair locations according to distance找到根据距离配对位置的最佳方式
【发布时间】:2012-01-28 08:09:01
【问题描述】:

我需要能够获取位置列表并确定配对它们的最佳方式,以便配对中每个位置之间的距离最短


我制作了一个脚本,给出了位置列表

  1. 创建一组独特的配对
  2. 对于每一对,它都会查询一个 API 以了解这对位置之间的距离

22 个位置的列表产生 231 对的列表。

使用这个生成的列表,如下所示:

address1, address2, dist

我需要找出它们之间距离最短的 11 对最佳配对。此外,此列表必须包括所有原始 22 个位置,每个位置仅在列表中出现一次。

**我正在寻找一种使用 SQL 查询、PHP 或两者兼有的解决方案

提前致谢!

【问题讨论】:

  • 你能补充更多细节吗?目前尚不清楚您是想从内存中的 PHP 数组中找到这些对,还是将它们存储在 DB 中(带有 API 响应)。表格结构也会有所帮助。

标签: php sql


【解决方案1】:

想通了。此解决方案首先查看最短距离,然后仅在之前未使用过 address1 或 address2 时才输出该行。

while ($row = mysql_fetch_assoc($res))
{
    // Assigning variables from cell values
    $address1 = $row['address1'];
    $address2 = $row['address2'];

    if(in_array($address1, $minDistance) OR in_array($address2, $minDistance)) {

    } else {
        $minDistance[] = $address1;
        $minDistance[] = $address2;
        echo $row['address1'] . '|' . $row['address2'] . '|' . $row['distance'] . '<br>';
    }
}

【讨论】:

    【解决方案2】:

    这非常复杂,如果为每一行分配某种 Id 会更简单一些。您可能会考虑这样做以简化事情,但使用您提供的数据集,这应该可以工作。

    SELECT DISTINCT TOP 11  x.*
        FROM    (SELECT r.address1
                                , MIN(r.dist) AS dist
                    FROM    (SELECT   l.address1
                                    , l.address2
                                    , l.dist
                                FROM    locdist l
                            UNION ALL
                            SELECT    l.address2 AS address1
                                    , l.address1 AS address2
                                    , l.dist
                                FROM    locdist l
                        ) r
                    GROUP BY    r.address1
            ) y
            LEFT OUTER JOIN locdist x
                ON  x.dist = y.dist
                    AND
                    (x.address1 = y.address1
                    OR
                    x.address2 = y.address1)
        ORDER BY x.dist
    

    【讨论】:

    • 对不起,我在第一次发布后才意识到它并没有完全按照您的要求进行。我相信这个版本应该可以解决问题。
    • 这个解决方案几乎可以工作,但它并不限制一个位置出现在一对以上。每个位置都必须成对使用,一旦成对使用一个位置,就不能再次使用。
    • 啊,我猜它并没有完全按照你的要求做......好吧,我不确定我会如何解决这个问题,看起来你已经有了一个解决方案,所以我想我不会担心的。
    【解决方案3】:
    SELECT address1, address2, dist, INSTR( @a , CONCAT( '--', address1 ) ) AS add1, INSTR( @a , CONCAT( '--', address2 ) ) AS add2, @a , @a := CONCAT( @a , '--', address1, '--', address2 )
    FROM `data`
    HAVING add1 =0
    AND add2 =0
    ORDER BY DIST
    LIMIT 0 , 30
    

    你可以用你的数据试试这个,它应该可以工作。

    【讨论】:

    • 您可以按照自己的方式限制行数
    猜你喜欢
    • 2021-07-25
    • 2021-01-14
    • 1970-01-01
    • 2012-02-01
    • 2017-11-19
    • 2011-04-25
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多