将类似的盒子分组

ari*_*152 7 c++ algorithm

我有一组(X,Y)坐标,它将单位正方形划分为子矩形.假设我的坐标是 -

         (    x1,    y1)    (    x2,    y2)      

         (0.0000,0.0000)    (0.3412,0.4175)   
         (0.7445,0.0000)    (1.0000,0.6553)   
         (0.7445,0.6553)    (1.0000,1.0000)   
         (0.0000,0.6553)    (0.7445,1.0000)   
         (0.3412,0.0000)    (0.7445,0.4175)   
         (0.3412,0.4175)    (0.7445,0.6553)   
         (0.0000,0.4175)    (0.3412,0.6553)....etc (total 10,000 coordinates)
Run Code Online (Sandbox Code Playgroud)

作为一个例子,我只采集了16组数据,这些坐标分割我的方块,如下所示 -

在此输入图像描述

类似框的定义

具有相似数量的邻居的那些盒子被认为是类似的盒子.对于方框[8]上方的图像,方框[13]等有4个最近邻居.所以他们被认为是类似的盒子.

下面的图片应该清楚 -

在此输入图像描述

::我的问题::

从图像我们可以看到 -

对于方框[8],最近的方框是:

box(1)(有4个邻居)

框[4](也有4个邻居)

盒子[14](有4个邻居)

盒子[16](有4个邻居)

因此,在这种情况下,最近框的邻居之和= 4 + 4 + 4 + 4 = 16

再次箱[13]最近的框是:

框[3](有6个邻居)

框[5](也有4个邻居)

盒子[6](有3个邻居)

框[12](有3个邻居)

因此,在这种情况下,最近框的邻居之和= 6 + 4 + 3 + 3 = 16

在这里,(类似框)框[8]和框[13] = 16 + 16 = 32的邻居总数.

类似地,我想将所有具有4个邻居的框分组,并找到最近框的邻居之和.并继续为每个类似的团体.

我的守则

这是我的代码.

#include <iostream>
#include <cstdlib>
#include <vector>
#include <stdio.h>

using namespace std;

class Rect {
public:
double x1, x2, y1, y2; // coordinates

Rect(double X1, double Y1, double X2, double Y2) {
  if (X1 < X2) {
    x1 = X1; x2 = X2;
  } else {
    x2 = X1; x1 = X2;
  }
  if (Y1 < Y2) {
    y1 = Y1; y2 = Y2;
  } else {
    y2 = Y1; y1 = Y2;
  }


}

bool isAdjacent(Rect rect) {
    if (x1 == rect.x1 || x1 == rect.x2 ||
        x2 == rect.x1 || x2 == rect.x2) {
      // use only < when comparing y1 and rect.y2 avoids sharing only a corner
      if (y1 >= rect.y1 && y1 < rect.y2) {
        return true;
      }
      if (y2 > rect.y1 && y2 <= rect.y2) {
        return true;
      }
      if (rect.y1 >= y1 && rect.y1 < y2) {
        return true;
      }
      if (rect.y2 > y1 && rect.y2 <= y2) {
        return true;
      }
    }
    if (y1 == rect.y1 || y1 == rect.y2 ||
        y2 == rect.y1 || y2 == rect.y2) {
      if (x1 >= rect.x1 && x1 < rect.x2) {
        return true;
      }
      if (x2 > rect.x1 && x2 <= rect.x2) {
        return true;
      }
      if (rect.x1 >= x1 && rect.x1 < x2) {
        return true;
      }
      if (rect.x2 > x1 && rect.x2 <= x2) {
        return true;
      }
    }
    return false;
  }

};



void isNearest(int b){

vector<Rect> rects;     
                //Rect(  x1 ,  y1  ,   x2  ,  y2   ) 
  rects.push_back(Rect(0.0000,0.0000, 0.8147,0.1355));
  rects.push_back(Rect(0.8147,0.0000, 1.0000,0.1355));

  rects.push_back(Rect(0.8147,0.1355, 0.9058,0.8350));
  rects.push_back(Rect(0.0000,0.1355, 0.1270,0.9689));

  rects.push_back(Rect(0.9058,0.1355, 0.9134,0.2210));
  rects.push_back(Rect(0.9058,0.8350, 1.0000,1.0000));
  rects.push_back(Rect(0.8147,0.8350, 0.9058,1.0000));


  rects.push_back(Rect(0.1270,0.1355, 0.6324,0.3082));
  rects.push_back(Rect(0.1270,0.9689, 0.8147,1.0000));
  rects.push_back(Rect(0.0000,0.9689, 0.1270,1.0000));

  rects.push_back(Rect(0.9134,0.1355, 1.0000,0.2210));
  rects.push_back(Rect(0.9134,0.2210, 1.0000,0.8350));
  rects.push_back(Rect(0.9058,0.2210, 0.9134,0.8350));


  rects.push_back(Rect(0.6324,0.1355, 0.8147,0.3082));
  rects.push_back(Rect(0.6324,0.3082, 0.8147,0.9689));
  rects.push_back(Rect(0.1270,0.3082, 0.6324,0.9689));


  int nearBox_count = 0;

  double TotalArea=0;


  for (int x = 0; x < rects.size(); ++x) {

    if (rects[b].isAdjacent(rects[x])) {


      if (x==b) {
continue; //this is our box , so do not count it.
}


nearBox_count++;

printf("box[%d] is nearest to box[%d]  \n", (b+1), (x+1));

}
}

printf("Total number of nearest box for [%d] is %d  \n",(b+1),nearBox_count );
printf("\n");

}


