Startpunkten

This commit is contained in:
2026-03-05 13:39:39 +01:00
commit c4d164d8c3
20 changed files with 3598 additions and 0 deletions

BIN
Dijkstra/NeverNeverLand.doc Normal file

Binary file not shown.

BIN
Dijkstra/dijkstra.exe Normal file

Binary file not shown.

285
Dijkstra/graf.cpp Normal file
View File

@@ -0,0 +1,285 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* graf.cpp
* Innehåller de funktioner programmet
* använder sig av för att beräkna
* den kortaste vägen
*************************************************/
#include "header.h"
/*===============================================
* graphNode
* Construktor.
* Skapar en graphNode
-------------------------------------------------*/
graphNode::graphNode() {
startCity = -1;
endCity = -1;
Start = 0;
End = 0;
}
/*===============================================
* Operator ==
* Operatoröverlagring
-------------------------------------------------*/
int graphNode::operator==(graphNode node) {
if(Start != node.Start || End != node.End ||
startCity != node.startCity || endCity != node.endCity)
return false;
return true;
}
/*===============================================
* Operator =
* Operatoröverlagring
-------------------------------------------------*/
void graphNode::operator=(graphNode node) {
startCity = node.startCity;
endCity = node.endCity;
Start = node.Start;
End = node.End;
}
/*===============================================
* Operator >
* Operatoröverlagring
-------------------------------------------------*/
int graphNode::operator>(graphNode node) {
if(Start <= node.Start)
return false;
return true;
}
/*===============================================
* dijkstraNode
* Construktor.
* Skapar en Dijkstra node
-------------------------------------------------*/
dijkstraNode::dijkstraNode() {
deleted = false;
lastCity = 0;
Totaltime = MAXINT; //Tiden sätts till max
}
/*===============================================
* ~dijkstraNode
* Destruktor.
* Tar bort en nod
-------------------------------------------------*/
dijkstraNode::~dijkstraNode() {}
/*===============================================
* graph
* Construktor
* Skapar en graph
-------------------------------------------------*/
graph::graph() {
visitedCities = 0;
table = NULL;
lastPath = NULL;
prevSize = 0;
lastTime = 0;
}
/*===============================================
* ~graph
* Destruktor
* Anropar deleteGraph
-------------------------------------------------*/
graph::~graph() { deleteGraph(); }
/*===============================================
* deleteGraph
* Tömmer grafen på info
-------------------------------------------------*/
void graph::deleteGraph() {
if(table != NULL)
delete[] table;
if(lastPath != NULL)
delete[] lastPath;
table = NULL;
lastPath = NULL;
visitedCities = 0;
prevSize = 0;
lastTime = 0;
}
/*===============================================
* makeGraph
* Skapar en graf med size stycken städer.
* Tar först bort eventuell gammal graf.
* Returnerar true om allt gick bra
-------------------------------------------------*/
int graph::makeGraph(int size) {
deleteGraph();
table = new list<graphNode>*[size];
if(table == NULL)
return false;
for(int index = 0; index < size; index++)
table[index] = new list<graphNode>[size];
if(table == NULL)
return false;
visitedCities = size;
return true;
}
/*===============================================
* connect
* Skapar förbindelse mellan noderna i grafen
-------------------------------------------------*/
void graph::connect(int startvertex, int endvertex, graphNode node) {
if(startvertex < 0 || startvertex > visitedCities-1 ||
endvertex < 0 || endvertex > visitedCities-1)
return;
node.startCity = startvertex;
node.endCity = endvertex;
table[startvertex][endvertex].insert(node);
}
/*===============================================
* shortestPath
* Letar reda på den kortaste
* vägen mellan två noder
-------------------------------------------------*/
graphNode graph::shortestPath(int startvertex, int endvertex, int time) {
int index, time1, time2;
graphNode node1, node2;
if(startvertex < 0 || startvertex > visitedCities-1 ||
endvertex < 0 || endvertex > visitedCities-1)
return node1;
int connections = table[startvertex][endvertex].listLength();
if(connections == 0) return node1;
node1 = table[startvertex][endvertex].printElement(1);
time1 = getTime(node1, time);
for(index = 2; index <= connections; index++) {
node2 = table[startvertex][endvertex].printElement(index);
time2 = getTime(node2, time);
if(time1 > time2) {
node1 = node2;
time1 = time2;
}
}
return node1;
}
/*===============================================
* getTime
* Returnerar antalet timmar mellan tiden
* time och tiden som finns i noden
-------------------------------------------------*/
int graph::getTime(graphNode node, int time) {
int total;
if(node.Start >= time && node.End > time && node.Start < node.End)
total = node.End - time;
else if(node.Start > node.End)
total = ( (24 - time + node.Start) + (24 - node.Start + node.End) );
else
total = (24 - time + node.End);
return total;
}
/*===============================================
* dijkstra
* Beräknar den kortaste sträckan dvs. tiden
* mellan två städer i NeverNeverLand
-------------------------------------------------*/
void graph::dijkstra(int startvertex, int endvertex, int time) {
delPath();
if(startvertex == endvertex || startvertex < 0 ||
startvertex > visitedCities-1 || endvertex < 0 ||
endvertex > visitedCities-1)
return;
dijkstraNode *temparray = new dijkstraNode[visitedCities];
if(temparray == NULL) return;
int min, index, parent = 0, temptime;
graphNode tempnode;
temparray[startvertex].Totaltime = 0;
temparray[startvertex].deleted = true;
min = startvertex;
while(min != endvertex) {
for(index = 0; index < visitedCities; index++) {
if(!temparray[index].deleted) {
tempnode = shortestPath(min, index, time);
if(tempnode.startCity != -1) {
temptime = getTime(tempnode, time);
if((temptime + temparray[min].Totaltime)
< temparray[index].Totaltime) {
temparray[index].Totaltime =
temptime + temparray[min].Totaltime;
if(parent == 0)
temparray[index].lastCity = 0;
else
temparray[index].lastCity = min;
temparray[index].Node = tempnode;
}
}
}
}
min = getMinTime(temparray);
temparray[min].deleted = true;
time = temparray[min].Node.End;
parent++;
}
calcPath(temparray, min);
}
/*===============================================
* calcPath
* Skapar en array med information
* om den kortaste vägen.
-------------------------------------------------*/
void graph::calcPath(dijkstraNode *array, int start) {
graphNode *path = new graphNode[visitedCities];
if(path == NULL)
return;
int temp = 1, index = start;
while(array[index].lastCity > 0) {
temp++;
index = array[index].lastCity;
}
prevSize = temp;
lastTime = array[start].Totaltime;
for(index = temp-1; index >= 0; index--) {
path[index] = array[start].Node;
start = array[start].lastCity;
}
lastPath = path;
}
/*===============================================
* getMinIndex
* Hittar den minsta noden i en array och
* returnerar dess index i arrayen
-------------------------------------------------*/
int graph::getMinTime(dijkstraNode *temptable) {
int temp = 0, index;
while(temptable[temp].deleted)
temp++;
for(index = temp+1; index < visitedCities; index++) {
if(!temptable[index].deleted) {
if(temptable[temp].Totaltime > temptable[index].Totaltime)
temp = index;
}
}
return temp;
}
/*===============================================
* delPath
* Tar bort det som lastpath pekar på
-------------------------------------------------*/
void graph::delPath() {
if(lastPath != NULL)
delete[] lastPath;
lastPath = NULL;
prevSize = 0;
}

