zoukankan      html  css  js  c++  java
  • 算法: 找子集合并按权值和排序 (货郎问题辅助算法)


    假设给出的 1-8 个数, 选4个

    1) 最小的权值的几个 ( 1, 2, 3, 4)

    2) 假设当前(a, b, c, d),  如果我们能确定权值和刚好大过它的组合, 不难找到所有组合按权值和排序


    数据结构

    需要两个结构 selects和 remains,  selects 是已经选择的子集合, remains 是要考虑的数

    他们是列表并需要排序, 先开始元素放置如下

    算法

    1) 用 remains 中最小的元素到 selects 中找到刚好它能大过的元素

    2) 如果找到, 交换这两个元素

    3) 如果不能找到, 从 remains 中删除此元素, 取下一个元素继续找 ( 就是到 1) )

    ------------ 能找到的情况

    selects

    1 2 3 4
    5 6 6 8

    remains

    selects

    1 2 3 5
    4 6 6 8

    remains


    ------------ 不能找到的情况

    selects

    2 3 4 5
    1 6 7 8

    remains

    selects

    2 3 4 5
    6 7 8

    remains

    ( 1 不用在考虑了, 放入 selects 必然会造成权值减少 )


    ================= 具体程序如下 ==================


    package com.pnp.findnextnumber;

    import java.util.ArrayList;
    import java.util.Collections;

    public class NextWeighSum {

        ArrayList<Integer> remains = new ArrayList<Integer>();
        ArrayList<Integer> selects = new ArrayList<Integer>();
        int TOTAL_COUNT = 10;
        int SELECT_COUNT = 4;

        void init() {
            for( int i=0; i<TOTAL_COUNT; i++)
                remains.add(i+1);
            Collections.sort(remains);
            for (int i=0; i<SELECT_COUNT; i++)
                selects.add( remains.remove(0));
        }
        
        /*
         * selects give the subset, need to return the next subset which the weight sum is just larger than current subset  
         */
        boolean selectNext() {
            while( remains.size() > 0) {
                int cur = remains.get(0);
                int pos = Collections.binarySearch(selects, cur);
                if (pos < 0) // binarySearch (-(insertion point) - 1)
                    pos = (-pos) -1;
                else {
                    System.err.print("Not allow equal elements");
                    System.exit(-1); // Not allow equal elements
                }
                
                if ( pos == 0 )  {// that means current element is less that any in selects, we won't need to consider this elem
                    remains.remove(0);
                    continue;
                }
                else {
                    int insert_pos = pos-1;
                    remains.set(0,selects.get(insert_pos));
                    selects.set(insert_pos, cur);
                    System.out.print(" an select ---");
                    print(selects);
                    return true;
                }
            }
            return false;
        }
        
        void selectAll() {
            while (selectNext())
                ;
        }


        static void print(ArrayList<Integer> list ) {
            int sum = 0;
            for (int i=0; i< list.size(); i++) {
                sum += list.get(i);
                System.out.print( " " + list.get(i));
            }
            System.out.println("   sum:"+sum  );
        }

        public static void main(String[] args) {
            NextWeighSum m = new NextWeighSum();
            m.init();
            m.selectAll();
        }

    }


    这个算法打算在 "货郎问题" 中使用, 货郎问题是选择权值和最小的边集合,试探是否其构成路径. 构成则问题解决,否则试探下一个.



  • 相关阅读:
    diary and html 文本颜色编辑,行距和其它编辑总汇
    bash coding to changeNames
    virtualbox ubuntu 网络连接 以及 连接 secureCRT
    linux 学习6 软件包安装
    linux 学习8 权限管理
    vim 使用2 转载 为了打开方便
    ubuntu
    linux 学习15 16 启动管理,备份和恢复
    linux 学习 14 日志管理
    linux 学习 13 系统管理
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2998458.html
Copyright © 2011-2022 走看看