zoukankan      html  css  js  c++  java
  • 匹配算法

    有若干个选手,每个选手有打某一个或几个位置的能力,每只队伍有N个不同位置。怎样组合这些选手可以组合出最多的队伍,队伍最多是几支?

    以下是我假设N=8时,使用贪心算法求最优解的过程。此算法思路较为简单,基本可以求出最优解,但还有不少可以优化的地方。望大家不吝赐教其他算法或优化算法。

    public class Match
    {

    protected Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
    protected MatchComparator comp = new MatchComparator();
    /**
    * @param args
    */
    public void main(List<Integer> nengli,List<Integer[]> talents)
    {
    // List<Integer> nengli = new ArrayList<Integer>();
    // nengli.add(1);
    // nengli.add(2);
    // nengli.add(4);
    // nengli.add(8);
    //
    // int[] a1 =
    // { 1, 2, 4, 8 };
    // int[] a2 =
    // { 1, 2 };
    // int[] a3 =
    // { 2 };
    // int[] a4 =
    // { 4, 8 };
    // int[] a5 =
    // { 1, 2 };
    // int[] a6 =
    // { 2 };
    // int[] a7 =
    // { 4, 8 };
    // int[] a8 =
    // { 4, 8 };

    // List<int[]> talents = new ArrayList<int[]>();
    // talents.add(a1);
    // talents.add(a2);
    // talents.add(a3);
    // talents.add(a4);
    // talents.add(a5);
    // talents.add(a6);
    // talents.add(a7);
    // talents.add(a8);

    //构建人才分类
    Map<Integer, Integer> pmap = new HashMap<Integer, Integer>();
    for (Integer[] arr : talents)
    {
    int sum = 0;
    for (int i : arr)
    {
    sum += i;
    }
    if (pmap.get(sum) == null)
    {
    pmap.put(sum, 0);
    }
    pmap.put(sum, pmap.get(sum) + 1);
    }

    //构建稀缺能力Map
    // Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
    for (Integer i : nengli)
    {
    map.put(i, 0);
    }
    for (Integer[] arr : talents)
    {
    for (int i : arr)
    {
    map.put(i, map.get(i) + 1);
    }
    }
    //获取最稀缺资源排名
    Collections.sort(nengli, comp);

    //已填充缓存
    Set<Integer> set = new HashSet<Integer>();
    // List<Integer[]> resultLst = new ArrayList<Integer[]>();
    // Integer[] tempresult = new Integer[nengli.size()];
    //循环填充
    int count = 0;
    find:for (Integer[] is : talents)
    {
    //从最稀缺资源开始填充
    for (Integer nl : nengli)
    {
    //已填充跳过
    if(set.contains(nl))
    {
    continue;
    }
    //查找有最稀缺能力的最不稀缺能力的人才
    // System.out.println("寻找有"+nl+"能力的人才");
    if (pmap.get(nl) != null && pmap.get(nl) > 0)
    {
    //人才分类去掉1个人才
    pmap.put(nl, pmap.get(nl)-1);
    //能力计数减掉该人才的能力
    map.put(nl, map.get(nl)-1);
    set.add(nl);
    // tempresult[set.size()-1] = nl;
    //填充下一个
    break;
    }
    // System.out.println(nl);
    int result = getRareNl2(nl,nl, nengli,-1, pmap);
    if (result != 0)
    {
    //人才分类去掉1个人才
    pmap.put(result, pmap.get(result)-1);
    //能力计数减掉该人才的能力
    Integer[] nls = divideNengli(result);
    for (int n : nls)
    {
    map.put(n, map.get(n)-1);
    }
    set.add(nl);
    // tempresult[set.size()-1] = result;
    //填充下一个
    break;
    }
    else
    {
    //填充失败,结束
    break find;
    }
    }
    //重新排序
    Collections.sort(nengli, comp);
    // 填充一轮,计数加1
    if(set.size()==nengli.size())
    {
    set.clear();
    count++;
    // resultLst.add(tempresult);
    // tempresult = new Integer[nengli.size()];
    }
    }

    System.out.println("最终结果:"+count);
    // for (Integer[] tem : resultLst)
    // {
    // System.out.println("最终结果排列:"+Arrays.toString(tem));
    // }
    // System.out.println("最终剩余项:"+Arrays.toString(tempresult));

    }



    /**
    * 分解出所有能力
    * @param result
    * @return
    */
    private static Integer[] divideNengli(int result)
    {
    List<Integer> lst = new ArrayList<Integer>();
    int pow = 0;
    while(result!=0)
    {
    int surplus = result%2;
    if(surplus==1)
    {
    int nl = (int)Math.pow(2, pow);
    lst.add(nl);
    }
    result = result/2;
    pow++;
    }
    return lst.toArray(new Integer[lst.size()]);
    }


    private static int getRareNl2(Integer source,Integer nengli, List<Integer> nengli2,int x, Map<Integer, Integer> pmap)
    {
    //获取有最稀缺能力的人才
    for (int i = nengli2.size() - 1; i > x; i--)
    {
    int left = nengli2.get(i);
    if(source==left)
    {
    continue;
    }
    if (pmap.get(nengli + left) != null && pmap.get(nengli + left) > 0)
    {
    return nengli + left;
    }
    // System.out.println(nengli + left);
    int result = getRareNl2(source,nengli + left, nengli2,i, pmap);
    if (result != 0)
    {
    return result;
    }
    }
    return 0;
    }

    public class MatchComparator implements Comparator<Integer>
    {
    // Map<Integer, Integer> map = null;
    //
    // public MatchComparator(final Map<Integer, Integer> map)
    // {
    // this.map = map;
    // }

    @Override
    public int compare(Integer o1, Integer o2)
    {
    return map.get(o1) - map.get(o2);
    }

    }
    }

  • 相关阅读:
    Sprinig.net 双向绑定 Bidirectional data binding and data model management 和 UpdatePanel
    Memcached是什么
    Spring.net 网络示例 codeproject
    jquery.modalbox.show 插件
    UVA 639 Don't Get Rooked
    UVA 539 The Settlers of Catan
    UVA 301 Transportation
    UVA 331 Mapping the Swaps
    UVA 216 Getting in Line
    UVA 10344 23 out of 5
  • 原文地址:https://www.cnblogs.com/uip001/p/9946650.html
Copyright © 2011-2022 走看看