<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Population</title>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><b><span lang="en-ca">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
</b></font><span lang="en-ca"><font size="6" color="#FF0000"><b>Dijkstra 
----Shortest Path</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca">First</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is actually <span lang="en-ca">first edition </span>of my <span lang="en-ca">Dijkstra</span> class<span lang="en-ca"> which is a standard algorithm for finding shortest path</span>.</b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>It is a kind of interpretation from the algorithm of text. </b></span></pre>
</div>
<div align="left">
  <pre><font color="#0000FF"><span lang="en-ca"><b>This can be called 1.5 edition, as I corrected the bug in display method.</b></span></font></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>A simple connected graph with weighted edges which stands for distance between the two incident vertices. Starting</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>from one vertex and ends at one vertex, what is the shortest distance and what is the path?</b></span></pre>
</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  <pre><span lang="en-ca"><b>I use my matrix class to store the weight graph with 1000 standing for no direct connection of two vertices. A </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>boolean array to stand for the set S. And a structure Label to store &quot;label number, previous vertex, and step&quot;.</b></span></pre>
</div>
<div align="left">
  <pre><font color="#0000FF"><span lang="en-ca"><b>The problem of previous edition is that I didn't really understand the algorithm. The only way to backtrack the </b></span></font></pre>
</div>
<div align="left">
  <pre><font color="#0000FF"><span lang="en-ca"><b>path is by way of its previous vertex from the end point till start point. That is why we need a structure Label</b></span></font></pre>
</div>
<div align="left">
  <pre><font color="#0000FF"><span lang="en-ca"><b>to keep record both label number and its &quot;Father&quot;.</b></span></font></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><b>1. void Dijkstra::doFindPath()</b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>The method findNext is finding all elements not in setList and has the minimum label number.</b></span></pre>
</div>
<div align="left">
  <pre><b>2. void Dijkstra::display()</b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>In C++, it is a pity that we don't have stack like assembly. I have to make it myself when backtracking the path.</b></span></pre>
</div>
<div align="left">
  <pre><b>3.void Dijkstra::updateVertex()</b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.<a name="explanation"></a></font></b><font size="5" color="#FF0000"><b>A<span lang="en-ca"> little explanation</span></b></font></pre>
</div>
<div align="left" style="width: 779; height: 67">
  <div style="width: 900; height: 16">
    <font face="Arial" size="2"><span lang="en-ca">1. Do</span>wnload the input 
    file<span lang="en-ca"> </span>
    <a href="http://www.staroceans.com/NickGraph.txt" style="color: blue; text-decoration: underline; text-underline: single">
    http://www.staroceans.com/NickGraph.txt</a><span lang="en-ca">, </span>put 
    it in your &quot;c:\&quot;&nbsp; drive and <span lang="en-ca">&quot;</span>opmatrix<span lang="en-ca">&quot;</span> 
    has a limit of 20, do you check if it exceeds it?</font></div>
  <div>
    <font face="Arial" size="2"><span lang="en-ca">2. Please</span>
    <a href="picture/Dijkstra.JPG"><span lang="en-ca">check </span>the graph </a>
    for the problem, make sure we are talking about the same graph.<span lang="en-ca">
    </span>The &quot;nameStr&quot; is actually an array of char string in order to help 
    you reading. </font>
  </div>
</div>
<pre>　</pre>
<pre>#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;cmath&gt;

using namespace std;

const int MaxElements = 20;
const int MaxRow = 20;
const int MaxCol = 20;
const double LIMIT = 0.01;
const int Infinite = 1000;

char* nameString[11] = {&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;,&quot;e&quot;,&quot;f&quot;,&quot;g&quot;,&quot;h&quot;,&quot;i&quot;,&quot;j&quot;,&quot;k&quot;};

class Matrix
{
private:
	int rowNum;
	int colNum;
	double lst[MaxRow][MaxCol];
protected:
	void mul(int dest, double scalor);
	void mul(int source, int dest, double scalor);
public:
	Matrix();
	Matrix&amp; transform(int index1, int index2);
	int row() const {return rowNum;}
	int col() const {return colNum;}
	void setRow(const int newRow) { rowNum = newRow;}
	void setCol(const int newCol) { colNum = newCol;}
	void display(bool displayNumber= false);
	double&amp; items(int r, int c);
	void initialize();
	void readFromFile(const char* fileName);
	void assign(const Matrix&amp; other);
	Matrix&amp; operator = (Matrix other);
	Matrix&amp; transposition();	
};