int main() {

  for (int i = 0; i < 16; ++i)
  {
    isNearest(i);
  }

return 0;
}
Run Code Online (Sandbox Code Playgroud)

它给出了正确的结果,如下所示 -

box[1] is nearest to box[2]  
box[1] is nearest to box[4]  
box[1] is nearest to box[8]  
box[1] is nearest to box[14]  
Total number of nearest box for [1] is 4  

box[2] is nearest to box[1]  
box[2] is nearest to box[3]  
box[2] is nearest to box[5]  
box[2] is nearest to box[11]  
Total number of nearest box for [2] is 4  

box[3] is nearest to box[2]  
box[3] is nearest to box[5]  
box[3] is nearest to box[7]  
box[3] is nearest to box[13]  
box[3] is nearest to box[14]  
box[3] is nearest to box[15]  
Total number of nearest box for [3] is 6  

box[4] is nearest to box[1]  
box[4] is nearest to box[8]  
box[4] is nearest to box[10]  
box[4] is nearest to box[16]  
Total number of nearest box for [4] is 4  

box[5] is nearest to box[2]  
box[5] is nearest to box[3]  
box[5] is nearest to box[11]  
box[5] is nearest to box[13]  
Total number of nearest box for [5] is 4  

box[6] is nearest to box[7]  
box[6] is nearest to box[12]  
box[6] is nearest to box[13]  
Total number of nearest box for [6] is 3  

box[7] is nearest to box[3]  
box[7] is nearest to box[6]  
box[7] is nearest to box[9]  
box[7] is nearest to box[15]  
Total number of nearest box for [7] is 4  

box[8] is nearest to box[1]  
box[8] is nearest to box[4]  
box[8] is nearest to box[14]  
box[8] is nearest to box[16]  
Total number of nearest box for [8] is 4  

box[9] is nearest to box[7]  
box[9] is nearest to box[10]  
box[9] is nearest to box[15]  
box[9] is nearest to box[16]  
Total number of nearest box for [9] is 4  

box[10] is nearest to box[4]  
box[10] is nearest to box[9]  
Total number of nearest box for [10] is 2  

box[11] is nearest to box[2]  
box[11] is nearest to box[5]  
box[11] is nearest to box[12]  
Total number of nearest box for [11] is 3  

box[12] is nearest to box[6]  
box[12] is nearest to box[11]  
box[12] is nearest to box[13]  
Total number of nearest box for [12] is 3  

box[13] is nearest to box[3]  
box[13] is nearest to box[5]  
box[13] is nearest to box[6]  
box[13] is nearest to box[12]  
Total number of nearest box for [13] is 4  

box[14] is nearest to box[1]  
box[14] is nearest to box[3]  
box[14] is nearest to box[8]  
box[14] is nearest to box[15]  
Total number of nearest box for [14] is 4  

box[15] is nearest to box[3]  
box[15] is nearest to box[7]  
box[15] is nearest to box[9]  
box[15] is nearest to box[14]  
box[15] is nearest to box[16]  
Total number of nearest box for [15] is 5  

box[16] is nearest to box[4]  
box[16] is nearest to box[8]  
box[16] is nearest to box[9]  
box[16] is nearest to box[15]  
Total number of nearest box for [16] is 4  
Run Code Online (Sandbox Code Playgroud)

虽然它可以识别最近的方框并计算邻居的数量,但我无法弄清楚如何对类似的方框进行分组(如上所述)并找到总和.

我被困在这里.谁能帮我?

更新了代码段

vector<CheckRect> rects;

unsigned isNearest(unsigned b, vector<unsigned>& neighbours) {

  unsigned nearBox_count = 0;

  for (unsigned x = 0; x < rects.size(); ++x) {
    if (rects[b].isAdjacent(rects[x])) {
      if (x==b) continue; //this is our box , so do not count it.
      nearBox_count++;
      printf("box[%d] is nearest to box[%d]  \n", (b+1), (x+1));
      neighbours.push_back(x);
    }
  }

  printf("Total number of nearest box for [%d] is %d  \n",
        (b+1), nearBox_count );
  printf("\n");

  return nearBox_count;
}

