<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>
DFS---</b></font><span lang="en-ca"><font size="6" color="#FF0000"><b>Standardized</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca">Second</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is <span lang="en-ca">second edition of my DFS base class. Like BFS, I standardized all virtual method and correct a couple of</span></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>small mistakes.</b></span></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><b><span lang="en-ca">How many </span>ways are there to travel in xyzw space from the origin (0,0,0,0) to the point (3,2,3,1) by taking steps </b></pre>
</div>
<div align="left">
  <pre><b>one unit in the positive x, positive y, positive z, or positive w direction?</b></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>No matter how complicated a problem may become, we can divide and conquer it by counting! And </span>depth<span lang="en-ca">-first-search</span></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>is one of the simplest way to do it.</b></span></pre>
</div>
<div align="left">
  <pre><b>As DFS uses very small memory, I don't need to reduce the size of problem, but the program wrote into my disk with </b></pre>
</div>
<div align="left">
  <pre><b>a file size of more than 800M until my disk runs out of free space. Then I change the program not to output all </b></pre>
</div>
<div align="left">
  <pre><b>outcomes, instead only the total number of solutions. However, it runs more than one hour and still there is no</b></pre>
</div>
<div align="left">
  <pre><b>result!</b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>There are several significant changes in new Standardized DFS class:</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>1. root is no longer a static object, so it is possible to be inherited by overriding virtual function &quot;createSon&quot;.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>2. MaxLevel is only a bottom line for DFS to touch down. A bug is corrected so that it will give correct result</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>even searching does not touch down. </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>3. evaluate method must be implemented by user to justify if result is what he is looking for.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>4. validateOption remains same to be necessary to be implemented by user.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>5. beginCount need one more parameter---nameStr, a char**. So that display method is standardize and no more </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>attention is needed. User simply passes the user-defined string array (char**) by second parameter in beginCount.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>6. A member counter solutionCounter is used to count the number of solutions.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>7. setOption still needs to be called before beginCount() to set up the options array.</b></span></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. virtual bool validateOption(int sonData);</b></pre>
</div>
<div align="left">
  <pre><b>This is the place where user-defined methods are implemented to determine if the data (integer)	will be verified </b></pre>
</div>
<div align="left">
  <pre><b>to be able to be added.</b></pre>
</div>
<div align="left">
  <pre><b>2. bool DFS::doGenerate()</b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>I made a small change in this function: a touchDown check is preceded to all option-check, because this is major</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>difference with BFS. User prefers to set up the maximum searching levels.</b></span></pre>
</div>
<div align="left">
  <pre><b>3. void DFS::onLeave()</b></pre>
</div>
<div align="left">
  <pre><b>This method allows you to do specific job when you visit all leaf points which is a solution such as delete node. </b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>4. DFS* DFS::generate()</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>This function is also modified as &quot;evaluate&quot; check becomes the only judgement for return. This makes it possible </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>that even searching does not reach maximum searching level, correct results still can be got as long as it justifies</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>&quot;evaluate&quot; check.</b></span></pre>
</div>
<pre>#include &lt;iostream&gt;

using namespace std;

const int MaxSonCount=8;

const int MaxLevel =20;

const int MaxOptions = 10;

enum AxisName
{X, Y, Z, W};

int limit[4] = {3,2,3,1};

char* directionString[4] = {&quot;X&quot;, &quot;Y&quot;, &quot;Z&quot;, &quot;W&quot;};

int axis[4] = {X,Y,Z,W};

class DFS
{
private:
	static DFS* root;
	static bool findAll;
	static int level;
	static int optionArray[MaxOptions];
	static int optionCount;
	static int maxLevel;
	static char** nameString;
	static int solutionCount;
	int depth;
	DFS* parent;
	DFS* sonArray[MaxSonCount];
	int data;
	int sonCount;
	int sonIndex;
	void addSon(int sonData);
	DFS* findBrother();
	DFS* findUncle();
	bool hasBrother();
	DFS* nextBrother();
	void initialize(DFS* now);
	bool touchDown();
	DFS* generate();
	void setMaxLevel(int max) { maxLevel = max;}
	bool doGenerate();
	void setNameStr(char** str){nameString = str;}
protected:
	virtual DFS* createSon();
	virtual bool validateOption(int sonData);	
	virtual void onLeave();
	virtual bool evaluate();
	virtual void collectResult();
public:	
	int getSolutionCount(){ return solutionCount;}
	void setOptions(int* array, int size);
	void beginCount(int max, char** str, bool findall=false);
};

bool DFS::findAll = false;
int DFS::maxLevel = 0;
int DFS::optionCount = 0;
int DFS::optionArray[MaxOptions] = {0};
int DFS::level = 0;
DFS* DFS::root = NULL;
char** DFS::nameString=NULL;
int DFS::solutionCount = 0;


int main()
{
	DFS R;
	R.setOptions(axis, 4);
	R.beginCount(16, directionString, true);
	cout&lt;&lt;&quot;Total number is &quot;&lt;&lt;R.getSolutionCount()&lt;&lt;endl;

	return 0;
}

//I don't know what extra work to be for the time being
bool DFS::evaluate()
{
	return depth == 9;
}

