Gamestudio Links
Zorro Links
Newest Posts
Free Live Data for Zorro with Paper Trading?
by dr_panther. 05/18/24 11:01
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (7th_zorro, dr_panther), 724 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Hanky27, firatv, wandaluciaia, Mega_Rod, EternallyCurious
19051 Registered Users
Previous Thread
Next Thread
Print Thread
Rating: 5
[Lite-C] Dijkstra Algorithm #204798
05/01/08 19:09
05/01/08 19:09
Joined: May 2005
Posts: 133
Germany, Passau
AlexDeloy Offline OP
Member
AlexDeloy  Offline OP
Member

Joined: May 2005
Posts: 133
Germany, Passau
I made a quick & dirty implementation of the dijksta algorithm which is useful to find the shortest path between two nodes in a (weighted) graph

An example:
In this graph we have five nodes and the weight of each edge (e.g. distance to travel, time to get there, etc.)
The shortest path between 0 and 2 is the orange one with total cost of 6 (3+3)


Now the code:

First some variables
 Code:
int nodes[5][5];      // distances in the graph as a adjacence matrix
int tmpnodes[5];      // tmp array
int distance[5];      // array for the found distances
int predecessor[5];   // array for the found predecessors
int numnodes = 5;     // how many nodes are in the graph


Then we have to init some vars
 Code:
void init_nodes() {
	// set all edges to -1 for 'not connected'
        int i,j;
	for (i = 0; i < numnodes; i++) {
		for (j = 0; j < numnodes; j++) {
			nodes[i][j] = -1;		
		}
	}
	
        // set the values for the edges
        // nodes[0][1] = 7 means the costs to travel from 0 to 1 is 7
        // nodes[1][0] could also be another value
        
	nodes[0][1] = 7;
	nodes[0][4] = 3;
	nodes[1][2] = 6;
	nodes[1][3] = 4;
	nodes[3][2] = 1;
	nodes[3][4] = 2;
	nodes[4][1] = 2;
	nodes[4][2] = 3;

	
        // set the distance between all nodes to 999
        // if you have costs over 999 set a higher value
        for (i = 0; i < numnodes; i++) {
		distance[i] = 999;
	}
        // set the distance to the start node to 0
        // if 0 is not your start node chance to distance[startnode]
	distance[0] = 0;
} 


now the algorihm:
 Code:
int dijkstra(int src, int tgt) {

	// init variables
	int i = 0;
	for (i = 0; i < numnodes; i++) {
		tmpnodes[i] = 1;
	}
	
	var minNode;
	
	int runDijkstra = 1;

	while (runDijkstra == 1) {

		// find the node with the minimal distance from the actual node
		
		minNode = tgt;
		for (i = 0; i < numnodes; i++) {
			if ((distance[i] < distance[minNode]) && (tmpnodes[i] == 1)) {
	   		minNode = i;
			}
		}
		tmpnodes[minNode] = 0;
		
		if (minNode == tgt) {
			break;
		}	
		
		// relax the edges 
		for (i = 0; i < numnodes; i++) {
			predecessor[i] = i;
			if (nodes[minNode][i] != -1) {
				var newlen = nodes[minNode][i] + distance[minNode];
				if (newlen < distance[i]) {
					distance[i] = newlen;
					predecessor[i] = minNode;
				}
			}
		}	
		
		// check if there are nodes left to check
		runDijkstra = 0;
		for (i = 0; i < numnodes; i++) {
			if (tmpnodes[i] == 1) {
				runDijkstra = 1;
			}	
		}
	}

	return distance[tgt];	
}


the dijksta function returns the shortest path, in the predecessor array are the nodes you must follow to recreate the path (start with predecessor[target] ...)

remember it's only a quick & dirty implementation and there can be errors left and of course plenty of room for improvements

[edit]
maybe a mod can move this to the lite-c contrib forum, i posted it here as a reply to 'Space StarMap Stargates' but I think the contrib forum would be better
[/edit]

Last edited by AlexDeloy; 05/01/08 22:57.
Re: [Lite-C] Dijkstra Algorithm [Re: AlexDeloy] #205169
05/04/08 17:08
05/04/08 17:08
Joined: Jul 2001
Posts: 6,904
H
HeelX Offline
Senior Expert
HeelX  Offline
Senior Expert
H