75
Dijkstra/graf.h Normal file
View File

@@ -0,0 +1,75 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* Graph.h
* Innehåller de definitioner och klasser
* som används för att beräkna kortaste
* vägen mellan två städer
*************************************************/
#ifndef _GRAPH_H_
#define _GRAPH_H_
#include "list.h"
/*===============================================
* graphNode
* Nod mellan två städer
-------------------------------------------------*/
class graphNode {
public:
graphNode(); //Construktor
~graphNode() {}; //Destruktor
int startCity; //Stad man åker ifrån
int endCity; //Stad man kommer till
int Start; //Starttid
int End; //Ankomsttid
void operator=(graphNode node); //Operator-överlagring
int operator>(graphNode node); //för noder
int operator==(graphNode node); //...
};
/*===============================================
* dijkstraNode
* Speciell nod för Dijkstra
-------------------------------------------------*/
class dijkstraNode {
public:
int deleted; //Märkning för noden
int lastCity; //Föregående besökt stad
int Totaltime; //TotaL restid
dijkstraNode(); //Construktor
~dijkstraNode(); //Destruktor
graphNode Node; //En nod
};
/*===============================================
* graph
* Skapar en graf och sköter uträkningen
-------------------------------------------------*/
class graph {
private:
int visitedCities; //Antalet traverserade städer
list<graphNode> **table; //Resväg
graphNode shortestPath(int startvertex, int endvertex, int time);
void delPath();
int getTime(graphNode node, int time);
int getMinTime(dijkstraNode *temptable);
void calcPath(dijkstraNode *array, int start);
public:
int lastTime; //Tid som ökas när vi reser
int prevSize; //Antalet städer i arrayen
graphNode *lastPath; //Traverserad väg
graph(); //Construktor
~graph(); //Destruktor
void deleteGraph();
void connect(int startvertex, int endvertex, graphNode node);
int makeGraph(int size);
void dijkstra(int startvertex, int endvertex, int time);
};
#endif

