c++ 用STL容器实现Dijkstraalg问题

要做前端的一股清流 2016-05-04 12:22:05
我是c++初学者,老师需要我们用STL容器去实现最短路算法
cgraph::cgraph(char* inputFile)
{
ifstream file(inputFile);

file>>numvertex>>numedge;
处无法正确传参,显示节点数和边数都是无穷大,错误如下

弄了两天实在不知为何,前来一试
若有高台指教,感激不尽。
#include"CEdge.h"
#include"tryy.h"
#include"add.h"
class cgraph
{
private: int numvertex,numedge;
list<cedge *>incidentlist;
map<int,cvertex *>mapVID_vertex; // all cvertex
list<cvertex *>listtempmark;// 暂时标记的顶点的集合
map<int,list<cedge*>>mapVID_listedge;//记录与顶点关联的出度边;


public:
cgraph(char* inputFile);
cgraph(list<cedge*> listedge);
cgraph(cgraph &);
~cgraph();
int getnumvertex();
int getnumedge();
void Dijkstraalg(int s);
list<cedge*> getlist();
void PrintShortestPath(int s, int d);
void PrintAllShortestPath(int s);
void DeleteIncidentList(int c);
void update(int VID);
void pro2_1output();
void update2(int VID);
void Dijkstraalg2(int s);
};

void cgraph::update(int VID)
{
list<cedge *> ledge=mapVID_listedge[VID];
list<cedge *>::iterator i, iend;
iend=ledge.end();
for(i=ledge.begin();i!=iend;i++)
{
int w=(*i)->getWeight();
cvertex* h=mapVID_vertex[(*i)->getHead()];
cvertex* t=mapVID_vertex[VID];
if(t->d+w<h->d)
{
h->d=t->d+w;
h->p=VID;
}

}
}

void cgraph::Dijkstraalg(int s)
{
map<int,cvertex*>::iterator i,iend;
iend=mapVID_vertex.end();
for(i=mapVID_vertex.begin();i!=iend;i++)
{
if(i->second->ID==s)
i->second->d=0;
listtempmark.push_back(i->second);
}
update(s);
while(!listtempmark.empty())
{
listtempmark.sort(pvertexcomp);
int j=(*listtempmark.begin())->ID;
listtempmark.pop_front();
update(j);



}
}

cgraph::cgraph(char* inputFile)
{
ifstream file(inputFile);

file>>numvertex>>numedge;
for (int i = 0; i < numvertex; i++)
{
cvertex* vp;
vp = new cvertex(INFINITY, NULL, i);
mapVID_vertex[i] = vp;
}
for (int i = 0; i< numedge; i++)
{
int edgid,head, tail, weight,capacity; //对input函数进行修改,增加容量
file>>edgid>>head>>tail>>weight>>capacity;
cedge *ep = new cedge(edgid,head, tail, weight,capacity);
incidentlist.push_back(ep);
list<cedge*> templist;
templist = mapVID_listedge[tail];
mapVID_listedge[tail].push_back(ep);
}

file.close();
}

void cgraph::PrintShortestPath(int s, int d)
{
cout<< " the length of the shortest path from "<<s<<" to "<<d<<" is: "<<mapVID_vertex[d]->d<<endl;
cout<< " the shortest path from "<<s<<" to "<<d<<" is: ";

list<int> shortest;
shortest.push_front(d);
int pre = d;
while(s!=pre)
{
pre = mapVID_vertex[pre]->p;
shortest.push_front(pre);
}

list<int>::iterator beg, tempiter;
for(beg = shortest.begin();beg != shortest.end();beg++)
{
cout<<*beg << " ";

}
cout<<endl;
}

void cgraph::PrintAllShortestPath(int s)
{
map<int, cvertex*>::iterator mapiter ;
for (mapiter = mapVID_vertex.begin(); mapiter != mapVID_vertex.end(); mapiter++)
{
if ( s != mapiter->second->ID)
{
PrintShortestPath(s, mapiter->second->ID);
}
}
}

cgraph::~cgraph()
{
}
// ****************************************************主函数部分**************************//
int main()
{
cgraph* graph = new cgraph("dijkstra.txt");
graph->Dijkstraalg(1); //测试源结点为1的所有最短路的dijkstra和相应输出
graph->PrintAllShortestPath(1);

cout<<"function pro2_1"<<endl;
graph->PrintShortestPath(1,8);//单源单宿测试

graph->Dijkstraalg2(1); //pro2_2
cout<<"function pro2_2"<<endl;
graph->PrintAllShortestPath(1);
int c;
cout<<"input the lower limit capacity"<<endl;
cin>>c;
void DeleteIncidentList(int c); //pro2_3
graph->Dijkstraalg(1);//仍以1为例,假设删除小于c权重的边后1节点仍在图中
cout<<"function pro2_3"<<endl;
graph->PrintShortestPath(1,8);





}
...全文
378 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
thetinytony 2016-05-09
  • 打赏
  • 举报
回复
ll

/*********************************************************** 
*  --- OpenSURF ---                                       *
*  This library is distributed under the GNU GPL. Please   *
*  use the contact form at http://www.chrisevansdev.com    *
*  for more information.                                   *
*                                                          *
*  C. Evans, Research Into Robust Visual Features,         *
*  MSc University of Bristol, 2008.                        *
*                                                          *
************************************************************/

/***********************************************************
*  translated by Mr.Hu(Graduate Student of SWJTU)		   *
*  His E-mail is eleftheria@163.com						   *
************************************************************/

#include "utils.h"

#include "surf.h"

//-------------------------------------------------------
//! SURF priors (these need not be done at runtime)
const float pi = 3.14159f;

//7x7大小的2维高斯核查找表(sigma = 2.5),(0,0)在左上角,(6,6)在右下角
const double gauss25 [7][7] = {
  0.02546481,	0.02350698,	0.01849125,	0.01239505,	0.00708017,	0.00344629,	0.00142946,
  0.02350698,	0.02169968,	0.01706957,	0.01144208,	0.00653582,	0.00318132,	0.00131956,
  0.01849125,	0.01706957,	0.01342740,	0.00900066,	0.00514126,	0.00250252,	0.00103800,
  0.01239505,	0.01144208,	0.00900066,	0.00603332,	0.00344629,	0.00167749,	0.00069579,
  0.00708017,	0.00653582,	0.00514126,	0.00344629,	0.00196855,	0.00095820,	0.00039744,
  0.00344629,	0.00318132,	0.00250252,	0.00167749,	0.00095820,	0.00046640,	0.00019346,
  0.00142946,	0.00131956,	0.00103800,	0.00069579,	0.00039744,	0.00019346,	0.00008024
};

//-------------------------------------------------------

//构造函数
Surf::Surf(IplImage *img, IpVec &ipts)
: ipts(ipts)
{
  this->img = img;
}

//-------------------------------------------------------

//在向量中描述所有特征
void Surf::getDescriptors(bool upright)
{
  //检查是否有特征点
  if (!ipts.size()) return;

  //得到向量的大小
  int ipts_size = (int)ipts.size();

  if (upright)
  {
	//U-SURF循环,仅获取描述符
    for (int i = 0; i < ipts_size; ++i)
    {
	  //设置被描述的Ipoint
      index = i;

	  //提取垂直(不是旋转不变)描述符
      getDescriptor(true);
    }
  }
  else
  {
	//为SURF-64循环分配方向并获取描述符
    for (int i = 0; i < ipts_size; ++i)
    {
      //设置被描述的Ipoint
      index = i;

      //分配方向和提取旋转不变性的描述符
      getOrientation();
      getDescriptor(false);
    }
  }
}

//-------------------------------------------------------

//为Ipoint分配方向
void Surf::getOrientation()
{
  Ipoint *ipt = &ipts[index];
  float gauss = 0.f, scale = ipt->scale;
  const int s = fRound(scale), r = fRound(ipt->y), c = fRound(ipt->x);
  std::vector<float> resX(109), resY(109), Ang(109);
  const int id[] = {6,5,4,3,2,1,0,1,2,3,4,5,6};//查找表

  int idx = 0;
  //在半径为6倍尺度圆形区域内计算Ipoints的haar响应
  for(int i = -6; i <= 6; ++i) 
  {
    for(int j = -6; j <= 6; ++j) 
    {
      if(i*i + j*j < 36) 
      {
        gauss = static_cast<float>(gauss25[id[i+6]][id[j+6]]);  //可以使用abs()而不是id表查找,但这样快
        resX[idx] = gauss * haarX(r+j*s, c+i*s, 4*s);
        resY[idx] = gauss * haarY(r+j*s, c+i*s, 4*s);
        Ang[idx] = getAngle(resX[idx], resY[idx]);
        ++idx;
      }
    }
  }

  //计算主方向 
  float sumX=0.f, sumY=0.f;
  float max=0.f, orientation = 0.f;
  float ang1=0.f, ang2=0.f;

  //以特征点为中心,张角为pi/3的扇形滑动窗口
  for(ang1 = 0; ang1 < 2*pi;  ang1+=0.15f) {
    ang2 = ( ang1+pi/3.0f > 2*pi ? ang1-5.0f*pi/3.0f : ang1+pi/3.0f);
    sumX = sumY = 0.f; 
    for(unsigned int k = 0; k < Ang.size(); ++k) 
    {
	  //样点相对于正x轴角度
      const float & ang = Ang[k];

	  //确定关键点是否在窗口内
      if (ang1 < ang2 && ang1 < ang && ang < ang2) 
      {
        sumX+=resX[k];  
        sumY+=resY[k];
      } 
      else if (ang2 < ang1 && 
        ((ang > 0 && ang < ang2) || (ang > ang1 && ang < 2*pi) )) 
      {
        sumX+=resX[k];  
        sumY+=resY[k];
      }
    }

	//如果产生的矢量比所有的矢量都长,则将其方向作为新的主方向
    if (sumX*sumX + sumY*sumY > max) 
    {
	  //保存最长矢量的方向
      max = sumX*sumX + sumY*sumY;
      orientation = getAngle(sumX, sumY);
    }
  }

  //将主方向作为ipt的一个属性
  ipt->orientation = orientation;
}

//-------------------------------------------------------

//得到修正后的描述符【见文章:Agrawal ECCV 08】
void Surf::getDescriptor(bool bUpright)
{
  int y, x, sample_x, sample_y, count=0;
  int i = 0, ix = 0, j = 0, jx = 0, xs = 0, ys = 0;
  float scale, *desc, dx, dy, mdx, mdy, co, si;
  float gauss_s1 = 0.f, gauss_s2 = 0.f;
  float rx = 0.f, ry = 0.f, rrx = 0.f, rry = 0.f, len = 0.f;
  float cx = -0.5f, cy = 0.f; //以子窗口为中心取4x4高斯权重

  Ipoint *ipt = &ipts[index];
  scale = ipt->scale;
  x = fRound(ipt->x);
  y = fRound(ipt->y);  
  desc = ipt->descriptor;

  if (bUpright)
  {
    co = 1;
    si = 0;
  }
  else
  {
    co = cos(ipt->orientation);
    si = sin(ipt->orientation);
  }

  i = -8;

  //计算特征点的描述符
  while(i < 12)
  {
    j = -8;
    i = i-4;

    cx += 1.f;
    cy = -0.5f;

    while(j < 12) 
    {
      dx=dy=mdx=mdy=0.f;
      cy += 1.f;

      j = j - 4;

      ix = i + 5;
      jx = j + 5;

      xs = fRound(x + ( -jx*scale*si + ix*scale*co));
      ys = fRound(y + ( jx*scale*co + ix*scale*si));

      for (int k = i; k < i + 9; ++k) 
      {
        for (int l = j; l < j + 9; ++l) 
        {
		  //得到样本点旋转后的坐标
          sample_x = fRound(x + (-l*scale*si + k*scale*co));
          sample_y = fRound(y + ( l*scale*co + k*scale*si));

		  //得到x和y的高斯加权响应值
          gauss_s1 = gaussian(xs-sample_x,ys-sample_y,2.5f*scale);
          rx = haarX(sample_y, sample_x, 2*fRound(scale));
          ry = haarY(sample_y, sample_x, 2*fRound(scale));

		  //得到旋转后x和y的高斯加权响应值
          rrx = gauss_s1*(-rx*si + ry*co);
          rry = gauss_s1*(rx*co + ry*si);

          dx += rrx;
          dy += rry;
          mdx += fabs(rrx);
          mdy += fabs(rry);

        }
      }

	  //将值添加到描述符向量中
      gauss_s2 = gaussian(cx-2.0f,cy-2.0f,1.5f);

      desc[count++] = dx*gauss_s2;
      desc[count++] = dy*gauss_s2;
      desc[count++] = mdx*gauss_s2;
      desc[count++] = mdy*gauss_s2;

      len += (dx*dx + dy*dy + mdx*mdx + mdy*mdy) * gauss_s2*gauss_s2;

      j += 9;
    }
    i += 9;
  }

  //转换为单位向量
  len = sqrt(len);
  for(int i = 0; i < 64; ++i)
    desc[i] /= len;

}


//-------------------------------------------------------

//计算(x,y)处的,方差为sig的2维高斯值
inline float Surf::gaussian(int x, int y, float sig)
{
  return (1.0f/(2.0f*pi*sig*sig)) * exp( -(x*x+y*y)/(2.0f*sig*sig));
}

//-------------------------------------------------------

//计算(x,y)处的,方差为sig的2维高斯值
inline float Surf::gaussian(float x, float y, float sig)
{
  return 1.0f/(2.0f*pi*sig*sig) * exp( -(x*x+y*y)/(2.0f*sig*sig));
}

//-------------------------------------------------------

//计算x方向的Harr小波响应值
inline float Surf::haarX(int row, int column, int s)
{
  return BoxIntegral(img, row-s/2, column, s, s/2) 
    -1 * BoxIntegral(img, row-s/2, column-s/2, s, s/2);
}

//-------------------------------------------------------

//计算y方向的Harr小波响应值
inline float Surf::haarY(int row, int column, int s)
{
  return BoxIntegral(img, row, column-s/2, s/2, s) 
    -1 * BoxIntegral(img, row-s/2, column-s/2, s/2, s);
}

//-------------------------------------------------------

//得到点(x,y)处相对于正x轴方向的角度
float Surf::getAngle(float X, float Y)
{
  if(X > 0 && Y >= 0)
    return atan(Y/X);

  if(X < 0 && Y >= 0)
    return pi - atan(-Y/X);

  if(X < 0 && Y < 0)
    return pi + atan(Y/X);

  if(X > 0 && Y < 0)
    return 2*pi - atan(-Y/X);

  return 0;
}
799050408 2016-05-09
  • 打赏
  • 举报
回复
参考算法竞赛入门的最短路模板,那个写得已经很好了
dustpg 2016-05-04
  • 打赏
  • 举报
回复
我只看到了一堆new,然后一个delete都没有,又没有智能指针。 stl容器直接储存对象就行了,除非理由足够充分。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