Joined: Jul 2001
Posts: 6,904
Nice! Thank you!

Re: [Lite-C] Dijkstra Algorithm [Re: HeelX] #206607
05/14/08 16:06
05/14/08 16:06
Joined: Jan 2007
Posts: 1,619
Germany
Scorpion Offline
Serious User
Scorpion  Offline
Serious User

Joined: Jan 2007
Posts: 1,619
Germany
sounds really useful. I always wanted to look into path finding by myself....

Re: [Lite-C] Dijkstra Algorithm [Re: Scorpion] #215304
07/10/08 11:44
07/10/08 11:44
Joined: Jun 2005
Posts: 87
France
MadJack Offline
Junior Member
MadJack  Offline
Junior Member

Joined: Jun 2005
Posts: 87
France
Nice job ! Very clear and short ! Much better than mine sick


Commercial A7.25b
RUGod
Re: [Lite-C] Dijkstra Algorithm [Re: MadJack] #215404
07/10/08 23:50
07/10/08 23:50
Joined: Oct 2004
Posts: 4,134
Netherlands
Joozey Offline
Expert
Joozey  Offline
Expert

Joined: Oct 2004
Posts: 4,134
Netherlands
Nice algorithm smile
Thank you


Click and join the 3dgs irc community!
Room: #3dgs
Re: [Lite-C] Dijkstra Algorithm [Re: Joozey] #215448
07/11/08 08:57
07/11/08 08:57
Joined: Oct 2006
Posts: 873
S
Shadow969 Offline
User
Shadow969  Offline
User
S

Joined: Oct 2006
Posts: 873
Thank you! smile

Re: [Lite-C] Dijkstra Algorithm [Re: Shadow969] #215529
07/11/08 20:33
07/11/08 20:33

F
Fear411
Unregistered
Fear411
Unregistered
F



i dont get it to work.
Can anyone make a little script where the player just go along the path?

Thanks

Last edited by Fear411; 07/11/08 20:33.
Re: [Lite-C] Dijkstra Algorithm [Re: ] #215531
07/11/08 21:05
07/11/08 21:05
Joined: May 2005
Posts: 133
Germany, Passau
AlexDeloy Offline OP
Member
AlexDeloy  Offline OP
Member

Joined: May 2005
Posts: 133
Germany, Passau
Unfortunately it's exam time so I don't have the time to provide a working script but you should do the following:

  • create a VECTOR array with the coods of your waypoints
  • fill the nodes[][] array with computed values (e.g. differences in height and/or distance)
  • run the algorithm
  • pass through the predecessor array, beginning with predecessor[target]
  • let your player follow the found nodes in the predecessor array


Re: [Lite-C] Dijkstra Algorithm [Re: AlexDeloy] #215591
07/12/08 10:10
07/12/08 10:10
Joined: Jun 2005
Posts: 87
France
MadJack Offline
Junior Member
MadJack  Offline
Junior Member

Joined: Jun 2005
Posts: 87
France
If you want to do this in Lite-C, you should read this thread :

Dijkstra + WED paths

You'll find there :

  • how to use paths created with WED to initialize the matrix
  • a link to a very basic demo to use it

But you should try to use Alex's algo script rather than mine for best preformances.

Anyway, I am finishing a new free plugin with a demo level to gather all this features. Delay : about 1 or two weeks...


Commercial A7.25b
RUGod
Re: [Lite-C] Dijkstra Algorithm [Re: MadJack] #290085
09/17/09 08:33
09/17/09 08:33
Joined: May 2005
Posts: 133
Germany, Passau
AlexDeloy Offline OP
Member
AlexDeloy  Offline OP
Member

Joined: May 2005
Posts: 133
Germany, Passau
Zapan@work reported some problems with the code so I looked over it and found an error.
To get the correct path you must move the line

Code:
predecessor[i] = i;



from the section "// relax the edges" of the dijkstra method to another place to initialize it.
You also have to change the value to 0 instead of i
e.g.
Code:
// init variables
	int i = 0;
	for (i = 0; i < numnodes; i++) {
		tmpnodes[i] = 1;
		predecessor[i] = 0;
	}



