好吧,伙计们,我在互联网上看到了这一点,而且我一直试图弄清楚它已经好几天了。如何使用Prim算法从输入文件中找到一组坐标的MST。有一些关于如何去做的事情,但跟随他们并且是C ++的新手,他们没有多大帮助。谁能告诉我CODE(最好)如何解决这个问题?


假设我在输入文件“Something.txt”中有一组坐标,包含:

(N个节点/顶点)

(x Coord),(y coord)

 etc ...
例如:


 9
 50 100
 100 150
 200 150
 300 150
 350 100
 300 50
 200 50
 100 50
 150 100



 鉴于这些点已经存在绘制,如何编写Prim的算法?我知道这很多,但我现在已经无法将其作为C ++的新学习者而感到困惑。 (是的,我已尝试拼出代码,我已经尝试查看其他示例并扭转它们以使其工作,我已经尝试了除了看到它是如何完成的所有事情所以我可以进一步了解我保持失踪。)


提前致谢。


编辑:使用参数通过pygraphics绘制点的代码传递给它的.txt输入文件,然后进入.dat文件,然后通过预先创建的绘图文件发布:


 class Point& #xA; {

市民:

 //构造函数。
点()
 {
 x = 0; y = 0; 
 } // end constructor
 Point(int a,int b,int id)
 {
 x = a; y = b; pointID = id;
 } // end constructor

 int getX(){return x; }
 int getY(){return y; }
 int getID(){return pointID; }
字符串数据;

点(字符串x)
 {
 data = x;
 }

私人:
 int x = 0; 
 int y = 0;
 int v;
 int xVert;
 int yVert;
 int pointID = 0;

列表<点* GT; pointList;
列表<点* GT;邻居;
 //矢量<邻> myNeighborvector;

 //定位包含值x
 Point * findPoint(字符串x)
 {
 for(Point * v:pointList)
 {
 if(v-> data == x)
 return v;
 }
返回NULL;
 }

 //添加邻居从x到y
 void addDirectedNeighbor(string x,string y)
 {
 Point * xVert = findPoint(x);
 Point * yVert = findPoint(y);

 xVert-> neighbors.push_back(yVert); //我认为这应该只为x的邻居添加y,但是当我尝试显示时,我将x作为y的邻居之一
 }

 void addNeighbor(string x,string y)
 {
 addDirectedNeighbor(x,y);
 addDirectedNeighbor(y,x);
 }

}; //结束类Point


 // -------------------------------- ------------------------------------------
 class Edge&#xA ; {

市民:

 //构造函数。
边缘()
 {

 } // end constructor
边缘(Point ptA,Point ptB)
 {
 pointA = ptA;
 pointB = ptB;
 length = sqrt(pow(abs(pointA.getX() - pointB.getX()),2)+ pow(abs(pointA.getY() - pointB.getY()),2));
 } // end constructor

 Point getPtA(){return pointA; }
 Point getPtB(){return pointB; }
 double getLen(){return length; }
 int getPtAID(){return pointA.getID(); }
 int getPtBID(){return pointB.getID(); }

私人:
点A;
点B;
双倍长度;

}; //结束类Edge

 // ------------------------------------ --------------------------------------
 / * class Neighbor
 { 

市民:

 //构造函数。
邻居()
 {
 length = sqrt(pow(abs(pointA.getX() - pointB.getX()),2)+ pow(abs(pointA.getY() - pointB.getY()),2));
 } // end constructor

 double getLen(){return length; }

私人:
双倍长度;
 int pointID = 0;

}; * / // end class Neighbor

 vector< Point> myPointvector; // vector将根据需要展开
 vector< Edge> MinSpanTree;

 int main(int argc,char * argv [])
 {
 ifstream fin;
 int coordPairs; //文件中的坐标对数
 int ptX,ptY;

 int loopCounter;
 int pointCounter = 0;
 double MSTLength = 0.0;


 //检查参数的数量。预期:文件的文件名
 if(argc!= 2)//此检查通常是硬编码的
 {//如果参数失败,提供纠正建议
 cout<< “\ n该程序使用命令行参数。\ n”;
 cout<< “用法:a.exe< filename> \ n”;
出口(0);
 }



尝试//此块中的所有行都是同一个异常处理程序的一部分
 {
 fin.open(的argv [1]);
 
 catch(例外& ex)
 {
 cout<< ex.what(); //显示异常的标准说明
出口(0); //退出程序
 }


 //从文件中读取,一次一个令牌。如果已知令牌类型,则
 //可以读入相应的变量类型,例如
 //在>> X; //将第一项读入整数变量x。
 //在>>海峡; //将下一个项目读入字符串变量str。


 //此行提供图形窗口设置。 
 cout<< “800 600 white”<< ENDL;

鳍>> coordPairs;
 cout<< coordPairs<< ENDL;
 while(fin>> ptX)
 {
 //对从文件中读取的元素执行某些操作
 // cout<< ptX<< ENDL;
鳍>> PTY; 
 // cout<< ptY<< ENDL;

 cout<< “circle”<< ptX<< “”<< ptY<< “”<< 20<< “seagreen”<< ENDL;


点dummyPoint(ptX,ptY,pointCounter ++);
 myPointvector.push_back(dummyPoint); // vector将根据需要扩展

 cout<< “现在myPointvector的大小”<< myPointvector.size()<< ENDL;


 } //结束

 fin.close();

返回0;
}



答案 0 :(得分:2)
这将需要几次迭代。
你有Point
和矢量。现在编写一个函数来计算两个点之间的距离,以及一个读取数据文件并生成点向量的函数。另外,写一个包含ID号和距离的类Neighbor
,并为Point
提供一个Neighbor
向量的数据成员。
然后给Point一些成员函数1)添加一个Neighbor,2)删除一个Neighbor(由ID指定),以及3)返回Point最近邻居的副本。
完成后,尝试从矢量中弹出一个点 A ,然后迭代剩余的矢量,计算从 A 到每个矢量的距离其他点反过来,并建立 A 的邻居集合。
当所有这些工作完成后,对此答案发表评论。
编辑1:
这是一个很有希望的开始,但代码的每次迭代都是正确的至关重要。它不必做任何事情(或最初的任何事情),但它必须为1 )编译和2)运行而不会崩溃。此代码无法编译。在Neighbor()
中,您引用pointA
和pointB
而未声明它们;它们应该是构造函数的参数。在Point
中,您引用了vertex
,findVertex
,xvert
和neighbors
,其中没有一个被定义甚至声明。 (Edge
类很有意思,但不清楚你打算如何使用它。)
支持Point
和Neighbor
类(或放弃Neighbor
,转而使用Edge
),以便他们可以编译和运行,即使他们不在做得好多了。我会在几个小时后回来看看。
编辑2:
最新版本的代码中有一些功能可能不必要,但我们会看到。
这个想法是构建一个树,那么这些类如何工作呢?尝试编写一个构造三个Point(带有硬编码值)的小测试函数,并将它们组装成树。一旦开始工作,请考虑如何将Prim算法应用于这三个点。