» »

[Algoritem] Kako do najkrajše poti na med točkami

[Algoritem] Kako do najkrajše poti na med točkami

dice7 ::

Kako bi jaz našel najkrajšo pot med, recimo, modro in zeleno točko na spodnji sliki. Znane bi imel koordinate vseh točk in koordinate do katerih lahko prideš od ene koordinate (to bi imel za vse koordinate shranjene).
 slika

slika



Pač razmišlju sem, da bi pač primerjal dolžine vseh možnih poti in izbral najkrajšo, vendar nekako ne vem na kak način bi začel. Predlogi zelo dobrodošli.
  • spremenil: dice7 ()

Pegaz ::

En enostaven način je tale:
Narediš eno for loop zanko, ki gre čez array točk. Notri maš še eno for zanko, ki gre prav tako čez array teh točk, a začne točke gledat tam eno naprej od tiste točke, katero ima zgornja for zanka.

Pogledaš razdaljo med točkama z enačbo: sqrt( (x2-x1)2 + (y2-y1)2). Če je manjša od trenutne najmanjše, jo shraniš.

for (int i = 0; i < array.lenght, i++) {
--for(int j = i+1; j < array.lenght; j++) {
--// pregledaš razdaljo in jo shraniš, če je najmanjša
--} 
}


Kakšen hitrejši način naj pa kdo drug pove.

MrBrdo ::

najbolje je verjetno da pogledaš kakšen routing algoritem, tam se rešuje ta problem
Category:Routing algorithms @ Wikipedia
najbolj znan je Dijkstra, če nimaš negativnih povezav itd... pri dijkstri je najhitrejše če delaš z priority queue (kopica).
če pa iščeš najkrajšo pot med vsemi točkami pa mislim da je floyd-warshall kar dober
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

dice7 ::

Pegaz, ja na to sem že razmišlu, sam potem bi se zgubil, ker bi npr pri zgornji sliki, če bi šel od zelene proti modri in bi točka desno od zelene bila malo bližje zeleni, bi šlo na popolnoma napačno pot


MrBrdo, hvala bom pogledal

AndyS ::

Dijkstra, tjt

Pegaz ::

dice7, vse kombinacije grejo čez, nobena se ne izgubi.

napsy ::

Dijkstra, Kruskal, ...
Minimum spanning tree @ Wikipedia
"If you die, you die. But when you live you live. There is no time to waste."

Spura ::

Naredi A* pa je. Hevristicna funkcija je lahko navadna ali pa manhattan razdalja. A* je boljsi od Dijkstre v tvojem primeru.

joze67 ::

Kakšen primer je to, da je O(n^3) algoritem boljši od O(n logn)?

Mavrik ::

Kakšen O(n^3)?! A* je preprosto Dijkstra, ki pri polnjenju prioritetne vrste upošteva zraven še hevristiko razdalje do konca in pri tem v večini primerov konča v manj iteracijah.
The truth is rarely pure and never simple.

Spura ::

joze67 je izjavil:

Kakšen primer je to, da je O(n^3) algoritem boljši od O(n logn)?

Wat?

Spura ::

Pa crtaj manhattan razdaljo. V tem primeru potem ne bo admissable. My bad. Kr navadno evklidsko uporabi.

Zgodovina sprememb…

  • spremenil: Spura ()

krneki0001 ::

Za iskanje najkrajše poti med točkami je dijkstrov algoritem
Dijkstrov algoritem @ Wikipedia

template <typename T, class edgeType>
void graph<T, edgeType>::dijkstra()
{
	// To store min vertex
	typedef std::priority_queue<graph<T>::vertexPtr> PQ;
	PQ cont;

	// backtrack vertex and its distance
	typedef map<string, int> myMap;
	myMap backVertex;
	stack<myMap> restoreStack;

	// To store visited vertex 
	vector<vertexPtr> visitedVertex;
	vector<int> distance;
	vector<graph<T>::vertexPtr> result;
	
	boost::shared_ptr<vertex<T> > aVertex;
	std::vector<edgePtr> myEdge;
	
	cont.push(allVertex[0]);
	distance.push_back(0);
	while (!cont.empty())
	{
		aVertex = cont.top();
		cont.pop();

		visitedVertex.push_back(aVertex);
		result.push_back(aVertex);
		myEdge = aVertex->getIncidentEdge();

		string minVertexID("");
		int minWeightage = myEdge[0]->getWeightage();
		for (int counter=0;counter<static_cast<int>(myEdge.size());++counter)
		{
			bool isNotVisit = true; 
			for (int sentinel=0;sentinel<static_cast<int>(visitedVertex.size());++sentinel)
			{
				if (visitedVertex[sentinel]->getVertexID() 
					== myEdge[counter]->getSecondVertexID())
				{
					isNotVisit = false;
					if (counter + 1 < static_cast<int>(myEdge.size()))
					{
						minWeightage = myEdge[counter+1]->getWeightage();
						minVertexID = myEdge[counter+1]->getSecondVertexID();
					}
					break;
				}
				else
				{
					isNotVisit = true;
				}
			}

			if (isNotVisit)
			{
				if (counter + 1 < static_cast<int>(myEdge.size()))
				{
				// To determine min weightage				
					if (myEdge[counter+1]->getWeightage() < minWeightage)
					{
						minWeightage = myEdge[counter+1]->getWeightage();
						minVertexID = myEdge[counter+1]->getSecondVertexID();
						myEdge.erase(myEdge.begin()+counter+1);
					}
				}
			}
		}

		// Update backtrack vertex and its distance
		
	

		// push minVertexID and update its distance
		for (int myLoop=0;myLoop<static_cast<int>(allVertex.size());++myLoop)
		{
			if (allVertex[myLoop]->getVertexID() == minVertexID)
			{
				cont.push(allVertex[myLoop]);
				minWeightage = distance.at(distance.size()-1) + minWeightage;
				distance.push_back(minWeightage);
				break;
			}
		}

		minVertexID.erase(0);
		minWeightage = 0;
	}	

	// Display result
	cout << "\n\n";
	for (int myLoop=0;myLoop<static_cast<int>(result.size());++myLoop)
	{
		cout << result[myLoop]->getVertexID() 
			<< "(" << distance[myLoop] << ")" <<  "->";
	}

}

