Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从O(n^3)到O(n^2)的优化算法_Java_Algorithm_Optimization - Fatal编程技术网

Java 从O(n^3)到O(n^2)的优化算法

Java 从O(n^3)到O(n^2)的优化算法,java,algorithm,optimization,Java,Algorithm,Optimization,我试图解决的问题如下: 假设在二维空间中有一组点,如何 我们能得到最大数量的共线点吗 我用Java解决了这个问题。 首先,我创建了一种检查线性的方法: return (y1 - y2) * (x1 - x3) = (y1 - y3) * (x1 - x2); 然后我使用了三个循环,这使得我的算法是O(n^3)。但我想看看这是否可以简化为O(n^2) 在网上搜索后,我发现我的实现与whats非常相似。所以问题是我们如何提高复杂性。任何例子都很好 这就是我最后做的: int p = 2; for

我试图解决的问题如下:

假设在二维空间中有一组点,如何 我们能得到最大数量的共线点吗

我用Java解决了这个问题。 首先,我创建了一种检查线性的方法:

return (y1 - y2) * (x1 - x3) = (y1 - y3) * (x1 - x2);
然后我使用了三个
循环,这使得我的算法是O(n^3)。但我想看看这是否可以简化为O(n^2)

在网上搜索后,我发现我的实现与whats非常相似。所以问题是我们如何提高复杂性。任何例子都很好

这就是我最后做的:

