qt foreach无法计算.exe_Floyd六边形最短路径计算

Floyd属于动态规划类计算最短路径的算法,通常的解法并不记录最短路径走法。笔者这里放一个带最短路径走法的Floyd算法。

c++代码如下

int findPairIDByPair(const QMap<int, QPoint>& ref, const QPoint& p)
{
	auto itr = ref.begin();
	while (itr != ref.end())
	{
		if (itr.value() == p)
			return itr.key();
		itr++;
	}
	return -1;
}
int  floyd(const QList<QPoint>& vertices, const  QList<QLine>& edges, const QPoint& from, const QPoint&  to, QList<QPoint>& output)
{
	if (!(vertices.contains(from) && vertices.contains(to)))
		return -1;
	QList<QPoint> points(vertices);
	points.removeAll(from);
	points.removeAll(to);
	points.push_front(from);
	points.push_back(to);
	foreach(auto line,edges)
	{
		if (!points.contains(line.p1()))
			return -1;
		if (!points.contains(line.p2()))
			return -1;
	}
	const int MAX_VALUE = std::numeric_limits<short>::max();
	const int size = points.size();
	QVector<boost::shared_array<QPair<int, int>>> ptr(size);
	for (int i = 0; i < size; i++)
		ptr[i].reset(new QPair<int, int>[size]);
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size; j++)
		{
			ptr[i][j].first = MAX_VALUE;
			ptr[j][i].first = MAX_VALUE;
		}
		ptr[i][i].first = 0;
	}
	QMap<int, QPoint> ref;
	for (int i = 0; i < size; i++)
		ref[i] = points[i];
	foreach(auto line, edges)
	{
		auto id1 = findPairIDByPair(ref, line.p1());
		auto id2 = findPairIDByPair(ref, line.p2());
		ptr[id1][id2].first = 1;
		ptr[id2][id1].first = 1;
	}
	for (int i = 0; i < size; i++)
		for (int j = 0; j < size; j++)
			for (int k = 0; k < size; k++)
			{
				if (ptr[i][j].first > ptr[i][k].first + ptr[k][j].first)
				{
					ptr[i][j].second = k;
					ptr[i][j].first = ptr[i][k].first + ptr[k][j].first;
				}
			}
	if (ptr[0][size - 1].first >= MAX_VALUE)
		return -1;
	output.clear();
	int i = size - 1;
	output.append(ref[i]);
	while (i != 0)
	{
		i = ptr[0][i].second;
		output.append(ref[i]);
	}
	std::reverse(output.begin(), output.end());
	return output.size() - 1;
}

函数int floyd(const QList<QPoint>& vertices, const QList<QLine>& edges, const QPoint& from, const QPoint& to, QList<QPoint>& output),参数分别是要计算点列表,边列表,起始和终止点,最短走点列表。

测试demo如下

class MinPath : public Scene
{
public:
	MinPath();
	~MinPath();
public:
	void initGL();
	void glDraw();
	void qtDraw(QWidget* widget);
	void update(int time);
public:
	void mousePressEvent(QMouseEvent* event);
	void mouseMoveEvent(QMouseEvent* event);
	void keyPressEvent(QKeyEvent* event);
private:
	QFont font;
	QPoint lastPos;
	QList<QPoint> points;
	QList<QPoint> drawPoints;
};
#define START QPoint(0,0)
#define END   QPoint(16,11)
MinPath::MinPath()
{
}
MinPath::~MinPath()
{
}
void MinPath::initGL()
{
	font.setPointSize(11);
	QColor bgcolor(30,30,90,90);
	World::getInstance().getGLPainter()->setBackgroundColor(bgcolor);
	//auto vimage = QImage("tank.png");
	/*texture = new QOpenGLTexture(vimage.mirrored());
	texture->setMinificationFilter(QOpenGLTexture::Nearest);
	texture->setMagnificationFilter(QOpenGLTexture::Linear);
	texture->setWrapMode(QOpenGLTexture::Repeat);
	texture->bind();
	glEnable(GL_TEXTURE_2D);
	glShadeModel(GL_FLAT);*/
}
void MinPath::glDraw()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	auto painter = World::getInstance().getGLPainter();
	glColor3f(0, 0, 0.3);
	painter->drawHexGons(0, 0, World::getInstance().getWorldResolution(), 60, 64);
	auto mgr = World::getInstance().getGridCellManager();
	auto res = World::getInstance().getWorldResolution()*0.6;
	painter->setLineWidth(2.0);
	glColor3f(0.9, 0.2, 0.3);
	auto p = mgr->getWorldPosByCellCoordinate(START.x(), START.y());
	painter->drawHexGon(p.x(), p.y(), res*0.6);
	p = mgr->getWorldPosByCellCoordinate(END.x(), END.y());
	painter->drawHexGon(p.x(), p.y(), res*0.6);
	glColor3f(0.6, 0.1, 0.1);
	foreach(auto item, points)
	{
		p = mgr->getWorldPosByCellCoordinate(item.x(), item.y());
		painter->drawWrongNumber(p, res);
	}
	glColor3f(0.1, 0.6, 0.2);
	int count = drawPoints.size();
	if (count > 0)
	{
		for (int i = 0; i < count - 1; i++)
		{
			auto p1 = mgr->getWorldPosByCellCoordinate(drawPoints[i].x(),drawPoints[i].y());
			auto p2 = mgr->getWorldPosByCellCoordinate(drawPoints[i+1].x(), drawPoints[i+1].y());
			painter->drawLine(p1,p2);
		}
	}
	painter->setLineWidth(1.0);
	glPopMatrix();
}
void MinPath::qtDraw(QWidget* widget)
{
	QPainter pter(widget);
	pter.setPen(QColor(30,120,90));
	pter.setFont(font);
	pter.drawText(8,20,QStringLiteral("鼠标左键设置和取消障碍,空格键计算最短路径"));
	pter.end();
}
void MinPath::update(int time)
{
}
void MinPath::mousePressEvent(QMouseEvent* event)
{
	if (event->button() == Qt::MouseButton::RightButton)
	{
		return;
	}
	lastPos = event->pos();
	int height = World::getInstance().getWorldSize().height();
	auto pos = World::getInstance().getGridCellManager()->getCellCoordinateByWorldPos(lastPos.x(), height - lastPos.y());
	if (pos == START || pos == END)
		return;
	auto itr = qFind(points, pos);
	if (itr == points.end())
		points.push_back(pos);
	else
	{
		std::remove(points.begin(), points.end(), pos);
	}
}
void MinPath::mouseMoveEvent(QMouseEvent* event)
{
}
void MinPath::keyPressEvent(QKeyEvent* event)
{
	if (event->key() == Qt::Key::Key_Space)
	{
		auto edges = World::getInstance().getGridCellManager()->getAdjacentCellsInMap(END.x(), END.y(), points);
		QList<QPoint> allPoints;
		for (int i = 0; i <= END.x(); i++)
			for (int j = 0; j <= END.y(); j++)
			{
				allPoints.append(QPoint(i, j));
			}
		int cnt = floyd(allPoints, edges, START, END, drawPoints);
		if (cnt == -1)
			drawPoints.clear();
	}
}

显示截图如下

e0e62a9529aa640ec6fdc8c9347ebaa3.png

f62998373c856b5d935f8990b945d8c5.png

如果需要完整代码请联系本人~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值