struct Label
{
	int labelNum;
	int father;
	int step;
};

class Dijkstra
{
private:
	bool setList[MaxElements];
	int elementCount;
	int startIndex;
	int endIndex;
	Matrix weight;
	Label opMatrix[MaxElements];
	int current;
	int domino; //the u
	void initialize();
	void display();
	bool isEnd() { return setList[endIndex];}
	void doFindPath();
	int findMin();
	bool findNext();
	void updateVertex();
	int step;
	void addElement();
public:
	void findPath(int start, int end);
};

int main()
{
	Dijkstra D;
	D.findPath(0, 10);

	return 0;
}

//as we cannot know how many step from start to end, I have to make
//a stack to record the step backwards.
void Dijkstra::display()
{
	int stack[MaxElements] = {0};
	int counter =0;
	cout&lt;&lt;&quot;The shortest distance is:&quot;&lt;&lt;opMatrix[endIndex].labelNum&lt;&lt;endl;
	cout&lt;&lt;&quot;The path is:\n&quot;;
	step = endIndex;
	stack[counter] = step;
	while (step!=startIndex)
	{	
		step = opMatrix[step].father;
		counter++;
		stack[counter] = step;
	}
	
	for (int i=counter; i&gt;=0; i--)
	{
		cout&lt;&lt;&quot;step &quot;&lt;&lt;counter -i + 1&lt;&lt;&quot; is &quot;&lt;&lt;nameString[stack[i]]&lt;&lt;endl;
		cout&lt;&lt;&quot;and its label is&quot;&lt;&lt;opMatrix[stack[i]].labelNum&lt;&lt;endl;
	
	}
}

void Dijkstra::addElement()
{
	setList[domino] = true; //add domino to set
	opMatrix[domino].step = step;
	step++;
}

bool Dijkstra::findNext()
{
	for (int i=current+1;i&lt;elementCount; i++)
	{
		if (!setList[i] &amp;&amp; weight.items(domino, i)!=Infinite)
		{
			current=i;
			return true;
		}
	}
	current = -1;
	return false;
}

void Dijkstra::updateVertex()
{
	if (opMatrix[domino].labelNum + weight.items(domino, current)&lt;opMatrix[current].labelNum)
	{
		opMatrix[current].labelNum = opMatrix[domino].labelNum + weight.items(domino, current);
		opMatrix[current].father = domino;
	}
}


int Dijkstra::findMin()
{
	int result = Infinite;
	int index = 0;
	for (int i=0; i&lt; elementCount; i++)
	{
		if (!setList[i]) //not in set
		{
			if (opMatrix[i].labelNum&lt;result)
			{
				result = opMatrix[i].labelNum;
				index = i;
			}
		}
	}
	return index;
}



void Dijkstra::doFindPath()
{
	while (!isEnd())
	{
		domino = findMin();
		addElement();
		while (findNext())
		{
			updateVertex();
		}
	}
}


void Dijkstra::findPath(int start, int end)
{
	startIndex = start;
	endIndex = end;
	initialize();
	weight.display();
	doFindPath();
	display();
}

void Dijkstra::initialize()
{
	weight.readFromFile(&quot;c:\\nickGraph.txt&quot;);
	elementCount = weight.row();
	for (int i=0; i&lt;elementCount; i++)
	{
		setList[i] = false;
		opMatrix[i].labelNum = Infinite;
		opMatrix[i].father = startIndex;
		opMatrix[i].step = step;
	}
	opMatrix[startIndex].labelNum = 0;
	current = -1;
	step=0;
}


Matrix&amp; Matrix::transposition()
{
	double hold;
	int temp;
	for (int r =0; r&lt; rowNum; r++)
	{
		for (int c=0; c&lt; r; c++)
		{
			hold = lst[r][c];
			lst[r][c] = lst[c][r];
			lst[c][r] = hold;
		}
	}
	temp = rowNum;
	rowNum = colNum;
	colNum = temp;
	return (*this);
}

Matrix&amp; Matrix::operator =(Matrix other)
{
	setRow(other.row());
	setCol(other.col());
	for (int r=0; r&lt; other.row(); r++)
	{
		for (int c=0; c&lt; other.col(); c++)
		{
			lst[r][c] = other.items(r, c);
		}
	}
	
	return (*this);
}

void Matrix::assign(const Matrix&amp; other)
{
	*this = other;
}