int p = 2; 
for (int i = 0; i < points.lenght(); i++) {
    for (int j = i+1; j < points.length(); j++) {
        int count = 2;
        for (int k =0; i < points.length(); k++) {
            if (k == i || k == j)
                 continue;
            //use linearity function to check if they are linear...    
        }
        p = max(p,count);
    }
}
int p=2;
对于(int i=0;i
您可以使用Ox使用两点之间的角度系数来解决此问题。例如,对于3个点:A B C。如果它们共线,当且仅当AB线和AC线与Ox线具有相同的角系数。这是我的伪代码:

// Type : an object to store information to use later
List<Type> res = new ArrayList<Type>();  
for (int i = 0; i < points.lenght(); i++) {
    for (int j = i+1; j < points.length(); j++) {
       double coefficient = CoeffiecientBetweenTwoLine(
                   line(points[i], points[j]), line((0,0), (0,1));
       res.add(new Type(points[i], points[j], coefficient);
    }
}
//键入:用于存储信息以供以后使用的对象
List res=new ArrayList();
对于(int i=0;i
然后,使用快速排序,根据系数在列表上方再次排序。任何系数等于,我们就可以知道哪些点是共线的。该算法的复杂性是
O(N^2logN)
(主要是用
O(N^2)
元素对列表进行排序,构建列表只需要
O(N^2)

@编辑: 那么,当我们显示等系数时,我们怎么知道有多少点共线呢? 有很多方法可以解决这个问题

  • 在排序步骤中,您可以按第一个参数进行排序(即 当两个系数相等时。例如,排序后, 结果应为(在这种情况下,如果1 3和4共线):

    (1 3) (1 4) (3 4)

从上面的建筑,你只需要看到条纹1。在这个例子中,是2。所以结果应该是3。(总是k+1)

  • 使用公式:因为始终等于的对数:
    n*(n-1)/2
    。因此,您将有:
    n*(n-1)/2=3
    。您可以知道n=3(n>= 这意味着你可以在这里解二次方程(但不能太多) 困难,因为你总是知道它有解决的办法,只是得到解决 一个解决方案(积极的)
编辑2 上面的步骤是为了知道有多少共线点是不正确的,因为在例如情况下,A B和C D是两条平行线(并且AB线不同于CD线),结果,它们仍然与Ox具有相同的系数。因此,我认为要解决此问题,可以使用
联合查找
数据结构来解决此问题。步骤为:

  • 角系数再排序 例如:(1,2,3,4)是共线的,它们与(5,6,7)平行,点8代表其他地方。因此,排序后,结果应该是:

    (12)(13)(14)(23)(24)(56)(5,7)(6,7)角系数相等,但在两条不同的直线上

    (1,5)(1,6)//将在两组平行线之间进行一些成对连接。(1,8)

    (5,8)(3,8)..//随机顺序。因为我不知道

  • 使用Union Find数据结构连接树:从第二个元素开始迭代,如果看到它的角度系数等于previous,则连接自身并连接previous。例如

    (1,3)==(1,2):连接1和2,连接1和3

    (1,4)==(1,3):连接1和3,连接1和4

    (5,6):连接2和4,连接5和6

    (5,7):加入5和7,加入5和6

    (1,8):不加入任何东西。(5,8):不加入任何东西

  • 完成这一步后,你所拥有的就是一棵多树,在每棵树中,都有一组共线的点

    在上面的步骤中,您可以看到一些对是多次连接的。您可以简单地通过标记来解决这个问题,如果它们已经连接,请忽略以进一步提高性能


    @:我认为这个解决方案不好,我只是凭我的大脑思考,而不是背后的真正算法。所以,还有什么清晰的想法,请告诉我。

    我得出了与@hqt的解决方案非常相似的结论,并想详细说明他们遗漏的细节

    如果此类元素的比率
    dx
    dy
    比率(即斜率)相同,则此类元素的两个元素相等

    static class Direction {
        Direction(Point p, Point q) {
            // handle anti-parallel via normalization
            // by making (dx, dy) lexicographically non-negative
            if (p.x > q.x) {
              dx = p.x - q.x;
              dy = p.y - q.y;
            } else if (p.x < q.x) {
              dx = q.x - p.x;
              dy = q.y - p.y;
            } else {
              dx = 0;
              dy = Math.abs(p.y - q.y);
            }
        }
    
        public boolean equals(Object obj) {
            if (obj==this) return true;
            if (!(obj instanceof Direction)) return false;
            final Direction other = (Direction) obj;
            return dx * other.dy == other.dx * dy; // avoid division
        }
    
        public int hashCode() {
            // pretty hacky, but round-off error is no problem here
            return dy==0 ? 42 : Float.floatToIntBits((float) dx / dy);
        }
    
        private final int dx, dy;
    }
    
    静态类方向{
    方向(点p、点q){
    //通过规范化处理反并行
    //通过使(dx,dy)按字典顺序非负
    如果(p.x>q.x){
    dx=p.x-q.x;
    dy=p.y-q.y;
    }否则如果(p.x
    现在通过在所有对上循环(复杂度
    O(n*n)
    )来填充番石榴的
    Multimap
    。迭代所有键(即方向)并通过a处理
    列表。找到的分区是一组共线点对。如果有
    k
    coll
        //just to create random 15 points
        Random random = new Random();
        ArrayList<Point> points = new ArrayList<Point>();
        for(int i = 0; i < 15; i++){
            Point p = new Point(random.nextInt(3), random.nextInt(3));
            System.out.println("added x = " + p.x + " y = " + p.y);
            points.add(p);
        }
    
        //code to count max colinear points
        int p = 0;
        for(int i = 0; i < points.size() -1; i++){
            int colinear_with_x = 1;
            int colinear_with_y = 1;
            for(int j = i + 1; j < points.size(); j++){
                if(points.get(i).x == points.get(j).x){
                    colinear_with_x++;
                }
                if(points.get(i).y == points.get(j).y){
                    colinear_with_y++;
                }
            }
            p = max(p,colinear_with_x,colinear_with_y);
        }
    
    map<key=(vector, point), value=quantity> pointsOnLine
    
    maxPoints = 2
    for i=1 to n
      for j=i+1 to n
        newKey = lineParametersFromPoints(point[i], point[j])
        if pointsOnLine.contains(newKey)
          pointsOnLine[key] += 1
          if maxPoints < pointsOnLine[key]
            maxPoints = pointsOnLine[key]
        else
          pointsOnLine.add(key)
          pointsOnLine[key] = 2