这是一个例子: 假设我有一个只包含0和1的二维数组:
0,1,0,0
0,0,0,1
1,0,1,0
我需要找到可以加到一个向量的最小数量的列。例如,
column0 + column1 + column3 = 0,0,1 + 1,0,0 + 0,1,0 = 1,1,1
因此,最小列数为3。
答案 0 :(得分:3)
这基本上是Set cover problem,这是NP难的。它可以作为整数线性规划问题进行公式化和求解(最佳)。
您还可以将问题转换为具有非常好的解算器的同一类的另一个问题,例如:布尔SAT。
最后,但并非最不重要的是,您可以使用贪婪和/或本地搜索算法来解决它,例如:模拟退火。
答案 1 :(得分:0)
无耻地复制来自https://stackoverflow.com/a/34588366/1203882
的组合代码import java.util.ArrayList;
import java.util.List;
public class Combin {
public static void main(String... banana) {
int[][] input = new int[][] { { 0, 1, 0, 0 }, { 0, 0, 0, 1 }, { 1, 0, 1, 0 } };
List<int[]> columns = new ArrayList<int[]>();
int min = Integer.MAX_VALUE;
//Set columns list
for (int column = 0; column < input[0].length; column++) {
int[] e = new int[input.length];
int index = 0;
for (int row = 0; row < input.length; row++) {
e[index++] = input[row][column];
}
columns.add(e);
}
//Sizes 0 1 2 3 and 4
for (int i = 0; i <= columns.size(); i++)
{
List<List<int []>> theList = getCombinations(i, columns);
for (List <int[]> a : theList)
{
if (check(a))
{
if (a.size() < min)
min = a.size();
//For the test returns 3, 3, and 4 as possibilities.
System.out.println("Found a possibility: " + a.size());
}
}
}
System.out.println("Min value: " + min);
}
public static <T> List<List<T>> getCombinations(int k, List<T> list) {
List<List<T>> combinations = new ArrayList<List<T>>();
if (k == 0) {
combinations.add(new ArrayList<T>());
return combinations;
}
for (int i = 0; i < list.size(); i++) {
T element = list.get(i);
List<T> rest = getSublist(list, i+1);
for (List<T> previous : getCombinations(k-1, rest)) {
previous.add(element);
combinations.add(previous);
}
}
return combinations;
}
public static <T> List<T> getSublist(List<T> list, int i) {
List<T> sublist = new ArrayList<T>();
for (int j = i; j < list.size(); j++) {
sublist.add(list.get(j));
}
return sublist;
}
//Create a vector by "or"ing every value.
public static boolean check(List<int []> result)
{
if (result.size() == 0)
return false;
int [] a = new int [result.get(0).length];
for(int [] j : result)
for (int index = 0; index < a.length; index++)
a[index] |= j[index];
return equalsVec(a);
}
//If all values aren't 1, return false. (ones vector)
public static boolean equalsVec(int [] a)
{
for (int i = 0; i < a.length; i++)
if (a[i] != 1)
return false;
return true;
}
}
输出:
Found a possibility: 3
Found a possibility: 3
Found a possibility: 4
Min value: 3