/* * 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; }