int main(){

cin>>N;

for(int b=0; b<N; b++){

  ifstream inputFile1("RectCoordinates.txt"); //input from the file previously generated
  int rect_number;
  double xa0,ya0,xa1,ya1;
  int neighbours;
  isNearest( b, &neighbours);// This is the line that causing my ERROR


  }
 vector<unsigned> nearBox_count(rects.size());
  vector< vector<unsigned> > neighbours(rects.size());
  for (unsigned i = 0; i < rects.size(); ++i) {
    nearBox_count[i] = isNearest(i, neighbours[i]);
  }

  // Calculate the sums of neighbouring boxes
  vector<unsigned> neighCount(rects.size(), 0);
  for (unsigned i = 0; i < rects.size(); i++) {
    for (unsigned j = 0; j < neighbours[i].size(); j++) {
      neighCount[i] += nearBox_count[neighbours[i][j]];
    }
  }

  // Calculate your result
  map<unsigned,unsigned> finalCount;
  for (unsigned i = 0; i < rects.size(); i++)
  {
    if (finalCount.count(nearBox_count[i]) == 0)
      finalCount[nearBox_count[i]] = neighCount[i];
    else
      finalCount[nearBox_count[i]] += neighCount[i];
  }

  // Print the result
  for (map<unsigned,unsigned>::iterator it = finalCount.begin();
        it != finalCount.end(); ++it) {
    printf("Sum neighbours for the neighbours of similar boxes with %d "
           "neighbours is %d\n", it->first, it->second);
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

给我错误 -

ss.cpp: In function ‘int main()’:
ss.cpp:102:29: error: invalid initialization of reference of type ‘std::vector<unsigned int>&’ from expression of type ‘unsigned int’
ss.cpp:22:10: error: in passing argument 2 of ‘unsigned int isNearest(unsigned int, std::vector<unsigned int>&)’
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

ile*_*nt2 0

除了尝试计算您的价值之外,我还对您的代码进行了一些细微的更改。

由于您所有的列表索引都不是负数,并且将来您可能会拥有大量的矩形,因此我建议将所有ints 放入unsigned. 这样做的另一个优点是可以抑制某些编译器关于比较下面代码中的有符号和无符号整数的警告。

我建议您进行的第二个更改是仅声明rects一次,而不是每次迭代时都声明isNearest。在下面的代码中,我通过创建rects一个全局变量并创建一个单独的函数来初始化它来实现这一点。通过创建rects全局变量,您现在可以将所有16s 替换为(减少在添加完整数据集时rects.size()忘记更改变量的可能性)。16

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <map>
#include <stdio.h>

using namespace std;

class Rect {
public:
  double x1, x2, y1, y2; // coordinates

  Rect(double X1, double Y1, double X2, double Y2) {
    if (X1 < X2) {
      x1 = X1; x2 = X2;
    } else {
      x2 = X1; x1 = X2;
    }
    if (Y1 < Y2) {
      y1 = Y1; y2 = Y2;
    } else {
      y2 = Y1; y1 = Y2;
    }
}

bool isAdjacent(Rect rect) {
    if (x1 == rect.x1 || x1 == rect.x2 ||
        x2 == rect.x1 || x2 == rect.x2) {
      // use only < when comparing y1 and rect.y2 avoids sharing only a corner
      if (y1 >= rect.y1 && y1 < rect.y2) {
        return true;
      }
      if (y2 > rect.y1 && y2 <= rect.y2) {
        return true;
      }
      if (rect.y1 >= y1 && rect.y1 < y2) {
        return true;
      }
      if (rect.y2 > y1 && rect.y2 <= y2) {
        return true;
      }
    }
    if (y1 == rect.y1 || y1 == rect.y2 ||
        y2 == rect.y1 || y2 == rect.y2) {
      if (x1 >= rect.x1 && x1 < rect.x2) {
        return true;
      }
      if (x2 > rect.x1 && x2 <= rect.x2) {
        return true;
      }
      if (rect.x1 >= x1 && rect.x1 < x2) {
        return true;
      }
      if (rect.x2 > x1 && rect.x2 <= x2) {
        return true;
      }
    }
    return false;
  }
};

vector<Rect> rects;

unsigned isNearest(unsigned b, vector<unsigned>& neighbours) {

  unsigned nearBox_count = 0;

  for (unsigned x = 0; x < rects.size(); ++x) {
    if (rects[b].isAdjacent(rects[x])) {
      if (x==b) continue; //this is our box , so do not count it.
      nearBox_count++;
      printf("box[%d] is nearest to box[%d]  \n", (b+1), (x+1));
      neighbours.push_back(x);
    }
  }

  printf("Total number of nearest box for [%d] is %d  \n",
        (b+1), nearBox_count );
  printf("\n");

  return nearBox_count;
}

void initRects(void) {

                //Rect(  x1 ,  y1  ,   x2  ,  y2   ) 
  rects.push_back(Rect(0.0000,0.0000, 0.8147,0.1355));
  rects.push_back(Rect(0.8147,0.0000, 1.0000,0.1355));

  rects.push_back(Rect(0.8147,0.1355, 0.9058,0.8350));
  rects.push_back(Rect(0.0000,0.1355, 0.1270,0.9689));

  rects.push_back(Rect(0.9058,0.1355, 0.9134,0.2210));
  rects.push_back(Rect(0.9058,0.8350, 1.0000,1.0000));
  rects.push_back(Rect(0.8147,0.8350, 0.9058,1.0000));


  rects.push_back(Rect(0.1270,0.1355, 0.6324,0.3082));
  rects.push_back(Rect(0.1270,0.9689, 0.8147,1.0000));
  rects.push_back(Rect(0.0000,0.9689, 0.1270,1.0000));

  rects.push_back(Rect(0.9134,0.1355, 1.0000,0.2210));
  rects.push_back(Rect(0.9134,0.2210, 1.0000,0.8350));
  rects.push_back(Rect(0.9058,0.2210, 0.9134,0.8350));


  rects.push_back(Rect(0.6324,0.1355, 0.8147,0.3082));
  rects.push_back(Rect(0.6324,0.3082, 0.8147,0.9689));
  rects.push_back(Rect(0.1270,0.3082, 0.6324,0.9689));
}

void readRects(const string& filename) {

  ifstream fpInput(filename.c_str());
  double dTemp[4];

  while (true) {
    for (unsigned i = 0; i < 4; i++) fpInput >> dTemp[i];
    if (!fpInput.good()) break;
    rects.push_back(Rect(dTemp[0], dTemp[1], dTemp[2], dTemp[3]));
  }

  fpInput.close();
}

int main() {

  // Initialize the vector rects
  //initRects();
  readRects("RectCoordinates.txt");

  vector<unsigned> nearBox_count(rects.size());
  vector< vector<unsigned> > neighbours(rects.size());
  for (unsigned i = 0; i < rects.size(); ++i) {
    nearBox_count[i] = isNearest(i, neighbours[i]);
  }

  // Calculate the sums of neighbouring boxes
  vector<unsigned> neighCount(rects.size(), 0);
  for (unsigned i = 0; i < rects.size(); i++) {
    for (unsigned j = 0; j < neighbours[i].size(); j++) {
      neighCount[i] += nearBox_count[neighbours[i][j]];
    }
  }

  // Calculate your result
  map<unsigned,unsigned> finalCount;
  for (unsigned i = 0; i < rects.size(); i++)
  {
    if (finalCount.count(nearBox_count[i]) == 0) {
      finalCount[nearBox_count[i]] = neighCount[i];
    } else {
      finalCount[nearBox_count[i]] += neighCount[i];
    }
  }

  // Print the result
  for (map<unsigned,unsigned>::iterator it = finalCount.begin();
        it != finalCount.end(); ++it) {
    printf("Sum neighbours for the neighbours of similar boxes with %d "
           "neighbours is %d\n", it->first, it->second);
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

更新:Rect现在可以通过在源文件中指定 s 或从外部文件加载来使用上面的代码。在上面的修改示例中,输入文件是RectCoordinates.txt

0.0000  0.0000  0.8147  0.1355
0.8147  0.0000  1.0000  0.1355

0.8147  0.1355  0.9058  0.8350
0.0000  0.1355  0.1270  0.9689

0.9058  0.1355  0.9134  0.2210
0.9058  0.8350  1.0000  1.0000
0.8147  0.8350  0.9058  1.0000


0.1270  0.1355  0.6324  0.3082
0.1270  0.9689  0.8147  1.0000
0.0000  0.9689  0.1270  1.0000

0.9134  0.1355  1.0000  0.2210
0.9134  0.2210  1.0000  0.8350
0.9058  0.2210  0.9134  0.8350


0.6324  0.1355  0.8147  0.3082
0.6324  0.3082  0.8147  0.9689
0.1270  0.3082  0.6324  0.9689
Run Code Online (Sandbox Code Playgroud)

以上输出结果:

Sum neighbours for the neighbours of similar boxes with 2 neighbours is 8
Sum neighbours for the neighbours of similar boxes with 3 neighbours is 32
Sum neighbours for the neighbours of similar boxes with 4 neighbours is 165
Sum neighbours for the neighbours of similar boxes with 5 neighbours is 22
Sum neighbours for the neighbours of similar boxes with 6 neighbours is 25
Run Code Online (Sandbox Code Playgroud)