<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Problem mit A* Wegsuchsalgorithmus]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich arbeite gerade an einer C++-Implementierung des A* Wegsuchalgorithmus (<a href="http://de.wikipedia.org/wiki/A*" rel="nofollow">http://de.wikipedia.org/wiki/A*</a>).<br />
Leider funktioniert es nicht richtig, es wird zwar ein Pfad gefunden, aber der geht quasi durchs ganze feld durch, ist also auf keinen fall ein optimaler weg, der eigentlich gefunden werden sollte.<br />
Ich vermute, dass es (zumindest unter anderem) daran liegt, dass ich eine std::priority_queue verwende, die zeiger auf Node-Objekte speichert und ich zwischendrin im algorithmus werte der Node-Objekte ändern muss und deshalb die priority_queue natürlich nicht mehr richtig funktioniert.<br />
Allerdings ist die priority_queue schon recht wichtig, damit der algorithmus effizient abläuft. Leider hat die queue aber nichts zum entfernen (sonst könnte ichs entfernen und neu einfügen, wenn ichs ändere). Habt ihr ne idee, durch was ich die priority_queue ersetzen kann, oder sonst nen Vorschlag?<br />
Ich poste hier mal den wichtigsten teil des codes, den rest verlinke ich bei pastebin: <a href="http://pastebin.com/3ZFJEhF4" rel="nofollow">http://pastebin.com/3ZFJEhF4</a> , weils etwas viel ist.</p>
<p>Die kritische Stelle mit der priorityqueue ist unten markiert.</p>
<pre><code class="language-cpp">//pathfinder.h
class PathFinder
{
public:
	PathFinder(const Map&amp; map);
	bool FindPath(/*out*/ std::vector&lt;Point&gt;&amp; result, const Point&amp; start, const Point&amp; end);
private:
	struct Node
	{
		enum ListStatus
		{
			NotSeen, Open, Closed
		};

		Node(){pred = nullptr;}
		int GetRating() const {return stepsToHere + heuristicRating;}

		Node * pred;		
		bool passable;
		Point pos;
		int stepsToHere;
		int heuristicRating;
		unsigned int lastUsedIndex;			
		ListStatus listStatus;
	};

	struct NodeComparator
	{
		bool operator()(const Node* lhs, const Node* rhs) const
		{
			return lhs-&gt;GetRating() &lt; rhs-&gt;GetRating();
		}
	};

	typedef std::priority_queue&lt;Node*, std::vector&lt;Node*&gt;, NodeComparator&gt; OpenList;
	void InitGrid(const Map&amp; map);
	void ExpandNode(Node &amp; currentNode, OpenList&amp; openNodes);	
	void ExamineNodeAt(Node&amp; pred, int stepsToHere, const Point&amp; pos, OpenList&amp; openNodes);
	static void CreateTrace(std::vector&lt;Point&gt;&amp; result, Node &amp; currentNode);

	TwoDimensionalArray&lt;Node&gt; grid_;
	unsigned int currentUseIndex;
	ManhattanDistanceCalculator manhattan_;
	Point endPos_;
};

//pathfinder.cpp
PathFinder::PathFinder(const Map&amp; map):
grid_(map.GetWidth(), map.GetHeight())
{
	currentUseIndex = 0;
	InitGrid(map);
}

void PathFinder::InitGrid(const Map&amp; map)
{
	for(int i = 0; i &lt; grid_.GetWidth(); ++i)
	{
		for(int j = 0; j &lt; grid_.GetHeight(); ++j)
		{
			Node &amp; node = grid_.GetRefAt(i, j);
			node.lastUsedIndex = 0;
			node.passable = map.IsPassable(i, j);
			node.pos = Point(i, j);
		}
	}
}

bool PathFinder::FindPath(std::vector&lt;Point&gt;&amp; result, const Point&amp; start, const Point&amp; end)
{
	endPos_ = end;
	result.clear();
	++currentUseIndex;

	Node &amp; startNode = grid_.GetRefAt(start.x, start.y);
	startNode.lastUsedIndex = currentUseIndex;
	startNode.listStatus = Node::Open;
	startNode.passable = true;
	startNode.pos = start;
	startNode.heuristicRating = manhattan_(start, end);
	startNode.pred = nullptr;
	OpenList openNodes;
	openNodes.push(&amp;startNode);
	while(!openNodes.empty())
	{
		Node &amp; currentNode = *openNodes.top();
		openNodes.pop();
		if(currentNode.pos == end)
		{
			CreateTrace(result, currentNode);
			return true;
		}
		currentNode.lastUsedIndex = currentUseIndex;
		ExpandNode(currentNode, openNodes);
		currentNode.listStatus = Node::Closed;
	}
	return false;
}

void PathFinder::ExpandNode(Node &amp; currentNode, OpenList&amp; openNodes)
{
	int x = currentNode.pos.x;
	int y = currentNode.pos.y;
	Point pos = currentNode.pos;
	int steps = currentNode.stepsToHere;

	pos.y--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.x++;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y++;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y++;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.x--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.x--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);
}

