M個の数をNグループ(M>N)に分け、Nグループ間の数の和がほぼ等しいことを保証する。

4880 ワード

M個の数をNグループ(M>N)に分け、Nグループ間の数の和がほぼ等しいことを保証する。
時間がかかりました。簡単な出題ですが。実は、最大1時間で書き上げることができます。うかつなので、3時間もかけて調べ上げました。
 
package com.xiva;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.junit.Test;

/**
 * @Description   needSortNum  ,  groupsNum 
 * @author XGT
 *
 */
public class Subgroup {

	List numList = new ArrayList();
	
	List cloneList = new ArrayList();
	
	//   
	Long averageNum = 0l;
	
	//       
	static int needSortNum = 100000;
	
	//  
	static int groupsNum = 213;
	
	//      
	static int range = 10000000;
	
	//       
	int currGroup = 0;
	
	Map> resultMap = new HashMap>();
	
	
	/**
	 *     range   needSortNum   
	 */
	private void genarateNum(){
		for (int i=0; i tempList = new ArrayList();
		while(cloneList.size() > 0){
			groupTempNum = groupTempNum + cloneList.get(currIndex);
			if(groupTempNum < averageNum){
				tempList.add(cloneList.get(currIndex));
				cloneList.remove(currIndex);
				currIndex = currIndex -1;
			}else{
				long groupNum = groupTempNum - cloneList.get(currIndex);
				
				while(groupNum < averageNum){
					long difference2 = averageNum -  groupNum;
					int index2 = getSuitedIndex(difference2, cloneList);
					if (index2 == 0)
						break;
					Integer suitedObj2 = cloneList.get(index2);
					
					tempList.add(cloneList.get(index2));
					cloneList.remove(index2);
					currIndex = currIndex -1;
					
					groupNum = groupNum + suitedObj2;
				}
				
				storeList2Map(tempList);
				groupTempNum = 0;
			}
			
			if(currGroup == groupsNum-1){
				doTheRestNum();
				break;
			}
		}
	}
	
	
	/**
	 * @Description          index
	 * @param difference
	 * @param cloneList
	 * @return
	 */
	private int getSuitedIndex(long difference, List cloneList){
		int size = cloneList.size();
		int reIndex = 0;
		
		for (int i=0; i 0){
				continue;
			}else{
				reIndex = i;
				break;
			}
		}
		if (reIndex==0){
			System.out.println("      ~");
			reIndex = 0;
		}
		else{
			if (Math.abs(difference - cloneList.get(reIndex-1)) < Math.abs(difference - cloneList.get(reIndex)) )
			{
				reIndex = reIndex -1;
			}
		}
		return reIndex;
	}
	
	/**
	 * @Description          Map
	 * @param tempList
	 */
	private void storeList2Map(List tempList){
		List gourpList = new ArrayList();
		gourpList.addAll(tempList);
		currGroup = currGroup + 1;
		resultMap.put(Integer.valueOf(currGroup), gourpList);
		tempList.clear();
	}
	
    /**
     *         
     */
	private void doTheRestNum(){
		int size = cloneList.size();
		if ( size > 0){
			List tempList = new ArrayList();
			for (int i=0; i>> entrySet = resultMap.entrySet();
        Iterator>> iterator = entrySet.iterator();
        int total = 0;
        System.out.println("   :" + averageNum);
        while  (iterator.hasNext()) {  
            Map.Entry> map = iterator.next();
            List list = map.getValue();
            long totalNum = 0l;
            for(Integer obj:list){
            	totalNum = totalNum + obj;
//            	System.out.print(obj+";");
            }
            System.out.println();
            System.out.println(" "+map.getKey()+" ,"+"   :" + list.size()+",   :"+totalNum+"   :"+(totalNum-averageNum));
            total = total + list.size();
        }  
        System.out.println(total);
	}
	
	@Test public void testSorted(){
		
		genarateNum();
		sortNum();
		setAverageNum();
		start2Divide();
		printAllResult();
	}

}
 主なコアアプローチは,秩序化,値の取り方,およびget SuitedIndex()という方法にある。
これは基本的な解決方法です。このプログラムに基づいて、もう一つの優れたアルゴリズムを書いてもいいです。最終的な結果は理想に向かっています。
 
調停アルゴリズムの思想は、グループと平均値の差に基づいて他のグループの要素を探して交換することである。