+ INTERP_KERNEL::AutoPtr<bool> proc_valid = new bool[grp_size];
+ fill((bool *)proc_valid, proc_valid+grp_size, true);
+
+ // Now the algo:
+ while (find((bool *)proc_valid, proc_valid+grp_size, true) != proc_valid+grp_size)
+ {
+ // Most loaded proc:
+ int max_sz = -1, max_id = -1;
+ for(itVector = full_set.begin(), procID=0; itVector != full_set.end(); itVector++, procID++)
+ {
+ int sz = (*itVector).size();
+ if (proc_valid[procID] && sz > max_sz)
+ {
+ max_sz = sz;
+ max_id = procID;
+ }
+ }
+
+ // Nothing more to do:
+ if (max_sz == -1)
+ break;
+ // For this proc, job with less loaded second proc:
+ int min_sz = infinity;
+ map<ProcCouple, int> & max_map = full_set[max_id];
+ ProcCouple hit_cpl = make_pair(-1,-1);
+ if(revertIter)
+ {
+ // Use a reverse iterator here increases our chances to hit a couple of the form (i, myProcId)
+ // meaning that the final matrix computed won't have to be sent: save some comm.
+ map<ProcCouple, int> ::const_reverse_iterator ritMap;
+ for(ritMap=max_map.rbegin(); ritMap != max_map.rend(); ritMap++)
+ if ((*ritMap).second < min_sz)
+ hit_cpl = (*ritMap).first;
+ }
+ else
+ {
+ for(itMap=max_map.begin(); itMap != max_map.end(); itMap++)
+ if ((*itMap).second < min_sz)
+ hit_cpl = (*itMap).first;
+ }
+ if (hit_cpl.first == -1)
+ {
+ // Plouf. Current proc 'max_id' can not be reduced. Invalid it:
+ proc_valid[max_id] = false;
+ continue;
+ }
+ // Remove item from proc 'max_id'
+ full_set[max_id].erase(hit_cpl);
+ // And mark it as not removable on the other side:
+ if (hit_cpl.first == max_id)
+ full_set[hit_cpl.second][hit_cpl] = infinity;
+ else // hit_cpl.second == max_id
+ full_set[hit_cpl.first][hit_cpl] = infinity;
+
+ // Now update all counts of valid maps:
+ procID = 0;
+ for(itVector = full_set.begin(); itVector != full_set.end(); itVector++, procID++)
+ if(proc_valid[procID] && procID != max_id)
+ for(itMap = (*itVector).begin(); itMap != (*itVector).end(); itMap++)
+ {
+ const ProcCouple & cpl = (*itMap).first;
+ // Unremovable item:
+ if ((*itMap).second == infinity)
+ continue;
+ if (cpl.first == max_id || cpl.second == max_id)
+ (*itMap).second--;
+ }
+ }
+ // Final formatting - extract remaining keys in each map:
+ int myProcId=_group.myRank();
+ _all_todo_lists.resize(grp_size);
+ procID = 0;
+ for(itVector = full_set.begin(); itVector != full_set.end(); itVector++, procID++)
+ for(itMap = (*itVector).begin(); itMap != (*itVector).end(); itMap++)
+ _all_todo_lists[procID].push_back((*itMap).first);
+ _to_do_list=_all_todo_lists[myProcId];
+
+#ifdef DEC_DEBUG
+ std::stringstream scout;
+ scout << "(" << myProcId << ") my TODO list is: ";
+ for (std::vector< ProcCouple >::const_iterator itdbg=_to_do_list.begin(); itdbg!=_to_do_list.end(); itdbg++)
+ scout << "(" << (*itdbg).first << "," << (*itdbg).second << ")";
+ std::cout << scout.str() << "\n";
+#endif