예제 #1
0
/*
 * Procedure will be following:
 *	1) in random sequential order, each node is moved to its neighbor module that results in the largest gain of the map eq.
 *	   If no move results in a gain of the map equation, the node stays in its original module.
 *	2) repeated 1) procedure, each time in a new random sequential order, until no move generates a gain of the map EQ.
 *
 *	The 1) procedure is implemented in Network::move() function.
 */
void stochastic_greedy_partition(Network &network, int numTh, double threshold, double vThresh, int maxIter, bool prior, bool fineTune, bool fast) {

	double oldCodeLength = network.CodeLength();
	int iter = 0;
	bool stop = false;

	struct timeval outer_T1, outer_T2;
	struct timeval inner_T1, inner_T2;
	struct timeval seq_T1, seq_T2;
	struct timeval convert_T1, convert_T2;

	double tSequential = 0.0;

	gettimeofday(&outer_T1, NULL);

	int nActiveUnits = (fineTune) ? network.NNode() : network.superNodes.size();
	cout << nActiveUnits << ", ";


	// set initial active nodes list ...
	vector<char>(nActiveUnits).swap(network.isActives);
	vector<int>(nActiveUnits).swap(network.activeNodes);
	for (int i = 0; i < nActiveUnits; i++) {
		network.activeNodes[i] = i;
		network.isActives[i] = 0;	// initially set inactive nodes.
	}


	int numMoved = 0;

	while (!stop && iter < maxIter) {
		gettimeofday(&inner_T1, NULL);

		oldCodeLength = network.CodeLength();

		if (fineTune) {
			if (numTh == 1) {
				if (prior)
					numMoved = network.prioritize_move(vThresh);
				else
					numMoved = network.move();
			}
			else { 
				if (prior)
					numMoved = network.prioritize_parallelMove(numTh, tSequential, vThresh);
				else
					numMoved = network.parallelMove(numTh, tSequential);
			}
		} 
		else {
			if (numTh == 1) {
				if (prior)
					numMoved = network.prioritize_moveSPnodes(vThresh);
				else 
					numMoved = network.moveSuperNodes();		// If at least one node is moved, return true. Otherwise, return false.
			}
			else {
				if (prior) 
					numMoved = network.prioritize_parallelMoveSPnodes(numTh, tSequential, vThresh);
				else
					numMoved = network.parallelMoveSuperNodes(numTh, tSequential);
			}
		}
		iter++;

		if (oldCodeLength - network.CodeLength() >= 0 && (oldCodeLength - network.CodeLength())/log(2.0) < threshold)
			stop = true;	//moved = false;

		gettimeofday(&inner_T2, NULL);

		// Print code length per iteration for DEBUG purpose.
		cout << "Iteration " << iter << ": code length =\t" << network.CodeLength()/log(2.0) << "\t, ";
		cout << "elapsed time:\t" << elapsedTimeInSec(inner_T1, inner_T2) << "\t(sec), ";
		cout << "accumulated time:\t" << elapsedTimeInSec(outer_T1, inner_T2) << "\t(sec)\t";
		cout << "sumExitPr = " << network.SumAllExitPr() << "\t";
		cout << "numMoved:\t" << numMoved << endl;
	}

	gettimeofday(&seq_T1, NULL);

	int outerLoop = 1;

	network.updateMembersInModule();
	
	gettimeofday(&seq_T2, NULL);
	tSequential += elapsedTimeInSec(seq_T1, seq_T2);

	if (fast)
		return;

	double tConvert = 0.0;

	do {
		oldCodeLength = network.CodeLength();

		stop = false;

		gettimeofday(&convert_T1, NULL);
		network.convertModulesToSuperNodes(numTh);
		gettimeofday(&convert_T2, NULL);

		tConvert += elapsedTimeInSec(convert_T1, convert_T2);

		nActiveUnits = network.superNodes.size();
		cout << nActiveUnits << ", ";


		// set initial active nodes list ...
		vector<char>(nActiveUnits).swap(network.isActives);
		vector<int>(nActiveUnits).swap(network.activeNodes);
		for (int i = 0; i < nActiveUnits; i++) {
			network.activeNodes[i] = i;	// initially all active units are active.
			network.isActives[i] = 0;	// initially set inactive nodes.
		}


		int spIter = 0;
		while (!stop && spIter < maxIter) {
			gettimeofday(&inner_T1, NULL);

			double innerOldCodeLength = network.CodeLength();

			if (numTh == 1) {
				if (prior)
					numMoved = network.prioritize_moveSPnodes(vThresh);
				else 
					numMoved = network.moveSuperNodes();
			}
			else { 
				if (prior)
					numMoved = network.prioritize_parallelMoveSPnodes(numTh, tSequential, vThresh);
				else
					numMoved = network.parallelMoveSuperNodes(numTh, tSequential);
			}

			spIter++;

			if (innerOldCodeLength - network.CodeLength() >= 0.0 && (innerOldCodeLength - network.CodeLength())/log(2.0) < threshold)
				stop = true;	//moved = false;

			gettimeofday(&inner_T2, NULL);

			// Print code length per spIter for DEBUG purpose.
			cout << "SuperIteration " << outerLoop << "-" << spIter << ": code length =\t" << network.CodeLength()/log(2.0) << "\t, ";
			cout << "elapsed time:\t" << elapsedTimeInSec(inner_T1, inner_T2) << "\t(sec), ";
			cout << "accumulated time:\t" << elapsedTimeInSec(outer_T1, inner_T2) << "\t(sec)\t";
			cout << "sumExitPr = " << network.SumAllExitPr() << "\t";
			cout << "numMoved:\t" << numMoved << endl;
		}

		gettimeofday(&seq_T1, NULL);

		network.updateMembersInModule();

		outerLoop++;
		
		gettimeofday(&seq_T2, NULL);
		tSequential += elapsedTimeInSec(seq_T1, seq_T2);

	} while ((oldCodeLength - network.CodeLength())/log(2.0) > threshold);
	
	gettimeofday(&outer_T2, NULL);
	
	cout << "Sequential running time for partition: " << tSequential << " (sec)" << endl;
	cout << "Time for converting Module to SuperNode: " << tConvert << " (sec)" << endl;
	cout << "Overall time for partition: " << elapsedTimeInSec(outer_T1, outer_T2) << "\t(sec)" << endl;
}