如何自动生成并分配与矩阵元素对应的变量?

-2 投票
3 回答
1248 浏览
提问于 2025-04-17 16:01

我正在处理一个二进制线性规划的问题。

我对计算机语言不太熟悉(只学了几个月的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 个回答

0

我会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可以帮你解决这个问题。

希望这些对你有帮助!

0

在C++中,你可以使用一个std::vector来存放多个向量,像这样:

std::vector<std::vector<int>> matrix;

你不需要为矩阵的每个值使用单独的变量,既然你已经有了矩阵,为什么还要这样做呢?

我不明白你为什么需要获取所有评估为truefalse的值。其实你可以直接把条件为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的矩阵坐标的向量。


如果你真的想同时保留truefalse的值,你可以使用一个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值的映射。遍历这个映射就可以得到矩阵的坐标。


当然,我可能完全误解了你的问题,如果是这样,你当然可以忽略这个回答。:)

0

Matlab确实很适合这个任务。虽然@Dr_Sam提供的例子可以动态创建矩阵,但我建议你在给矩阵赋值之前先初始化它们。这样做可以确保你的代码在工作区中如果已经存在同名变量时,仍然能得到正确的变量,而且你的变量总是会有预期的大小。

假设你想定义一个8x8的方阵:

m = zeros(8)

一般来说,如果你想初始化一个大小为imaxjmaxkmax的三维矩阵:

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.

撰写回答