void Matrix::mul(int dest, double scalor)
{
	for (int c=0; c&lt; colNum; c++)
	{
		lst[dest][c] *= scalor;
	}
}

void Matrix::mul(int source, int dest, double scalor)
{
	for (int c=0; c&lt; colNum; c++)
	{
		lst[dest][c] += lst[source][c]*scalor;
	}
}


double&amp; Matrix::items(int r, int c)
{
	return lst[r][c];
}

void Matrix::readFromFile(const char* fileName)
{
	int r=0, c=0;
	char ch;
	ifstream f;
	f.open(fileName);
	while (!f.eof())
	{
		ch = f.peek();
		
		if (ch!=10)  //return char
		{
			
			f&gt;&gt;lst[r][c];
			c++;
			if (c&gt;colNum)
				colNum = c;
		}
		else
		{
			f.ignore();
			r++;
			setCol(c);
			c =0;
		}
	}
	if (r!=0)
	{
		setRow(r+1);
	}
}


void Matrix::initialize()
{
	for (int r=0; r &lt; rowNum; r++)
	{
		for (int c=0; c&lt; colNum; c++)
		{
			lst[r][c] = r*2+c;
		}
	}	
}

Matrix&amp; Matrix::transform(int index1, int index2)
{
	double hold;
	if (index1&lt;rowNum&amp;&amp;index2&lt;rowNum)
	{
		for (int i=0; i&lt;colNum; i++)
		{
			hold = lst[index1][i];
			lst[index1][i] = lst[index2][i];
			lst[index2][i] = hold;
		}
		for (i=0; i&lt; rowNum; i++)
		{
			hold = lst[i][index1];
			lst[i][index1] = lst[i][index2];
			lst[i][index2] = hold;
		}
	}
	return *this;
}




void Matrix::display(bool displayNumber)
{
//	int temp;
	long preFlag;
	int number=0;
	preFlag = cout.flags();
//	temp = cout.precision(4);
//	cout.setf(ios::fixed);
	
	cout&lt;&lt;&quot;\nrow\\col&quot;;
	for (int c=0; c&lt; colNum; c++)
	{
		cout&lt;&lt;&quot;  &quot;&lt;&lt;c;
	}
	cout&lt;&lt;&quot;\n\n&quot;;
	for (int r = 0; r&lt; rowNum; r++)
	{
		cout&lt;&lt;r&lt;&lt;&quot;\t &quot;;
		number = 0;
		for (c = 0; c&lt; colNum; c++)
		{
			cout&lt;&lt;(fabs(lst[r][c])&lt;LIMIT?0:lst[r][c])&lt;&lt;&quot;  &quot;;
			if (fabs(lst[r][c])&gt;=LIMIT)
			{
				number++;
			}
		}
		if (displayNumber)
		{
			cout&lt;&lt;number;
		}

		cout&lt;&lt;endl;
	}
//	cout.precision(temp);
	cout.flags(preFlag);
}

Matrix::Matrix()
{
	rowNum = 5;
	colNum = 5;
	initialize();
}
</pre>
<pre>			
</pre>
<pre><font color="#FF0000"><a name="Result"></a>The following is result of program: </font></pre>
<pre><span lang="en-ca"><font color="#FF0000">This is the first result that starts from &quot;a&quot; or index 0, and ends at &quot;z&quot; or index 5, it has exactly same result from text.</font></span></pre>
<pre>row\col 0 1 2 3 4 5

0 1000 4 2 1000 1000 1000 
1 4 1000 1 5 1000 1000 
2 2 1 1000 8 10 1000 
3 1000 5 8 1000 2 6 
4 1000 1000 10 2 1000 3 
5 1000 1000 1000 6 3 1000 
The shortest distance is:13
The path is:
step 1 is a
its last step isa and its label is0
step 2 is c
its last step isa and its label is2
step 3 is b
its last step isc and its label is3
step 4 is d
its last step isb and its label is8
step 5 is e
its last step isd and its label is10
step 6 is z
its last step ise and its label is13
</pre>

<pre>　</pre>

<pre><font color="#FF0000"><span lang="en-ca">This is quite annoying! I try to test it by choosing starting vertex as &quot;e&quot; or index 4 which is adjacent to ending vertex &quot;z&quot; or </span></font></pre>