void PathFinder::ExamineNodeAt(Node &amp; pred, int stepsToHere, const Point&amp; pos, OpenList&amp; openNodes)
{
	if(pos.x &lt; 0 || pos. x &gt;= grid_.GetWidth() || pos.y &lt; 0 || pos.y &gt;= grid_.GetHeight())
	{
		return;
	}
	++stepsToHere;
	Node&amp; node = grid_.GetRefAt(pos.x, pos.y);
	if(!node.passable)
	{
		return;
	}
	//node first seen
	if(node.lastUsedIndex != currentUseIndex)
	{
		node.pred = &amp;pred;
		node.stepsToHere = stepsToHere;
		node.lastUsedIndex = currentUseIndex;
		node.listStatus = Node::Open;
		node.heuristicRating = manhattan_(pos, endPos_);
		openNodes.push(&amp;node);
	}
	//a better way to node was found
	else
	{
		Node::ListStatus status = node.listStatus;
		if(status == Node::Closed)
		{
			return;
		}
		if(stepsToHere &lt; node.stepsToHere)
		{
//-----------&gt;//messes up priorityqueue...&lt;--------------
			node.stepsToHere = stepsToHere;
			node.pred = &amp;pred;
		}
	}
}

void PathFinder::CreateTrace(std::vector&lt;Point&gt;&amp; result, Node &amp; currentNode)
{
	if(currentNode.pred != nullptr)
	{
		CreateTrace(result, *currentNode.pred);
	}
	result.emplace_back(currentNode.pos);
}
</code></pre>
<p>Noch ein paar Hinweis:<br />
Damit ich das grid nicht jedes mal neu erstellen / auf null setzen muss, hab ich diesen lastUsedIndex und currentUseIndex gemacht. Falls der lastUsedIndex einer Node != currentIndex ist, ist die Node noch nicht besucht worden in diesem Suchvorgang.</p>
<p>Vielen Dank schonmal für eure Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/293105/problem-mit-a-wegsuchsalgorithmus</link><generator>RSS for Node</generator><lastBuildDate>Sun, 16 Aug 2026 13:10:08 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/293105.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 25 Sep 2011 21:03:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Sun, 25 Sep 2011 21:05:55 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich arbeite gerade an einer C++-Implementierung des A* Wegsuchalgorithmus (<a href="http://de.wikipedia.org/wiki/A*" rel="nofollow">http://de.wikipedia.org/wiki/A*</a>).<br />
Leider funktioniert es nicht richtig, es wird zwar ein Pfad gefunden, aber der geht quasi durchs ganze feld durch, ist also auf keinen fall ein optimaler weg, der eigentlich gefunden werden sollte.<br />
Ich vermute, dass es (zumindest unter anderem) daran liegt, dass ich eine std::priority_queue verwende, die zeiger auf Node-Objekte speichert und ich zwischendrin im algorithmus werte der Node-Objekte ändern muss und deshalb die priority_queue natürlich nicht mehr richtig funktioniert.<br />
Allerdings ist die priority_queue schon recht wichtig, damit der algorithmus effizient abläuft. Leider hat die queue aber nichts zum entfernen (sonst könnte ichs entfernen und neu einfügen, wenn ichs ändere). Habt ihr ne idee, durch was ich die priority_queue ersetzen kann, oder sonst nen Vorschlag?<br />
Ich poste hier mal den wichtigsten teil des codes, den rest verlinke ich bei pastebin: <a href="http://pastebin.com/3ZFJEhF4" rel="nofollow">http://pastebin.com/3ZFJEhF4</a> , weils etwas viel ist.</p>
<p>Die kritische Stelle mit der priorityqueue ist unten markiert.</p>
<pre><code class="language-cpp">//pathfinder.h
class PathFinder
{
public:
	PathFinder(const Map&amp; map);
	bool FindPath(/*out*/ std::vector&lt;Point&gt;&amp; result, const Point&amp; start, const Point&amp; end);
private:
	struct Node
	{
		enum ListStatus
		{
			NotSeen, Open, Closed
		};

		Node(){pred = nullptr;}
		int GetRating() const {return stepsToHere + heuristicRating;}

		Node * pred;		
		bool passable;
		Point pos;
		int stepsToHere;
		int heuristicRating;
		unsigned int lastUsedIndex;			
		ListStatus listStatus;
	};

	struct NodeComparator
	{
		bool operator()(const Node* lhs, const Node* rhs) const
		{
			return lhs-&gt;GetRating() &lt; rhs-&gt;GetRating();
		}
	};

	typedef std::priority_queue&lt;Node*, std::vector&lt;Node*&gt;, NodeComparator&gt; OpenList;
	void InitGrid(const Map&amp; map);
	void ExpandNode(Node &amp; currentNode, OpenList&amp; openNodes);	
	void ExamineNodeAt(Node&amp; pred, int stepsToHere, const Point&amp; pos, OpenList&amp; openNodes);
	static void CreateTrace(std::vector&lt;Point&gt;&amp; result, Node &amp; currentNode);

	TwoDimensionalArray&lt;Node&gt; grid_;
	unsigned int currentUseIndex;
	ManhattanDistanceCalculator manhattan_;
	Point endPos_;
};

//pathfinder.cpp
PathFinder::PathFinder(const Map&amp; map):
grid_(map.GetWidth(), map.GetHeight())
{
	currentUseIndex = 0;
	InitGrid(map);
}

void PathFinder::InitGrid(const Map&amp; map)
{
	for(int i = 0; i &lt; grid_.GetWidth(); ++i)
	{
		for(int j = 0; j &lt; grid_.GetHeight(); ++j)
		{
			Node &amp; node = grid_.GetRefAt(i, j);
			node.lastUsedIndex = 0;
			node.passable = map.IsPassable(i, j);
			node.pos = Point(i, j);
		}
	}
}

bool PathFinder::FindPath(std::vector&lt;Point&gt;&amp; result, const Point&amp; start, const Point&amp; end)
{
	endPos_ = end;
	result.clear();
	++currentUseIndex;

	Node &amp; startNode = grid_.GetRefAt(start.x, start.y);
	startNode.lastUsedIndex = currentUseIndex;
	startNode.listStatus = Node::Open;
	startNode.passable = true;
	startNode.pos = start;
	startNode.heuristicRating = manhattan_(start, end);
	startNode.pred = nullptr;
	OpenList openNodes;
	openNodes.push(&amp;startNode);
	while(!openNodes.empty())
	{
		Node &amp; currentNode = *openNodes.top();
		openNodes.pop();
		if(currentNode.pos == end)
		{
			CreateTrace(result, currentNode);
			return true;
		}
		currentNode.lastUsedIndex = currentUseIndex;
		ExpandNode(currentNode, openNodes);
		currentNode.listStatus = Node::Closed;
	}
	return false;
}

void PathFinder::ExpandNode(Node &amp; currentNode, OpenList&amp; openNodes)
{
	int x = currentNode.pos.x;
	int y = currentNode.pos.y;
	Point pos = currentNode.pos;
	int steps = currentNode.stepsToHere;

	pos.y--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.x++;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y++;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y++;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.x--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.x--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);

	pos.y--;
	ExamineNodeAt(currentNode, steps, pos, openNodes);
}