36
Dijkstra/header.h Normal file
View File

@@ -0,0 +1,36 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* Header.h
* Innehåller definitioner och includes
* som används i programmet.
*************************************************/
#ifndef ___HEADER___
#define ___HEADER___
#include <iostream.h>
#include <stdlib.h>
#include <values.h>
#include <fstream.h>
#include <string.h>
#include <conio.h>
#include "graf.h"
#include "list.h"
const int false=0; //boolsk variabel
const int true=!false; //boolsk variabel
const int citySize=25; //Max antal tecken i en stad
const int numOfCities=13; //Antalet städer
const int FORWARD=2; //För inläsning
const int MAXTIME = 6; //Max antal tkn
const int BASE=10; //Talbas
const int BUFFERSIZE=20; //Buffer för säker inmatning
#endif

240
Dijkstra/list.h Normal file
View File

@@ -0,0 +1,240 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* list.h
* Innehåller definitioner och funktioner
* för en templatelista.
*************************************************/
#ifndef _LISTA_H_
#define _LISTA_H_
#include "header.h"
/*===============================================
* list
* Denna klass skapar en templatelista.
* Varje nod innehåller ett godtyckligt data-
* fält och en pekare till nästa nod.
-------------------------------------------------*/
template <class T>
class list {
private:
struct nod { // En template nod
T data;
nod *next;
};
int size; // Storleken på listan.
nod *head; // Pekar på första elementet i listan.
public:
list();
~list();
int listLength(); //Storleken på listan
void insert(T data); //Sätter in en nod
void del(int place); //Tar bort en nod
void sort(void); //Sorterar listan
int seek(T data); //Söker i listan
int isFree(void); //Kollar om det finns element i listan
void delAll(void); //Tar bort allt i listan
int occupiedExist(T data); //Kollar om inmatat värde existerar
int occupied(int place); //Testar om det finns plats
void setNode(nod *dat, T data); //Mata in data i den nya noden
T printElement(int place); //Visar Innehållet på bestämd plats.
T *getPtr(int place); //Returnera platsen på place position
};
/*===============================================
* list
* Construktor, skapar en lista
-------------------------------------------------*/
template <class T>
list<T>::list() {
head = NULL;
size = 0;
}
/*===============================================
* ~list
* Destruktor. Anropar delAll
-------------------------------------------------*/
template <class T>
list<T>::~list() { delAll(); }
/*===============================================
* insert
* Sätter in en ny nod i listan
-------------------------------------------------*/
template <class T>
void list<T>::insert(T data) {
nod *newNode = new nod;
newNode->next = head;
head = newNode;
size++;
newNode->data = data;
}
/*===============================================
* del
* Tar bort ett element på en viss
* position i listan
-------------------------------------------------*/
template <class T>
void list<T>::del(int place) {
int i = 1;
nod *temp1;
temp1 = head;
nod *temp2;
temp2 = head->next;
if(temp2 == NULL || place == 1) { //Bara ett element i listan
head = temp1->next;
delete temp1;
size--;
}
else { //Flera element i listan
temp2 = head;
while(i < place) {
temp1 = temp2;
temp2 = temp1->next;
i++;
}
temp1->next = temp2->next;
delete temp2;
size--;
}
}
/*===============================================
* isFree
* Kollar om listan är tom. Returnerar
* true om listan är tom
-------------------------------------------------*/
template <class T>
int list<T>::isFree() {
if(size == 0) return true;
else return false;
}
/*===============================================
* occupied
* Kollar om plats finns på en angiven
* position.
-------------------------------------------------*/
template <class T>
int list<T>::occupied(int place) {
if( (place < 1) || (place > size) ) return false;
else return true;
}
/*===============================================
* listLength
* Returnerar antalet element i listan
-------------------------------------------------*/
template <class T>
int list<T>::listLength() { return size; }
/*===============================================
* sort
* Sorterar elementen i listan
-------------------------------------------------*/
template <class T>
void list<T>::sort() {
nod *temp;
T sop;
int changed;
do {
changed = 0;
for(temp = head; temp != NULL; temp = temp->next)
if(temp->data > temp->next->data) {
sop = temp->data;
temp->data = temp->next->data;
temp->next->data = sop;
changed = 1;
}
}while(changed);
}
/*===============================================
* delAll
* Tar bort alla element i listan.
* Sätter sedan storleken till 0
-------------------------------------------------*/
template <class T>
void list<T>::delAll() {
nod *temp1 = head;
nod *temp2;
head = NULL;
while(temp1 != NULL) {
temp2 = temp1;
temp1 = temp1->next;
delete temp2;
}
size = 0;
}
/*===============================================
*
*
-------------------------------------------------*/
template <class T>
int list<T>::occupiedExist(T data) { //Kollar om inmatat värde existerar
nod *temp;
for(temp = head; temp != NULL; temp = temp->next)
if(temp->data == data)
return true;
return false;
}
/*===============================================
*
*
-------------------------------------------------*/
template <class T>
int list<T>::seek(T data) { //Söker efter ett element i listan
nod *temp;
int position = 0;
for(temp = head; temp != NULL; temp = temp->next) {
position++;
if(temp->data == data)
return position; //Funnet! Returnera positionen
}
position = 0;
return position; //Inget hittades, returnera 0
}
/*===============================================
* printElement
* Hämtar element på en angiven plats
-------------------------------------------------*/
template <class T>
T list<T>::printElement(int place) {
nod *temp1 = head;
int i = 1;
while(i < place && i < size) {
temp1 = temp1->next;
i++;
}
return temp1->data;
}
/*===============================================
* getPtr
* Returnera adressen till ett element
* på en angiven plats
-------------------------------------------------*/
template <class T>
T *list<T>::getPtr(int place) {
nod *temp1 = head;
int i = 1;
while(i < place && i < size) {
temp1 = temp1->next;
i++;
}
return &(temp1->data);
}
#endif

