如何自动生成并分配与矩阵元素对应的变量?
我正在处理一个二进制线性规划的问题。
我对计算机语言不太熟悉(只学了几个月的Java和C++),但这个问题比较复杂,我可能还是需要用到计算机。
第一步是为矩阵M中的每个元素声明变量m_ij(至少是8X8的矩阵)。然后我把矩阵中每个元素的对应值赋给这些变量。
接下来是生成其他变量集,x_ij1、x_ij2、x_ij3、x_ij4和x_ij5,当m_ij的值不为0时就生成。x_ijk变量的值只能是0或1,我不需要为这些变量手动赋值。
可能最简单的方法是为每个变量声明并赋值,比如:
int* m_11 = 5, int* m_12 = 2, int* m_13 = 0, ... int* m_1n = 1
int* m_21 = 3, int* m_12 = 1, int* m_13 = 2, ... int* m_2n = 3
然后挑选那些值不为0的变量,按照情况声明x_ij1到x_ij5。
但这可能工作量太大,特别是因为我还要考虑很多不同的矩阵。
有没有什么办法可以自动完成这个过程呢?
我对Java和C++了解一点,正在考虑在C++中使用lp_solve包(来解决二进制整数线性规划问题),但如果有其他语言或程序能更简单地做到这一点,我也愿意尝试。
我相信一定有办法可以做到(可能是用循环,我猜?),这其实是个很简单的任务,只是因为我对编程语言了解不多,所以不知道怎么做。
我的一个同学写了一个程序,可以生成满足我们需要的某些条件的随机矩阵,如果我能用那个矩阵作为输入,那就太理想了,但现在只要有任何方法都可以。
比如,如果有办法用Excel来做,把矩阵的元素放到Excel文件的单元格里,然后导入到C++中,自动生成变量并赋值,那就能大大简化这个任务!
3 个回答
我会C++和Matlab(不懂Python),在你的情况下,我建议你用Matlab,因为它在你刚开始编程的时候用起来简单得多(不过等你发现Matlab的局限性时,别忘了再回到C++)。
在Matlab中,你可以很轻松地定义矩阵:只需要输入矩阵的名字和你想设置的索引:
m(1,1) = 1
m(2,2) = 1
这样就能得到一个2x2的单位矩阵(在Matlab中,索引是从1开始的,默认值是0)。你也可以用同样的方法定义三维矩阵:
x(1,2,3) = 2
关于从Excel导入数据,如果你把Excel文件保存为CSV格式,就可以用dlmread
这个函数在Matlab中读取它。你也可以尝试直接在Matlab中实现你的算法。
最后,如果你想解决二进制整数规划问题,Matlab里已经有一个内置的函数bintprog
可以帮你解决这个问题。
希望这些对你有帮助!
在C++中,你可以使用一个std::vector
来存放多个向量,像这样:
std::vector<std::vector<int>> matrix;
你不需要为矩阵的每个值使用单独的变量,既然你已经有了矩阵,为什么还要这样做呢?
我不明白你为什么需要获取所有评估为true
或false
的值。其实你可以直接把条件为true
的坐标放进一个std::vector
里:
std::vector<std::pair<int, int> true_values;
for (int i = 0; i < matrix.size(); i++)
{
for (int j = 0; j < matrix[i].size(); j++)
{
if (some_condition_for_this_matrix_value(matrix[i][j], i, j) == true)
true_values.emplace_back(std::make_pair(i, j));
}
}
这样你就得到了一个包含所有条件为true
的矩阵坐标的向量。
如果你真的想同时保留true
和false
的值,你可以使用一个std::unordered_map
,里面的每一对数据用std::pair
来表示,矩阵坐标作为键,bool
值作为值:
// Create a type alias, as this type will be used multiple times
typedef std::map<std::pair<int, int>, bool> bool_map_type;
bool_map_type bool_map;
把矩阵中的所有值插入到这个映射中,矩阵的坐标作为键,值则根据你的条件是true
还是false
。
要获取bool_map
中的所有条目,你可以用std::remove_if
来删除所有false
的条目:
std::remove_if(bool_map.begin(), bool_map.end(),
[](const bool_map_type::value_type& value) {
return value.second == false;
};
现在你就得到了一个只包含true
值的映射。遍历这个映射就可以得到矩阵的坐标。
当然,我可能完全误解了你的问题,如果是这样,你当然可以忽略这个回答。:)
Matlab确实很适合这个任务。虽然@Dr_Sam提供的例子可以动态创建矩阵,但我建议你在给矩阵赋值之前先初始化它们。这样做可以确保你的代码在工作区中如果已经存在同名变量时,仍然能得到正确的变量,而且你的变量总是会有预期的大小。
假设你想定义一个8x8的方阵:
m = zeros(8)
一般来说,如果你想初始化一个大小为imax
、jmax
、kmax
的三维矩阵:
imax = 8;
jmax = 8;
kmax = 5;
x = zeros(imax,jmax,kmax);
现在给这些矩阵赋值或读取值是非常简单的,注意这里的m的长度和宽度与x
的第一个维度是一样的:
m(3,4) = 4; %Assign a value
myvalue = m(3,4) %read the value
m(:,1) = 1:8 *Assign the values 1 through 8 to the first column
x(2,4,5) = 12; %Assign a single value to the three dimensional matrix
x(:,:,2) = m+1; Assign the entire matrix plus one to one of the planes in x.