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);
    }

    }
    }

  • 相关阅读:
    SpringBoot使用SpringSession和redis解决session共享问题(nginx反向代理)
    centos7中安装和配置nginx和keepalived
    定位
    css
    css美化
    html5
    列表,表格,媒体元素
    表单
    一期测试错题修改
    字符串
  • 原文地址:https://www.cnblogs.com/uip001/p/9946650.html
Copyright © 2011-2022 走看看