【问题标题】:How can I find the least rect, which contains all points or the point symmetrical to the y=x axis?如何找到包含所有点或与 y=x 轴对称的点的最小矩形?
【发布时间】:2016-01-12 21:11:13
【问题描述】:

我有一组点 (x,y)。如何找到包含这些点或与 y=x 轴对称的点的最小矩形(边垂直于坐标系的轴)?并非所有的点都必须同时是镜像,因此可以有一些正常的点和一些与原始点对称的点。

【问题讨论】:

  • 您基本上是在问如何计算二维边界矩形?只需遍历集合中的每个点并获取每个组件的最小值和最大值,您将拥有一个边界矩形。
  • 否;他要求一个轴对齐的边界矩形,但可以选择用它们的镜像对应物替换集合中的任意多个点。这就是挑战。
  • @ThorngardSO 这不是挑战。最小的矩形总是可以很容易地通过镜像所有点来生成,这样它们就分布在一个象限上,如果对称是轴向或两个象限,如果它是点对称。
  • @Paul 我也有类似的怀疑,但完全不确定。但如果是这种情况,请将其发布为答案!
  • 最小的 x*y 还是最小的 x+y?

标签: algorithm optimization dynamic-programming mathematical-optimization


【解决方案1】:

可以使用蛮力O(n*2^n) 方法解决此问题:将您的点定义为一些类/结构,除了您的点的(x,y) 坐标外,它还包含一个布尔值mirrored 状态。对于n 点数,循环遍历这组点的所有2^n 可能状态集。对于每组状态,计算边界矩形的周长 (2x+2y)。

以下是在 Swift 中实现的解决方案。如果您选择使用这种蛮力方法,希望您可以将其翻译成您选择的语言。


点容器和帮助功能:

struct Point {
    private var xOrig : Double
    private var yOrig : Double
    private var mirrored = false
    var x : Double { return mirrored ? yOrig : xOrig }
    var y : Double { return mirrored ? xOrig : yOrig }

    init(_ x: Double, _ y: Double) {
        xOrig = x
        yOrig = y
    }

    mutating func setState(state: Bool) {
        mirrored = state
    }
}

func boundingBoxCircumference(points: [Point]) -> Double {
    let xMax = points.maxElement { $0.x < $1.x }?.x ?? 0.0
    let xMin = points.minElement { $0.x < $1.x }?.x ?? 0.0
    let yMax = points.maxElement { $0.y < $1.y }?.y ?? 0.0
    let yMin = points.minElement { $0.y < $1.y }?.y ?? 0.0

    return 2*((xMax - xMin) + (yMax - yMin))
}

func setMirroredStates(inout points: [Point], states: [Bool]) {
    for i in 0..<points.count {
        points[i].setState(states[i])
    }
}

主要功能及示例

func findSmallestBox(var points: [Point]) -> Double {
    var smallestBox = Double.infinity
    for i in 0..<Int(pow(2,Double(points.count))) {
        smallestBox = min(smallestBox, boundingBoxCircumference(points))

        var binString = String(i, radix: 2)
        if let a = Optional(points.count - binString.characters.count) where a > 0 {
            binString = "".stringByPaddingToLength(a, withString: "0", startingAtIndex: 0) + binString
        }
        let pointStates = Array(binString.characters).map { String($0) == "1" }

        setMirroredStates(&points, states: pointStates)
    }
    return smallestBox
}

var myPoints : [Point] = [Point(1,2), Point(-4,3), Point(7,-5), Point(5,4), Point(-5, -1)]
print(findSmallestBox(myPoints)) // 34

【讨论】:

  • 感谢您的代码,但不幸的是我知道暴力解决方案。我正在寻找更好的解决方案,因为 0(n*2^n) 太多了。
  • @WojtekPrzechodzeń 我明白了,也许其他人能想出办法。
猜你喜欢
  • 1970-01-01
  • 2012-09-09
  • 2022-10-06
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 2019-01-29
  • 2017-11-30
相关资源
最近更新 更多