<pre><font color="#FF0000"><span lang="en-ca">index of 5. It is giving correct distance, but with incorrect path! Originally I thought it should be e--&gt;z, but it actually goes</span></font></pre>

<pre><span lang="en-ca"><font color="#FF0000">to d first as e-&gt;d is shorter. After that it gives correct label of &quot;z&quot;, but the path is just incorrect!</font></span></pre>

<pre>row\col 0 1 2 3 4 5

0 1000 4 2 1000 1000 1000 
1 4 1000 1 5 1000 1000 
2 2 1 1000 8 10 1000 
3 1000 5 8 1000 2 6 
4 1000 1000 10 2 1000 3 
5 1000 1000 1000 6 3 1000 
The shortest distance is:3
The path is:
step 1 is e
its last step ise and its label is0
step 2 is d
its last step ise and its label is2
step 3 is z
its last step ise and its label is3


</pre>

<pre><b><font color="#FF0000" size="4"><span lang="en-ca"><a name="correct"></a>The above is first edition result, now it is correct after I made correction in </span></font></b></pre>

<pre><b><font color="#FF0000" size="4"><span lang="en-ca">display method.</span></font></b></pre>

<pre><font color="#FF0000"><span lang="en-ca">This is starting from vertex &quot;a&quot;</span></font></pre>

<pre>　</pre>

<pre>row\col 0 1 2 3 4 5

0 1000 4 2 1000 1000 1000
1 4 1000 1 5 1000 1000
2 2 1 1000 8 10 1000
3 1000 5 8 1000 2 6
4 1000 1000 10 2 1000 3
5 1000 1000 1000 6 3 1000
The shortest distance is:13
The path is:
step 1 is a
and its label is0
step 2 is c
and its label is2
step 3 is b
and its label is3
step 4 is d
and its label is8
step 5 is e
and its label is10
step 6 is z
and its label is13
Press any key to continue</pre>

<pre>　</pre>

<pre><font color="#FF0000"><span lang="en-ca">this is starting from vertex &quot;e&quot; which is adjacent to target &quot;z&quot;.</span></font></pre>

<pre>row\col 0 1 2 3 4 5

0 1000 4 2 1000 1000 1000
1 4 1000 1 5 1000 1000
2 2 1 1000 8 10 1000
3 1000 5 8 1000 2 6
4 1000 1000 10 2 1000 3
5 1000 1000 1000 6 3 1000
The shortest distance is:3
The path is:
step 1 is e
and its label is0
step 2 is z
and its label is3
Press any key to continue
</pre>

<pre></pre>

<pre><font color="#FF0000">And here is the input weight matrix:( The 1000 stands for not directly connected, and the matrix is adjacent vertex Matrix.)</font></pre>

<pre>1000 4 2 1000 1000 1000
4 1000 1 5 1000 1000
2 1 1000 8 10 1000
1000 5 8 1000 2 6
1000 1000 10 2 1000 3
1000 1000 1000 6 3 1000</pre>

<pre>　</pre>

<pre>　</pre>

<pre><b><font color="#FF0000"><span lang="en-ca"><a name="assignment">This is the running result of my assignment:</a></span></font></b></pre>

<pre><span lang="en-ca">
row\col 0 1 2 3 4 5 6 7 8 9 10

0 1000 1 3 10 10 5 1000 1000 1000 1000 1000
1 1 1000 1000 1000 7 1000 1000 1000 1000 1000 1000
2 3 1000 1000 1000 1000 1 1000 1000 1000 1000 1000
3 10 1000 1000 1000 2 5 8 4 6 1000 1000
4 10 7 1000 2 1000 1000 1000 8 1000 1000 1000
5 5 1000 1 5 1000 1000 1000 1000 10 1000 1000
6 1000 1000 1000 8 1000 1000 1000 3 3 4 4
7 1000 1000 1000 4 8 1000 3 1000 1000 4 1000
8 1000 1000 1000 6 1000 10 3 1000 1000 1000 7
9 1000 1000 1000 1000 1000 1000 4 4 1000 1000 4
10 1000 1000 1000 1000 1000 1000 4 1000 7 4 1000
The shortest distance is:20
The path is:
step 1 is a
and its label is0
step 2 is c
and its label is3
step 3 is f
and its label is4
step 4 is d
and its label is9
step 5 is h
and its label is13
step 6 is g
and its label is16
step 7 is k
and its label is20
Press any key to continue

</span></pre>

<pre>　</pre>

<pre></pre>

<p>　</p>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>