setting the predecessor of a node to the node itself was a bug.

I also took a more advanced graph from the german wikipedia page.



Here's the working code
Code:
#include <acknex.h>
#include <default.c>

int nodes[10][10];      // distances in the graph as a adjacence matrix
int tmpnodes[10];      // tmp array
int distance[10];      // array for the found distances
int predecessor[10];   // array for the found predecessors
int numnodes = 10;     // how many nodes are in the graph

void init_nodes() {
	// set all edges to -1 for 'not connected'
	int i,j;
	for (i = 0; i < numnodes; i++) {
		for (j = 0; j < numnodes; j++) {
			nodes[i][j] = -1;	
		}
	}
	
  // set the values for the edges
  // nodes[0][1] = 7 means the costs to travel from 0 to 1 is 7
  // nodes[1][0] could also be another value

		nodes[0][1] = 85;
		nodes[0][2] = 217;
		nodes[0][7] = 173;

		nodes[1][4] = 80;
		nodes[1][0] = 85;

		nodes[2][0] = 217;
		nodes[2][5] = 186;
		nodes[2][6] = 103;

		nodes[3][6] = 183;

		nodes[4][1] = 80;
		nodes[4][8] = 250;

		nodes[5][2] = 186;

		nodes[6][2] = 103;
		nodes[6][3] = 183;
		nodes[6][9] = 167;

		nodes[7][0] = 173;
		nodes[7][9] = 502;

		nodes[8][4] = 250;
		nodes[8][9] = 84;

		nodes[9][9] = 84;
		nodes[9][6] = 167;
		nodes[9][7] = 502;
		
	
        // set the distance between all nodes to 999
        // if you have costs over 999 set a higher value
        for (i = 0; i < numnodes; i++) {
		distance[i] = 999;
	}
        // set the distance to the start node to 0
        // if 0 is not your start node chance to distance[startnode]
	distance[0] = 0;
} 

/*****************************************************************************/

int dijkstra(int src, int tgt) {

	// init variables
	int i = 0;
	for (i = 0; i < numnodes; i++) {
		tmpnodes[i] = 1;
		predecessor[i] = 0;
	}
	
	var minNode;
	
	int runDijkstra = 1;

	while (runDijkstra == 1) {

		// find the node with the minimal distance from the actual node
		
		minNode = tgt;
		for (i = 0; i < numnodes; i++) {
			if ((distance[i] < distance[minNode]) && (tmpnodes[i] == 1)) {
	   		minNode = i;
			}
		}
		tmpnodes[minNode] = 0;
		
		if (minNode == tgt) {
			break;
		}	
		
		// relax the edges 
		for (i = 0; i < numnodes; i++) {
			//predecessor[i] = i;
			if (nodes[minNode][i] != -1) {
				var newlen = nodes[minNode][i] + distance[minNode];
				if (newlen < distance[i]) {
					distance[i] = newlen;
					predecessor[i] = minNode;
				}
			}
		}	
		
		// check if there are nodes left to check
		runDijkstra = 0;
		for (i = 0; i < numnodes; i++) {
			if (tmpnodes[i] == 1) {
				runDijkstra = 1;
			}	
		}
	}

	return distance[tgt];	
}

void main()
{
	STRING* sTemp = str_create("");
	STRING* sTemp2 = str_create("");

	int start = 0;
	int ziel = 9;
	init_nodes();
	int dist = dijkstra(start, ziel);

	str_cpy(sTemp,"distance:\t");
	str_cat(sTemp, str_for_num(sTemp2,dist));
	error(sTemp);
	
	str_cpy(sTemp,"path:\t");
	int tmp = ziel;
	
	str_cat(sTemp, str_for_num(sTemp2,ziel));

	int tmp2;
	
	int vorgaenger;
	
	// run through predecessors	
        while (tmp != start) {
		vorgaenger = predecessor[tmp];
		str_cat(sTemp, " <- ");
		str_cat(sTemp, str_for_num(sTemp2,vorgaenger));
		tmp = vorgaenger;
	}	

	// sTemp now contains the reversed path
	error(sTemp);
}




Moderated by  HeelX, Spirit 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1