bool DFS::touchDown()
{
	return depth==maxLevel;
}

void DFS::onLeave()
{
	DFS* ptr =this;
	delete ptr;
}

//a stack
void DFS::collectResult()
{
	int temp[MaxLevel] = {0};
	DFS* ptr = this;

	while (ptr-&gt;parent!=NULL)
	{
		temp[ptr-&gt;depth-1] = ptr-&gt;data;
		ptr = ptr-&gt;parent;
	}
	cout&lt;&lt;&quot;The route is:&quot;;
	for (int i=0; i&lt;depth; i++)
	{
		cout&lt;&lt;nameString[temp[i]]&lt;&lt;&quot;, &quot;;
	}
	cout&lt;&lt;&quot;It is number:&quot;&lt;&lt;solutionCount++;
	cout&lt;&lt;endl;
}

void DFS::setOptions(int *array, int size)
{
	optionCount = size;
	for (int i=0; i&lt;size; i++)
	{
		optionArray[i] = *(array+i);
	}
}

bool DFS::doGenerate()
{
	bool result = false;
	if (touchDown())
	{
		return false;
	}

	for (int i=0; i&lt; optionCount; i++)
	{
		if (validateOption(optionArray[i]))
		{
			addSon(optionArray[i]);
			result = true;		
		}
	}
	if (result)
	{
		level++;
	}
	return result;
}

bool DFS::validateOption(int sonData)
{
	int counter[4]={0}; //count all axis advances
	DFS* ptr= this;

	while (ptr-&gt;parent!=NULL)
	{
		counter[ptr-&gt;data]++; //data is axis
		ptr = ptr-&gt;parent;
	}

	return counter[sonData]&lt;limit[sonData];
}

DFS* DFS::findBrother()
{
	DFS* ptr= this;
	DFS* dummy=ptr;
	while (!(ptr-&gt;hasBrother()))
	{
		dummy = ptr; //keep the clue
		ptr = ptr-&gt;parent;
		level--;   //???
		if (dummy!=root)
		{
			dummy-&gt;onLeave(); //clear
		}
		if (ptr==NULL)
		{
			return NULL;
		}
	}
	dummy = ptr;  //keep clue
	ptr = ptr-&gt;nextBrother();
	dummy-&gt;onLeave(); //clear 
	return ptr;
}

void DFS::beginCount(int max, char** str, bool findall)
{
	setNameStr(str);
	DFS* ptr = this;
	setMaxLevel(max);
	findAll = findall; //setup if want all result
	initialize(this);
	while (true)
	{		
		ptr = ptr-&gt;generate();
		if (ptr==NULL)
		{
			if (solutionCount==0)
			{
				cout&lt;&lt;&quot;No solution!&quot;;
			}
			break;
		}
		if (ptr-&gt;evaluate())
		{
			ptr-&gt;collectResult();
			if (!findAll)
			{
				break;
			}
		}
		ptr = ptr-&gt;findBrother();
		if (ptr==NULL)
		{
		
			if (solutionCount==0)
			{
				cout&lt;&lt;&quot;No solution!&quot;;
			}
			break;
		}
	}
}
		
DFS* DFS::generate()
{
	DFS* ptr= this;

	while (!ptr-&gt;evaluate())
	{
		if (!ptr-&gt;doGenerate())
		{
			ptr=ptr-&gt;findBrother();
			if (ptr==NULL)
			{
				break;
			}
		}
		else
		{
			ptr = ptr-&gt;sonArray[0];
		}
	}

	return ptr;
}

DFS* DFS::createSon()
{
	DFS* ptr = new DFS;
	return ptr;
}

void DFS::addSon(int sonData)
{	
	if (sonCount+1&lt;MaxSonCount)
	{
		DFS* ptr = createSon();
		ptr-&gt;data = sonData;
		ptr-&gt;sonCount = 0;
		ptr-&gt;parent = this;
		ptr-&gt;depth = depth+1;
		sonArray[sonCount] = ptr;		
		ptr-&gt;sonIndex = sonCount;
		sonCount++;
	}
	else
	{
		cout&lt;&lt;&quot;Exceed max of sons!&quot;;
	}
}

void DFS::initialize(DFS* now)
{
	root = now;
	root-&gt;depth = 0;
	root-&gt;sonCount = 0;
	root-&gt;sonIndex = -1;
	root-&gt;parent = NULL;
	root-&gt;data = 0;
	level = 0;
}

bool DFS::hasBrother()
{
	if (parent!=NULL)
	{
		if (parent-&gt;sonCount &gt; sonIndex+1)//has little brother
		{
			return true;
		}
	}
	return false;
}

DFS* DFS::nextBrother()
{
	if (parent!=NULL)
	{
		if (parent-&gt;sonCount &gt; sonIndex+1)//has little brother
		{
			return parent-&gt;sonArray[sonIndex+1]; //next little brother
		}
	}
	return NULL;
}
</pre>
<pre></pre>
<pre></pre>
<pre><b><font color="#FF0000"><a name="result"></a>The result is 504<span lang="en-ca">0</span></font></b>
</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>