krneki0001 ::

Lahko pa uporabiš tudi tale algoritm (napisan je v ruby-ju)
module Algorithms

    # Floyd's algorithm to solve the all-pairs, shortest path problem
    # for the given edge-weighted, directed graph.
    # +g+:: An edge-weighted, directed graph.
    def Algorithms.floydsAlgorithm(g)
        n = g.numberOfVertices
        distance = DenseMatrix.new(n, n)
        for v in 0 ... n
            for w in 0 ... n
                distance[v, w] = Fixnum::MAX
	    end
	end
	g.edges do |e|
            distance[e.v0.number, e.v1.number] = e.weight
	end
        for i in 0 ... n
            for v in 0 ... n
                for w in 0 ... n
                    if distance[v, i] != Fixnum::MAX and \
                        distance[i, w] != Fixnum::MAX
                        d = distance[v, i] + distance[i, w]
			distance[v, w] = d if distance[v, w] > d
		    end
		end
	    end
	end
        result = DigraphAsMatrix.new(n)
        for v in 0 ... n
            result.addVertex(v)
	end
        for v in 0 ... n
            for w in 0 ... n
                if distance[v, w] != Fixnum::MAX
                    result.addEdge(v, w, distance[v, w])
		end
	    end
	end
        return result
    end

end

Spura ::

On rabi pot med dolocenim parom, ne poti med vsemi moznimi pari.

krneki0001 ::

Mal nej popravi programček, pa je.

MrBrdo ::

za pot med dolocenim parom je najboljsi dijkstra se mi zdi (floyd warshall je za med vsemi je malo drugacen algoritem ne dosti)
MrBrdo

dice7 ::

Pač ja, rabu bi ugotovit kk najti najkrajšo pot med določenima točkama in točke ne bi bile pravilno razporejene (bi bile slepe ulice). Razmišljal sem, da bi za vsako točko shranu do katere točke lahka preko nje prideš in tako naprej, sam nisem čist prepričan kako to izvest.

Zgornji algoritmi mi pa povzročajo malce zmede :S

Zgodovina sprememb…

  • spremenil: dice7 ()

Arto ::

napsy je izjavil:

Dijkstra, Kruskal, ...
Minimum spanning tree @ Wikipedia


Kruskal je druga zgodba, če sem se prav naučil.

Dijkstro implementiraj, je precej enostavna zadeva.

MrBrdo ::

dice7: dijkstra je res na easy... mislim da glavni pogoj pri dijkstri je da nimaš povezav z negativno ceno (npr. da bi rekel med T1 in T2 je razdalja (cena) -10).

http://renaud.waldura.com/doc/java/dijk...
tole si poglej zgleda kr vredu razloženo
MrBrdo

alexa-lol ::

Dijkstra je uredu

Zgodovina sprememb…

Spura ::

MrBrdo je izjavil:

za pot med dolocenim parom je najboljsi dijkstra se mi zdi (floyd warshall je za med vsemi je malo drugacen algoritem ne dosti)

A* je vedno boljsi od dijkstre, ker je izboljsava dijkstre. Na nekem navadnem grafu ne mores delat A*, ker nimas iz cesa racunat hevristicne funkcije. V danem primeru pa so vozlisca grafa tocke s koordinatami, utezi povezav pa razdalja, kar lahko uporabis v hevristicni funkciji. Zato je tukaj A* mogoc is precej boljsi od dijkstre. Dijstra dodatno informacijo iz lokacije vozlisc povsem ignorira, in zato tukaj ni optimalen. A*, pri katerem je hevristicna funkcija vedno enaka 0 za vsa vozlisca je dijkstra.

Zgodovina sprememb…

  • spremenil: Spura ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[c++] naloge

Oddelek: Programiranje
476162 (4702) technolog
»

c# QuadTree Indexing

Oddelek: Programiranje
7853 (675) RobertDev
»

[C#] Sesutje aplikacije

Oddelek: Programiranje
111616 (1451) Jean-Paul
»

[C++] prevajalnik hoce konstruktor za strukturo

Oddelek: Programiranje
182596 (2300) Tr0n
»

Katero workstation graficno?

Oddelek: Kaj kupiti
191673 (1393) Senitel

Več podobnih tem