输出1到N之间所有相加最接近M的数字组合【可参考更改为背包算法】

原创 2016年08月29日 10:07:36
昨天查询背包算法,结果很多都是写的贪心算法,而且还有很多是错误的,遂自行写一个。


/**
 * Knapsack.java  V1.0   2016年8月28日 下午6:45:02
 *
 * Copyright pengzhistar@sina.com All rights reserved.
 *
 * Modification history(By    Time    Reason):
 * 
 * Description:
 */




package com.shopx.util;




import java.util.ArrayList;
import java.util.List;




//如果需要更改成背包算法,那么将ABS判断更改为不大于背包总量


public class MathUtil {




public static void main(final String... args) {
List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(5);

list.add(7);
list.add(5);
list.add(8);
list.add(3);
MathUtil k = new MathUtil();
List<Integer> result = new ArrayList<Integer>();
k.near(list,result, 0,18,true);
System.out.println(result);

List<Integer> result2 = new ArrayList<Integer>();
k.near(list,result2, 0,18);

System.out.println(result2);
}




public void near(List<Integer> list,List<Integer> result, int start, int capacity){
near(list, result, start, capacity, false);
}
public void near(List<Integer> list,List<Integer> result, int start, int capacity,boolean minShort) {

//不计算最短路径,那么得到相等之后立即跳出
if(!minShort){
int count = count(result);
if(count == capacity){
return ;
}
}

if(start == list.size()){
return ;
}

int num = 0;
ArrayList<Integer> _result_temp = new ArrayList<Integer>();

ArrayList<Integer> _result = new ArrayList<Integer>();
//计算所有的组合,去绝对值最小的那一个,这里代码可以更简洁,目前仅一个偏移计算,可以在多一个偏移变量进行递归,就不多写了
for (int i = 0; i < list.size(); i++) {
num += list.get(i);
_result_temp.add(list.get(i));
for (int j = start + 1; j < list.size() && j != i; j++) {
_result_temp.add(list.get(j));
if(Math.abs(num - capacity) < Math.abs(count(_result_temp) - capacity) ){
_result_temp.remove(list.get(j));
}else{
num = count(_result_temp);
}
}
num = 0;
if(Math.abs(count(_result_temp) - capacity) < Math.abs(count(_result)  - capacity) ){
_result = (ArrayList<Integer>) _result_temp.clone();
}else if(minShort && Math.abs(count(_result_temp) - capacity) == Math.abs(count(_result)  - capacity)){
//去最短计算路径
if(_result.size() > _result_temp.size()){
_result = (ArrayList<Integer>) _result_temp.clone();
}
}

_result_temp = new ArrayList<Integer>();
}

if(Math.abs(count(result) - capacity) > Math.abs(count(_result)  - capacity) ){
fresh(result,_result);
}else if(minShort && Math.abs(count(result) - capacity) == Math.abs(count(_result)  - capacity)){
//去最短计算路径
if(result.size() > _result.size()){
fresh(result,_result);
}
}
near(list, result, ++start, capacity,minShort);

}




private void fresh(List<Integer> result, ArrayList<Integer> _result) {
result.clear();
for (int i = 0; i < _result.size(); i++) {
result.add(_result.get(i).intValue());
}
}




private int count(List<Integer> result) {
int count = 0;
for (Integer integer : result) {
count += integer;
}
return count;
}




}

输入n,m,从1-n个数字里输出和为m的组合

利用动态规划法, #include #include using namespace std; vector result; void find(int n,int m) { if...

Java组合算法(m个n选1)

现有8个小球,对小球进行编号,依次为a、b、c、……、g、h。将编号后的8个小球分成三组,分组情况如下:第一组:[a, b, c];第二组:[d, e];第三组:[f, g, h]。从每组中选出一个小...
  • xht555
  • xht555
  • 2015年01月29日 21:38
  • 3049

面试题:从给定的N个正数中选取若干个数之和最接近M

这道题跟捞鱼问题一样,都是刚进实验室新生培训那会儿做过的题目,不过这个是一师姐当时找工作的面试题。 如题,并输出该子序列 测试用例:2,9,5,7,4,11,10 分别输出最接近33、40、47...

面试题:从给定的N个正数中选取若干个数之和最接近M

转载自 http://www.ahathinking.com/archives/110.html 文章作者:Yx.Ac 文章来源:勇幸|Thinking (http://www...
  • gatieme
  • gatieme
  • 2016年06月04日 22:23
  • 1479

搜狗笔试:N个正实数选出若干个之和最接近M

搜狗:有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M。 需要选出若干个x,使这几个x的和与 M 最接近。 请描述实现算法,并指出算法复杂度。 思路:对于每一个...

算法之数学自由组合问题(从M个不重复的数字中选取N个数字进行自由组合)

今天,遇到一个同事的问题,要求给定从给定的5个不重复的数字中,取出3个数字,输出所有的组合情况。其实就是数学中的组合问题。以前仅仅做的是关于求出组合的情况数,这个很简单,用递归就可以求解。这题要求列举...

将一个整数M分成N个数相加的和,要求每个数至少要大于等于1

Du熊正在负责一个大型的项目,目前有K台服务器,有N个任务需要用这K台服务器来完成,所以要把这些任务分成K个部分来完成,在同上台服务器上执行的任务必须是连续的任务,每个任务有各自需要的执行时间。 例...
  • a135450
  • a135450
  • 2013年04月01日 14:13
  • 1160

小于等于n的正整数相加等于m的一个算法

/* * 有集合N={1,2,3……,n},求a1+a2+……+an=m(ai属于N不等于0,i=1,2,……n)的所有组合,m,n都是自然数 */ public static void func1(...
  • fso918
  • fso918
  • 2013年11月25日 18:34
  • 1267
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:输出1到N之间所有相加最接近M的数字组合【可参考更改为背包算法】
举报原因:
原因补充:

(最多只允许输入30个字)