191
Dijkstra/main.cpp Normal file
View File

@@ -0,0 +1,191 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* main.cpp
* Innehåller drivrutiner för
* Dijkstra labben.
* Skapat med Borland C++ 4.0
* Låt main.cpp och graph.cpp
* finnas i projektet.
* Kompilera för Easywin, Windows 3.x
* 16-bitar, target: Small
* Se till att filen network.txt finns
* i samma katalog som dijkstra.exe
*************************************************/
#include "header.h"
/*===============================================
* cities
* Alla städer i NeverNeverLand
-------------------------------------------------*/
const char cities[numOfCities][citySize] = {
{"Wonderland"},
{"Sanctuary"},
{"Battlefield"},
{"Octopus's Garden"},
{"Paradise City"},
{"Strawberry Fields"},
{"Chaos"},
{"El Dorado"},
{"Kozmic Place"},
{"Oz"},
{"Nowhereland"},
{"Shangrila"},
{"Southbound"}
};
graph myGraph; //Global klass för grafen
/*===============================================
* mataIn
* Ser till att bara tal matas in
-------------------------------------------------*/
int mataIn() {
char buffer[BUFFERSIZE];
int f;
do {
cin >> buffer;
if (strcmp(buffer,"0") == 0) return 0;
else {
f = atoi(buffer);
if (f!=0) return f;
else cout <<"NAN, try again: ";
}
}while (!f);
return 0;
}
/*===============================================
* getName
* Hämtar namn på stad, dvs det nummer staden
* motsvarar
-------------------------------------------------*/
int getName(char *text) {
int i = 0;
while(strcmp(text, cities[i]) !=0 && i < numOfCities)
i++;
if(i >= numOfCities) return -1;
else return i;
}
/*===============================================
* readGraph
* Läser in alla städer och tider från fil.
-------------------------------------------------*/
void readGraph()
{
graphNode node;
ifstream myFile;
char temp[citySize];
if(!myGraph.makeGraph(numOfCities)) { //Skapar en graf
cout<<"Could not make graph";getch();
return;
}
myFile.open("network.txt"); //Öppnar filen
do {
myFile.get(temp, citySize);
node.startCity = getName(temp); //Hämtar startstad
myFile.seekg(FORWARD, ios::cur);
myFile.get(temp, citySize);
node.endCity = getName(temp); //Hämtar slutstad
myFile.seekg(FORWARD, ios::cur);
myFile.get(temp, citySize);
node.Start = atoi(temp); //Hämtar starttid
myFile.seekg(FORWARD, ios::cur);
myFile.get(temp, citySize);
node.End = atoi(temp); //Hämtar sluttid
myFile.seekg(FORWARD, ios::cur);
myGraph.connect(node.startCity, node.endCity, node); //Sätter in noden
} while(myFile.peek() != EOF);
}
/*===============================================
* printPath
* Skriver ut kortaste vägen
-------------------------------------------------*/
void printPath() {
int index;
char text[citySize * 4], time[MAXTIME];
cout << "The shortest path is:"
<< "\n________________________________________________________";
for(index = 0; index < myGraph.prevSize; index++) {
text[0] = 0;
time[0] = 0;
cout << "\nFrom " << cities[myGraph.lastPath[index].startCity];
itoa(myGraph.lastPath[index].Start, time, BASE);
cout << " "<< time << ":00\t";
time[0] = 0;
cout << "to ";
cout << cities[myGraph.lastPath[index].endCity];
itoa(myGraph.lastPath[index].End, time, BASE);
cout << " " << time << ":00\t";
}
text[0] = 0; time[0] = 0;
itoa(myGraph.lastTime, time, BASE);
cout << "\n________________________________________________________";
cout << "\nThe total travelling time is "<<time<<" hours";
}
/*===============================================
* printTowns
* Skriver ut alla städer på skärmen
-------------------------------------------------*/
void printTowns()
{
clrscr();
cout << "\t\t\t\t\t\t\t\t<b-brox>"
<< "\n Welcome to the RailWay Company"
<< "\n in the NeverNeverLand..."
<< "\n ____________________________________________________"
<< "\n | 0. Wonderland 7. El Dorado |"
<< "\n | 1. Sanctuary 8. Kozmic Place |"
<< "\n | 2. Battlefield 9. Oz |"
<< "\n | 3. Octopus's Garden 10. Nowhereland |"
<< "\n | 4. Paradise City 11. Shangrila |"
<< "\n | 5. Strawberry Fields 12. Southbound |"
<< "\n | 6. Chaos |"
<< "\n |__________________________________________________|"
<< "\n";
}
/*===============================================
* main
* Huvudfunktionen för programmet.
* Läser in grafen och ber användaren
* mata in mellan vilka städer han skall resa
-------------------------------------------------*/
void main() {
int start, end, time;
char playAgain;
readGraph(); //Läs in filen
do{
printTowns(); //Skriv ut städerna
do {
cout <<"\nFrom wich town (0-"<<(numOfCities-1)<<"): ";
start=mataIn();
}while(start<0 || start>numOfCities-1);
do {
cout <<"To wich town (0-"<<(numOfCities-1)<<"): ";
end=mataIn();
}while(end<0 || end>numOfCities-1);
do {
cout <<"Time of departure (0-24): ";
time=mataIn();
}while(time<0 || time>24);
myGraph.dijkstra(start, end, time); //Beräkna kortaste väg
if(myGraph.prevSize > 0)
printPath(); //Skriv ut vägen
else
cout <<"\nStarttown and arrivaltown are the same! Are you stupid?";
cout <<"\n\nPlay Again (Y/N)? ";
cin >> playAgain;
}while(playAgain == 'y' || playAgain == 'Y');
}

BIN
Dijkstra/map.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

1068
Dijkstra/network.txt Normal file

File diff suppressed because it is too large Load Diff

17
Dijkstra/read_me Normal file
View File

@@ -0,0 +1,17 @@
Laboration 4 i
Datastrukturer och Algoritmer
Dijkstra's shortest path
------------------------------------------------
Stort OBS!
Denna lab är utvecklad under windows
med Borland C++ 5.0
Kompilering under Linux kommer ej
att fungera utan lite trix.
Tex finns inte funktioner som clrscr()
i Linux.
Exe-filen borde gå att köra på en windows-
dator. Se till att network.txt finns i samma
katalog som exe-filen.
Labben är provkörd och klar.
------------------------------------------------
Christian Ohlsson, di7chro@cse.kau.se, 1999