给定一组n个数,n个偶数,我如何得到两个n / 2个数的子集,每个子集中数字的总和尽可能接近?
实施例: 设定= {1.6,4.0,0.7,2.9,5.0,3.1,5.0,1.0,0.6,5.0},总和28.9
子集可以是: {5.0,5.0,2.9,1.0,0.6},总和14.5和 {5.0,4.0,3.1,1.6,0.7},总和14.4
我需要一个算法,伪代码很好。
谢谢!
答案 0 :(得分:0)
我看待它的方式是:有两个列表,空白。 a = [],b = [] 对于x中的每个元素(数字列表),将其附加到最需要它的那个元素,也就是说,其总和小于另一个元素。
x=[1.6, 4.0, 0.7, 2.9, 5.0, 3.1, 5.0, 1.0, 0.6, 5.0]
x.sort()
x.reverse()
print(x)
#[5.0, 5.0, 5.0, 4.0, 3.1, 2.9, 1.6, 1.0, 0.7, 0.6]
b=[];c=[]
for i in a:
if sum(b) <= sum(c):
b.append(i)
else:
c.append(i)
print(sum(b))
print(sum(c))
#Hope this helps!
编辑:
如果我们希望这些集合具有相同的大小,那么这可能会成为一个问题。使用组合学将需要很长时间,但我认为没有其他选择。然后,我的知识有限。所以这里是:
给定一组22,找到一组11,总和为22的一半,或尽可能接近。如果它尽可能接近,请查看开关元件是否会产生更好的结果。但这与组合学一样低效。
这是一个非常难的问题。甚至维基百科都承认了这一点。 :-D: - (
抱歉,我无法提供更多帮助。
答案 1 :(得分:0)
我找到了解决方案。 这是java实现:
package javaapplication;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class JavaApplication {
private static DecimalFormat df = new DecimalFormat(".#");
private static double totalCuadroIzquierdo = 0;
private static double totalCuadroDerecho = 0;
private static ArrayList<Double> cuadroIzquierdo;
private static ArrayList<Double> cuadroDerecho;
public static void main(String[] args) {
Double[] vectorTodos = {
//100.0,99.0,98.0,89.0,76.0,60.0,56.0,45.0,43.0,32.0, 5.0, 5.0, 5.0, 4.1, 3.9, 3.1, 2.4, 1.7, 1.0, 0.6
//100.0,99.0,98.0,89.0,76.0,60.0,56.0,45.0,43.0,32.0, 5.0, 4.1, 3.9, 3.1, 2.4, 1.7, 1.0, 0.6
//99.0,89.0,76.0,60.0,56.0,45.0,43.0,32.0, 5.0, 4.1, 3.9, 3.1, 2.4, 1.7, 1.0, 0.6
99.0,60.0,56.0,45.0,43.0,32.0
//5.0, 4.1//, 3.9, 3.1//, 2.4, 1.7, 1.0, 0.6
};
List<Double> todos = new ArrayList(Arrays.asList(vectorTodos));
int n = todos.size();
Collections.sort(todos);
Collections.reverse(todos);
todos.forEach((numero) -> {System.out.println(numero);}); System.out.println("####");
cuadroIzquierdo = new ArrayList();
cuadroDerecho = new ArrayList();
for (double numero : todos) {
if (totalCuadroIzquierdo > totalCuadroDerecho) {
if (cuadroDerecho.size() < n/2) {
cuadroDerecho.add(numero);
totalCuadroDerecho += numero;
} else {
cuadroIzquierdo.add(numero);
totalCuadroIzquierdo += numero;
}
} else {
if (cuadroIzquierdo.size() < n/2) {
cuadroIzquierdo.add(numero);
totalCuadroIzquierdo += numero;
} else {
cuadroDerecho.add(numero);
totalCuadroDerecho += numero;
}
}
add();
}
cuadroIzquierdo.forEach((numero) -> {System.out.println(numero);}); System.out.println("----"); System.out.println(df.format(totalCuadroIzquierdo));
System.out.println("****");
cuadroDerecho.forEach((numero) -> {System.out.println(numero);}); System.out.println("----"); System.out.println(df.format(totalCuadroDerecho));
}
private static void add() {
double totalCuadroMayor;
double totalCuadroMenor;
ArrayList<Double> cuadroMayor;
ArrayList<Double> cuadroMenor;
boolean cuadroIzquierdoMayor;
if (totalCuadroIzquierdo > totalCuadroDerecho) {
cuadroMayor = new ArrayList(cuadroIzquierdo);
cuadroMenor = new ArrayList(cuadroDerecho);
totalCuadroMayor = totalCuadroIzquierdo;
totalCuadroMenor = totalCuadroDerecho;
cuadroIzquierdoMayor = true;
} else {
cuadroMayor = new ArrayList(cuadroDerecho);
cuadroMenor = new ArrayList(cuadroIzquierdo);
totalCuadroMayor = totalCuadroDerecho;
totalCuadroMenor = totalCuadroIzquierdo;
cuadroIzquierdoMayor = false;
}
ArrayList mCuadroMayor = new ArrayList(cuadroMayor);
ArrayList mCuadroMenor = new ArrayList(cuadroMenor);
for (double maxCuadroMayor : cuadroMayor) {
for (double maxCuadroMenor : cuadroMenor) {
if (totalCuadroMayor - totalCuadroMenor > maxCuadroMayor - maxCuadroMenor && maxCuadroMayor > maxCuadroMenor) {
mCuadroMayor.remove(maxCuadroMayor);
mCuadroMayor.add(maxCuadroMenor);
mCuadroMenor.remove(maxCuadroMenor);
mCuadroMenor.add(maxCuadroMayor);
totalCuadroMayor = totalCuadroMayor - maxCuadroMayor + maxCuadroMenor;
totalCuadroMenor = totalCuadroMenor - maxCuadroMenor + maxCuadroMayor;
maxCuadroMayor = maxCuadroMenor;
}
}
cuadroMenor.clear();
cuadroMenor.addAll(mCuadroMenor);
}
cuadroMayor.clear();
cuadroMayor.addAll(mCuadroMayor);
cuadroIzquierdo.clear();
cuadroDerecho.clear();
if (cuadroIzquierdoMayor) {
cuadroIzquierdo.addAll(cuadroMayor);
cuadroDerecho.addAll(cuadroMenor);
totalCuadroIzquierdo = totalCuadroMayor;
totalCuadroDerecho = totalCuadroMenor;
} else {
cuadroDerecho.addAll(cuadroMayor);
cuadroIzquierdo.addAll(cuadroMenor);
totalCuadroDerecho = totalCuadroMayor;
totalCuadroIzquierdo = totalCuadroMenor;
}
Collections.sort(cuadroIzquierdo);
Collections.reverse(cuadroIzquierdo);
Collections.sort(cuadroDerecho);
Collections.reverse(cuadroDerecho);
}
}