分组类似的盒子
我有一组(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)
作为一个例子,我只用了16组数据,这些坐标就像这样分开了我的方形 -
类似框的定义
那些有相似数量邻居的盒子被认为是相似的盒子。 对于盒子上方的图像[8],盒子[13]等有4个最近的邻居。 所以他们被认为是相似的盒子。
下面的图片应该使这个清晰的 -
::我的问题::
从图片我们可以看到 -
对于框[8] ,最近的框是:
框(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;
}
它给出了像这样的正确结果 -
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
虽然它可以识别最近的盒子并计算邻居的数量,但我无法弄清楚如何将相似的盒子分组(如上所述)并找出总和。
我被困在这里。 谁能帮我?
更新了代码片段
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 %dn", it->first, it->second);
}
return 0;
}
给我错误 -
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>&)’
我该如何解决它?
除了尝试计算您的价值之外,我还对代码进行了一些小修改。
既然你所有的列表索引都不是负数,并且未来可能会有大量的矩形,我建议将所有的int
变为unsigned
。 这有一个额外的好处,就是可以抑制某些编译器警告,比较下面的代码中的有符号和无符号整数。
我建议你做的第二个改变是只声明一次rects
,而不是每次迭代isNearest
。 在下面的代码中,我通过使rects
成为一个全局变量并创建一个单独的函数来初始化它来实现这一目标。 通过将rects
一个全局变量,您现在可以用rects.size()
替换所有16
s(减少在添加完整数据集时忘记更改一个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 %dn", it->first, it->second);
}
return 0;
}
更新:现在可以通过在源文件中指定Rect
或从外部文件加载来使用上述代码。 在上面的修改示例中,输入文件是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
以上输出结果:
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
而不是试图维护某些数据结构中的矩形之间的关系,那么使矩形对象本身变得聪明并知道它的邻居数量和它们是谁是更好的主意。
例如(不完整的proptotype来说明想法):
class Rect {
public:
//methods
Rect(double X1, double Y1, double X2, double Y2);
//const access
double getX1() const;
double getX2() const;
double getY1() const;
double getY2() const;
int numNeighbors() const { return neighbors.size();}
int sumOfNeighbors() const { int res(0); for(size_t i=0;i< neighbors.size();++i) res += neighbors[i]->numNeighbors(); return res;}
std::vector<Rect*> getNeighbors() {return neighbors};
void addNeighbor(Rect* newNeighbor) {neighbors.push_back(newNeighbor);}
//data
private:
double x1, x2, y1, y2; // coordinates
std::vector<Rect*> neighbors;
};
有了这样的矩形类,你可以为每个矩形添加邻居,检索它自己的每个矩形的所有邻居,以及它们的所有邻居 - 所有关系都保留在矩形本身而不是一些外部对象中,主程序的代码应该非常小。
一旦你填充了rects,你可以简单地遍历它们,选择具有所需数量的邻居,并对它们进行任何操作。
我想如果你想大幅度简化所有这些,你可以使用Kobelevskiy先生的建议:
#include <iostream>
#include <cstdlib>
#include <vector>
#include <stdio.h>
using namespace std;
class Rect {
public:
double x1, x2, y1, y2; // coordinates
//methods
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;
}
}
~Rect()
{
};
int numNeighbors() const { return neighbors.size();}
int sumOfNeighbors() const { int res(0); for(size_t i=0;i< neighbors.size();++i) res += neighbors[i]->numNeighbors(); return res;}
std::vector<Rect*> getNeighbors() {return neighbors;};
void addNeighbor(Rect* newNeighbor) {neighbors.push_back(newNeighbor);}
//data
std::vector<Rect*> neighbors;
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;
void CalculateAdjacentsForRect(unsigned int rects_element){
for (unsigned int x = 0; x < rects.size(); x++) {
if (rects[rects_element]->isAdjacent(rects[x])) {
if (x==rects_element) {
continue; //this is our box , so do not count it.
}
rects[rects_element]->addNeighbor(rects[x]);
}
}
}
const int MAX_ADJACENT_RECTS = 10;
int main() {
//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));
for (unsigned int i = 0; i < rects.size(); i++)
{
CalculateAdjacentsForRect(i);
}
for (unsigned int i = 0; i < rects.size(); i++)
{
cout << "nRect" << i << " has a neighbor sum of " << rects[i]->sumOfNeighbors();
}
cout << "n";
for (int ix = 0; ix < MAX_ADJACENT_RECTS; ix++)
{
int num_rects_with_this_num_of_adjacents = 0;
int num_adjacents_total_for_similar_rects = 0;
for (unsigned int i = 0; i < rects.size(); i++) {
if ( rects[i]->numNeighbors() == ix ) {
num_rects_with_this_num_of_adjacents++;
num_adjacents_total_for_similar_rects += rects[i]->sumOfNeighbors();
}
}
cout << "nThere are " << num_rects_with_this_num_of_adjacents << " rects with " << ix << " adjacent rects. They have a cum neighbor sum of " << num_adjacents_total_for_similar_rects;
}
return 0;
}
链接地址: http://www.djcxy.com/p/73661.html
下一篇: Java 8 autoboxing + generics: different behaviour with variable vs. method