如何在C++中生成元素总和相等的两个不同随机数矩阵
如何让两个随机生成的C++矩阵元素总和相等?
问题背景
已用C++生成两个随机整数矩阵:a(尺寸IT×P)和b(尺寸OT×P),代码如下:
// 生成矩阵a a = new int* [IT](); for (int j = 0; j < IT; j++) { a[j] = new int[P]; for (int p = 0; p < P; p++) { a[j][p] = RL.randint(0,100); // 自定义随机数生成函数 } } // 生成矩阵b b = new int* [OT](); for (int m = 0; m < OT; m++) { b[m] = new int[P]; for (int p = 0; p < P; p++) { b[m][p] = RL.randint(0, 100); } }
需要满足两个矩阵的元素总和相等,无需固定总和的具体数值,仅要求两者总和一致。
解决方案
方法1:生成时直接匹配总和
先生成其中一个矩阵并计算总和,再生成另一个矩阵时,用最后一个元素调整总和,确保与第一个矩阵相等:
// 先生成矩阵a并计算总和sum_a long long sum_a = 0; a = new int* [IT](); for (int j = 0; j < IT; j++) { a[j] = new int[P]; for (int p = 0; p < P; p++) { a[j][p] = RL.randint(0,100); sum_a += a[j][p]; } } // 生成矩阵b,调整最后一个元素匹配sum_a long long sum_b = 0; b = new int* [OT](); bool valid_b = false; while (!valid_b) { sum_b = 0; // 先释放之前可能分配的b内存 for (int k = 0; k < OT; k++) { if (b[k] != nullptr) delete[] b[k]; } delete[] b; b = new int* [OT](); for (int m = 0; m < OT; m++) { b[m] = new int[P]; for (int p = 0; p < P; p++) { // 非最后一个元素正常生成随机数 if (!(m == OT-1 && p == P-1)) { b[m][p] = RL.randint(0,100); sum_b += b[m][p]; } else { // 计算最后一个元素的值,确保在0-100范围内 int last_val = sum_a - sum_b; if (last_val >= 0 && last_val <= 100) { b[m][p] = last_val; sum_b += last_val; valid_b = true; } else { // 最后一个元素超出范围,重置循环重新生成 m = OT; // 跳出内层循环 p = P; } } } } }
方法2:生成后调整差值
先生成两个完整的随机矩阵,再通过微调元素让总和相等:
// 先生成a、b矩阵并计算各自总和 long long sum_a = 0, sum_b = 0; // ... 生成a矩阵的代码,同时累加sum_a // ... 生成b矩阵的代码,同时累加sum_b long long diff = sum_a - sum_b; while (diff != 0) { if (diff > 0) { // a总和更大,减少a的元素,增加b的元素 // 找a中可减1的元素 for (int j = 0; j < IT && diff > 0; j++) { for (int p = 0; p < P && diff > 0; p++) { if (a[j][p] > 0) { a[j][p]--; sum_a--; diff--; } } } // 找b中可加1的元素 for (int m = 0; m < OT && diff > 0; m++) { for (int p = 0; p < P && diff > 0; p++) { if (b[m][p] < 100) { b[m][p]++; sum_b++; diff--; } } } } else { // b总和更大,减少b的元素,增加a的元素 for (int m = 0; m < OT && diff < 0; m++) { for (int p = 0; p < P && diff < 0; p++) { if (b[m][p] > 0) { b[m][p]--; sum_b--; diff++; } } } for (int j = 0; j < IT && diff < 0; j++) { for (int p = 0; p < P && diff < 0; p++) { if (a[j][p] < 100) { a[j][p]++; sum_a++; diff++; } } } } }
方法3:Excel生成后导入C++
Excel生成矩阵:
- 生成矩阵a:用
RANDBETWEEN(0,100)填充所有单元格,计算总和(比如用SUM()函数) - 生成矩阵b:用
RANDBETWEEN(0,100)填充除最后一个单元格外的所有区域,最后一个单元格设置为=sum_a - sum(b的其他单元格),如果结果超出0-100,重新生成b的其他元素 - 将两个矩阵分别保存为CSV文件(比如
matrix_a.csv和matrix_b.csv)
- 生成矩阵a:用
C++读取CSV文件:
#include <fstream> #include <sstream> #include <string> #include <stdexcept> // 读取CSV到指定矩阵 void loadMatrixFromCSV(const std::string& filepath, int** matrix, int rows, int cols) { std::ifstream file(filepath); if (!file.is_open()) { throw std::runtime_error("无法打开文件: " + filepath); } std::string line; int current_row = 0; while (std::getline(file, line) && current_row < rows) { std::stringstream line_stream(line); std::string cell; int current_col = 0; while (std::getline(line_stream, cell, ',') && current_col < cols) { matrix[current_row][current_col] = std::stoi(cell); current_col++; } if (current_col != cols) { throw std::runtime_error("CSV列数与矩阵列数不匹配"); } current_row++; } if (current_row != rows) { throw std::runtime_error("CSV行数与矩阵行数不匹配"); } } // 使用示例 // loadMatrixFromCSV("matrix_a.csv", a, IT, P); // loadMatrixFromCSV("matrix_b.csv", b, OT, P);
内容的提问来源于stack exchange,提问作者georgia siomou
相关产品推荐
相关产品推荐