void PathFinder::ExamineNodeAt(Node &amp; pred, int stepsToHere, const Point&amp; pos, OpenList&amp; openNodes)
{
	if(pos.x &lt; 0 || pos. x &gt;= grid_.GetWidth() || pos.y &lt; 0 || pos.y &gt;= grid_.GetHeight())
	{
		return;
	}
	++stepsToHere;
	Node&amp; node = grid_.GetRefAt(pos.x, pos.y);
	if(!node.passable)
	{
		return;
	}
	//node first seen
	if(node.lastUsedIndex != currentUseIndex)
	{
		node.pred = &amp;pred;
		node.stepsToHere = stepsToHere;
		node.lastUsedIndex = currentUseIndex;
		node.listStatus = Node::Open;
		node.heuristicRating = manhattan_(pos, endPos_);
		openNodes.push(&amp;node);
	}
	//a better way to node was found
	else
	{
		Node::ListStatus status = node.listStatus;
		if(status == Node::Closed)
		{
			return;
		}
		if(stepsToHere &lt; node.stepsToHere)
		{
//-----------&gt;//messes up priorityqueue...&lt;--------------
			node.stepsToHere = stepsToHere;
			node.pred = &amp;pred;
		}
	}
}

void PathFinder::CreateTrace(std::vector&lt;Point&gt;&amp; result, Node &amp; currentNode)
{
	if(currentNode.pred != nullptr)
	{
		CreateTrace(result, *currentNode.pred);
	}
	result.emplace_back(currentNode.pos);
}
</code></pre>
<p>Noch ein paar Hinweis:<br />
Damit ich das grid nicht jedes mal neu erstellen / auf null setzen muss, hab ich diesen lastUsedIndex und currentUseIndex gemacht. Falls der lastUsedIndex einer Node != currentIndex ist, ist die Node noch nicht besucht worden in diesem Suchvorgang.</p>
<p>Vielen Dank schonmal für eure Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123611</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123611</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Sun, 25 Sep 2011 21:05:55 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 07:43:30 GMT]]></title><description><![CDATA[<p>Hat denn keiner eine Idee?</p>
<p>Ich fasse das Problem nochmal kurz zusammen, dann müsst ihr euch nicht durch den länglichen text oben quälen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
<p>Ich brauche eine priority_queue, um immer dan Knoten mit der niedrigsten Bewertung zu entfernen. Außerdem muss ich ab und zu ein Element mittendrin ändern, das kann z.B. auch durch entfernen und neueinfügen passieren.<br />
Das ganze soll trotzdem möglichst effizient sein.<br />
Was für eine Datenstruktur bietet sich da an?</p>
<p>Ich werde es evtl. mal mit einem Multiset versuchen (multi, weil die elemente nach Bewertung verglichen werden und mehrere Knoten trotz verschiedener Positionen die selbe Bewertung haben können).<br />
Vermutlich ist das entfernen in der mitte (um den wert zu ändern) aber relativ ineffizient...<br />
Edit: Vll doch nicht, in der referenz steht amortisiert konstante laufzeit, hört sich ja ganz gut an.<br />
Edit2: Ich glaube ich nehme besser ein normales set, dass primär nach bewertung geht und sekundär nach position, damit ich überhaupt ein element nach position entfernen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123711</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123711</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Mon, 26 Sep 2011 07:43:30 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 09:09:48 GMT]]></title><description><![CDATA[<p><code>std::priority_queue</code> ist ja nur ein Adapter für einen anderen Container wie <code>std::vector</code> . Du kannst mit dem letzteren die gleiche Funktionalität erreichen, dabei können dir <code>std::push_heap()</code> , <code>std::pop_heap()</code> und <code>std::make_heap()</code> aus <code>&lt;algorithm&gt;</code> helfen.</p>
<p>Übrigens hat Boost.Graph eine Implementierung für A*, falls du das Rad nicht neu erfinden willst. Die ist wahrscheinlich auch optimiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123741</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123741</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 26 Sep 2011 09:09:48 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 09:50:45 GMT]]></title><description><![CDATA[<p>Wenn es effizient sein soll, musst du dir wohl eine eigene Heap Klasse implementieren. Du kannst die <code>std::push_heap()</code> , <code>std::pop_heap()</code> Funktionen verwenden und musst noch eine Funktion schreiben, mit der du den Wert eines Eintrags im Heap ändern kannst. Das lässt sich noch ein wenig effizienter schreiben, als einer Entfernen gefolgt von ein Einfügen-Operation.</p>
<p>Falls du es ganz effizient haben willst, kannst du auch einen Fibbonacci-Heap implementieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123762</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123762</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 26 Sep 2011 09:50:45 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 10:37:01 GMT]]></title><description><![CDATA[<p>Heap selbst implementieren ist mir (zumindest erstmal) zuviel aufwand, ich versuchs erstmal mit nem set, bring es zum laufen und guck obs schnell genug läuft und wenn nicht such ich erstmal nach dem bottleneck und nur falls es dann wirklich die OpenList ist guck ich nochmal in Richtung Heaps <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
<p>Edit: Hab mir gerade doch nochmal die heap-algorithmen angeguckt, ist dann wohl doch nicht soviel aufwand, vll benutz ich doch den heap.</p>
<p>Wie kriegt man denn dabei die decreaseKey-Operation gut hin?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123774</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123774</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Mon, 26 Sep 2011 10:37:01 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 11:03:00 GMT]]></title><description><![CDATA[<p>Welche DecreaseKey-Operation? Ruf einfach makeHeap auf, wenn du<br />
Elemente in der PQ geändert hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123781</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123781</guid><dc:creator><![CDATA[HeaperHeaper]]></dc:creator><pubDate>Mon, 26 Sep 2011 11:03:00 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 11:26:51 GMT]]></title><description><![CDATA[<pre><code>make_heap: At most, (3*(last-first)) comparisons.
</code></pre>
<p>Ich sage mal O(n). Eine set mit Einfuegen/Loeschen ist aber O(log n).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123799</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123799</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 26 Sep 2011 11:26:51 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 12:05:33 GMT]]></title><description><![CDATA[<p>Dann bleib ich wohl doch beim set, außer wenn wer nen guten Vorschlag hat.</p>
<p>DecreaseKey soll heißen, dass ein element so verändert wird, dass er in der priority_queue früher drankommt als vorher.</p>
<p>Jedes element bei mir hat eine rating.<br />
Je niedriger, desto früher wirds abgearbeitet.<br />
Hin und wieder muss ich die Rating eines Elements verringern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123819</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123819</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Mon, 26 Sep 2011 12:05:33 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 13:14:32 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<pre><code>make_heap: At most, (3*(last-first)) comparisons.
</code></pre>
<p>Ich sage mal O(n). Eine set mit Einfuegen/Loeschen ist aber O(log n).</p>
</blockquote>
<p>Ein Heap lässt sich auch so implementieren, dass beliebige Elemente in O(log n) entfernt werden können. Ein Heap ist nur im Allgemeinen schneller als ein <em>set</em> (um einen konstanten Faktor). Das geht natürlich nur, wenn man weis, wo sich das entsprechende Element im Moment im Heap befindet.</p>
<p>Q schrieb:</p>
<blockquote>
<p>Wie kriegt man denn dabei die decreaseKey-Operation gut hin?</p>
</blockquote>
<p>Wenn du die irgendwo gefunden hast, dann wird die schon in Ordnung sein. Es ging mir nur darum, zu erwähnen, dass es besser geht, als entfernen und einfügen. Eben mit einer <code>decreaseKey</code> -Funktion. Man kann auch relativ einfach eine <code>changeKey</code> -Funktion bauen.</p>
<p>Heaps sind btw. hier recht gut erklärt:<br />
<a href="https://duckduckgo.com/?q=isbn+9780262033848&amp;cppnetbooks" rel="nofollow">Introduction to Algorithms | ISBN: 9780262033848</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123863</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123863</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 26 Sep 2011 13:14:32 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 14:03:11 GMT]]></title><description><![CDATA[<p>ProgChild schrieb:</p>
<blockquote>
<p>Q schrieb:</p>
<blockquote>
<p>Wie kriegt man denn dabei die decreaseKey-Operation gut hin?</p>
</blockquote>
<p>Wenn du die irgendwo gefunden hast, dann wird die schon in Ordnung sein. Es ging mir nur darum, zu erwähnen, dass es besser geht, als entfernen und einfügen. Eben mit einer <code>decreaseKey</code> -Funktion. Man kann auch relativ einfach eine <code>changeKey</code> -Funktion bauen.</p>
</blockquote>
<p>Ich habe ja keine gefunden, sondern will eine basteln <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123891</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123891</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Mon, 26 Sep 2011 14:03:11 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 14:33:51 GMT]]></title><description><![CDATA[<p>Jetzt hab ich folgendes Problem:</p>
<pre><code class="language-cpp">struct NodeComparator
	{
		bool operator()(const Node* lhs, const Node* rhs) const
		{
			if(lhs-&gt;GetRating() &lt; rhs-&gt;GetRating())
				return true;
			if(lhs-&gt;pos.x &lt; rhs-&gt;pos.x)
				return true;
			return lhs-&gt;pos.y &lt; rhs-&gt;pos.y;
		}
	};

	typedef std::set&lt;Node*, NodeComparator&gt; OpenList;
</code></pre>
<blockquote>
<p>Debug Assertion Failed!<br />
Expression: invalid operator&lt;</p>
</blockquote>
<p>Was ist denn falsch an meinem Comparator?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123902</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123902</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Mon, 26 Sep 2011 14:33:51 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 14:54:03 GMT]]></title><description><![CDATA[<p>Hallo Q,</p>
<p>du willst ja nur die Positionen vergleichen, wenn dein Rating gleich ist (und daselbe dann für dein pos.x und pos.y):</p>
<pre><code class="language-cpp">struct NodeComparator
    {
        bool operator()(const Node* lhs, const Node* rhs) const
        {
            if(lhs-&gt;GetRating() &lt; rhs-&gt;GetRating())
                return true;
            else if(lhs-&gt;GetRating() &gt; rhs-&gt;GetRating())
                return false;

            if(lhs-&gt;pos.x &lt; rhs-&gt;pos.x)
                return true;
            else if(lhs-&gt;pos.x &gt; rhs-&gt;pos.x)
                return false;

            return lhs-&gt;pos.y &lt; rhs-&gt;pos.y;
        }
    };
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2123915</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123915</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Mon, 26 Sep 2011 14:54:03 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 15:07:32 GMT]]></title><description><![CDATA[<p>Danke! Jetzt funktionierts!<br />
Hab std::set statt priority_queue verwendet.</p>
<p>Edit: Irgendwo ist nocjh nen fehler, gerade wurde ein ungültiger Pfad mit sprüngen drin gefunden.<br />
Edit2: Ups ich glaube, die Sprünge hab ich nur gesehen, weil die Konsole Zeilenumbrüche reingemacht hat <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /> Bin mir aber nicht ganz sicher.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123920</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123920</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Mon, 26 Sep 2011 15:07:32 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit A* Wegsuchsalgorithmus on Mon, 26 Sep 2011 17:29:58 GMT]]></title><description><![CDATA[<p>Q schrieb:</p>
<blockquote>
<p>Ich habe ja keine gefunden, sondern will eine basteln <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
</blockquote>
<p>Ach so. Dann habe ich dich falsch verstanden.</p>
<p>Angenommen bei deinem Heap ist immer das Minimum die Wurzel. Wenn du jetzt den Schlüssel von einem Element verminderst, dann muss dieses Element im Binärbaum so weit nach oben geschoben werden, bis der Schlüssel seiner Söhne größer sind, als es selbst. Dazu immer mit dem Vater-Knoten vergleichen und falls die Eigenschaft noch nicht erfüllt ist, die Knoten vertauschen. Das gleiche dann mit der neuen Position wiederholen, usw.</p>
<p>Mehr Details müsstest du in entsprechender Literatur nachlesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2123993</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2123993</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 26 Sep 2011 17:29:58 GMT</pubDate></item></channel></rss>