运动促前第二次发育 轻松胸“涌”出位

本文介绍了几种通过锻炼胸大肌来改善乳房形态的方法,包括凳上肘屈伸、小球俯卧撑等练习,旨在帮助女性提升胸部线条,防止乳房下垂。
运动可以降低乳癌的发病几率!运动可以阻止乳线一路向下!运动可以促使乳房第二次发育。前方等待我们的是无情的地球引力,后面追赶着超级营养催化的“波涛汹涌”,美丽的口号很动人,美丽的行动更要快!
    
    
运动促前第二次发育 轻松胸“涌”出位

    
    

    练习一:凳上肘屈伸——针对肱三头肌,带动胸大肌。

    练习二:小球俯卧撑——针对胸大肌、肱三头肌、三角肌前束。

    练习三:球上展胸——针对胸大肌和肱三头肌。

    运动美胸Q&A

    Q:运动真的能增大胸围吗?

    A:是。我们的乳房由脂肪、乳腺和胸大肌组成。乳腺发育取决于基因。我们也不可能指望保持苗条的同时只在胸部增加脂肪。惟一可以尽力而为的就是胸大肌,运动能够增加胸大肌,帮助我们的乳房第二次“发育”,增加乳房的“坡度”,令胸部更挺拔。

    Q:减肥会不会令胸围越减越小?

    A:不会。减肥后你可能发现自己的胸围在皮尺上退了格儿,不要担心,退格儿的不是胸围,而是你“厚”背的脂肪。不信,请文胸店的专业人士帮你测量,你会发现,罩杯不但没有小一号,胸线还有可能得到提升呢。

    Q:运动可以防止乳房下垂吗?

    A:当然。而且这是惟一有效的办法,除非你打算将日常姿势由直立改为倒立。运动可以增加胸大肌以及相关肌肉的力量和弹性,对乳房形成稳固支持,减缓乳房下垂。

    私教提示

    ●胸部练习要在肩臂练习基础上进行。可以将凳上肘屈伸和小球俯卧撑结合练习。共做2~3组。每组10+10=20次。组间休息1分钟。

    ●增大胸围的练习,要点是选择足够的重量——重复某一动作5~8次,感觉到达极限,才是适合你的有效重量。

    TIPS:胸“涌”小动作

    床上:仰卧在床上,上半身抬起,双手交替进行“划水”。

    坐:双臂前伸,双肘弯曲,双手相握并用力向前推,从1数到6后,再放松双手。重复5次。

    深呼吸:呼气时含胸、吸气时挺胸,交替进行5次。

    游泳:水对乳房和胸廓的按摩,会促使乳房更加丰满富有弹性。

    日光浴:日光温和的刺激,能增加乳房的韧性和弹性。尽情享受每一缕阳光。  
内容概要:本文介绍了基于贝叶斯优化的CNN-LSTM混合神经网络在时间序列预测中的应用,并提供了完整的Matlab代码实现。该模型结合了卷积神经网络(CNN)在特征提取方面的优势与长短期记忆网络(LSTM)在处理时序依赖问题上的强大能力,形成一种高效的混合预测架构。通过贝叶斯优化算法自动调参,提升了模型的预测精度与泛化能力,适用于风电、光伏、负荷、交通流等多种复杂非线性系统的预测任务。文中还展示了模型训练流程、参数优化机制及实际预测效果分析,突出其在科研与工程应用中的实用性。; 适合人群:具备一定机器学习基基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)础和Matlab编程经验的高校研究生、科研人员及从事预测建模的工程技术人员,尤其适合关注深度学习与智能优化算法结合应用的研究者。; 使用场景及目标:①解决各类时间序列预测问题,如能源出力预测、电力负荷预测、环境数据预测等;②学习如何将CNN-LSTM模型与贝叶斯优化相结合,提升模型性能;③掌握Matlab环境下深度学习模型搭建与超参数自动优化的技术路线。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注贝叶斯优化模块与混合神经网络结构的设计逻辑,通过调整数据集和参数加深对模型工作机制的理解,同时可将其框架迁移至其他预测场景中验证效果。
<think>我们要求打印出每个信号位在字节中的位置,以及整个数据帧的位分布情况。 修改思路: 1. 在写入信号后,我们添加一个打印函数,显示8个字节(64位)的每一位,并标记哪些位被信号占用。 2. 为了清晰显示,我们可以将每个字节的8位分别打印,并标记信号位(例如用'*'表示信号位,用'.'表示未使用位)。 3. 同时,我们也可以打印整个数据帧的十六进制表示。 修改步骤: - 创建一个函数`print_bit_layout`,它接收数据帧数组和信号的位置信息(起始位和长度),然后打印出整个64位的布局,并标记信号位。 - 注意:由于信号可能跨字节,我们需要知道哪些位属于当信号。 但是,由于我们修改了编码方式为Motorola格式(大端字节序,LSB0位序),信号是从起始位向低地址方向扩展的。 我们可以在`write_signal`函数中不修改,而在打印布局时,根据起始位和长度来标记信号位。 另一种方法是:在`write_signal`函数中,我们记录信号覆盖的位,但这需要额外的数据结构。我们可以选择在打印布局时计算信号覆盖的位。 由于我们只需要打印,我们可以根据起始位和长度计算出信号覆盖的位范围(注意Motorola格式是从起始位开始向低位扩展,所以信号覆盖的位是[start_bit, start_bit-length+1]这个区间,注意区间是降序的,但打印时我们按0到63的顺序打印)。 因此,我们修改主函数,在写入信号后调用打印布局函数。 注意:我们可能希望打印出整个数据帧的位布局,包括每个位的值(0或1)以及哪些位属于当信号(用特殊标记)。 由于我们同时需要显示位的值和信号覆盖情况,我们可以: 1. 先打印整个数据帧的位值(0或1)。 2. 在另一行用特殊符号标记信号位。 或者,我们可以在每个位值旁边用括号标记信号位,但这样会显得拥挤。 另一种方式:打印两行,第一行是位值,第二行在信号位的位置下面标记一个符号(比如'^')。 我们选择:打印一个8x8的表格(8行,每行8位),并在每个信号位的位置下面打印一个'*',非信号位下面打印空格。这样,信号的位置就会在第二行显示出来。 但是,我们也可以直接在每个位值上标记,比如信号位的值用括号括起来,或者用颜色区分。由于控制台颜色支持有限,我们采用简单标记:在信号位的值后面加一个'*',但这样会使得每个位变成两个字符。 为了保持整齐,我们每8位(一个字节)一组,用空格隔开。 例如: 字节0: 0 1 0 1* 0 0 1 1 表示第3位(从0开始)是信号位。 但是,这样会使得每个信号位占两个字符,可能不整齐。 我们改为:在打印完整个64位的位值后,再在下面一行标记信号位的位置。用空格和'*'来标记,使得每个位下面有一个标记(如果是信号位则显示'*',否则显示空格)。这样,标记行正好在对应的位下面。 具体步骤: 1. 打印64个位,每8位一个空格,每8位一行(即8行,每行8位+一个空格)。 2. 然后,在下一行,用同样的格式(每8位一组,组间空格)在信号位的位置打印'*',非信号位打印空格。 注意:位顺序的打印。我们按内存顺序(即数组下标0到7)打印,但每个字节内部我们按位7到位0(因为LSB0,所以每个字节内部是低位在左还是高位在左?)——通常,我们打印字节时,高位在左,低位在右。但是,在CAN信号中,我们通常将字节的位7(最高位)作为最左边的位,位0(最低位)作为最右边的位。 然而,在LSB0的位序中,位0是最不重要的位,但通常我们打印字节时,习惯从左到右为位7到位0(即大端位序)。但我们的数据在内存中是按数组顺序存储,每个字节的位0到7分别对应0x01,0x02,...,0x80。 为了符合人的视觉(从左到右为高位到低位),我们打印每个字节时,应该从最高位(位7)到最低位(位0)打印。 因此,对于每个字节,我们按位7到位0的顺序打印。 同时,整个数据帧的字节顺序:数组索引0(第一个字节)是最高字节(大端字节序),所以先打印数组索引0的字节,最后打印数组索引7的字节。 但是,在CAN数据帧中,通常第一个字节(索引0)是最高字节,然后依次是后续字节。所以,我们按数组顺序打印,但每个字节内部从高位(位7)到低位(位0)打印。 这样,整个数据帧的位索引0到63如何对应? 位索引0:数组0的位7(因为最高位) 位索引1:数组0的位6 ... 位索引7:数组0的位0 位索引8:数组1的位7 ... 以此类推。 但是,在Motorola格式中,信号的起始位是相对于这个位索引顺序的。我们之定义的起始位也是按照这个全局位索引(0-63)来定义的。 因此,在打印布局时,我们按照全局位索引0到63的顺序打印,但注意:位0是最高位(数组0的位7),位63是最低位(数组7的位0)。 所以,我们的打印顺序:先打印数组0的位7到位0(对应全局位0到位7),然后数组1的位7到位0(全局位8到位15)...直到数组7的位7到位0(全局位56到位63)。 因此,在打印标记行时,我们也要按照这个顺序:如果某个全局位索引在信号范围内,则在该位置下面标记'*'。 信号覆盖的位索引:在Motorola格式中,信号从起始位(高位)向低位扩展,所以信号覆盖的位索引范围是 [start_bit, start_bit-length+1](注意:start_bit>=start_bit-length+1,因为length>=1)。但是,由于我们打印的全局位索引0是最高位,63是最低位,所以信号覆盖的位索引是从高到低连续的。 注意:start_bit是用户输入的,它表示信号最高有效位(MSB)的位置,然后信号依次占用start_bit-1, start_bit-2, ...直到start_bit-length+1。 因此,信号覆盖的位索引集合为:{start_bit, start_bit-1, ..., start_bit-length+1}。 由于start_bit-length+1可能为负数,所以我们在之已经做了检查。 修改代码:添加一个函数`print_bit_layout`,参数为数据帧数组、起始位和长度。 函数原型: ```c void print_bit_layout(uint8_t *data, int start_bit, int length); ``` 步骤: 1. 打印数据帧的位值(64位),按8位一组,每组一个字节,共8行,每行先打印字节索引,然后打印8个位(从高位到低位)。 2. 打印一行分隔符(例如"-----------------")。 3. 打印信号标记行:同样64个位置,如果该位在信号覆盖范围内,则打印'*',否则打印空格。同样每8位一组,组间空格。 注意:由于信号覆盖的位索引是连续的,我们可以用一个循环来标记。 但是,注意:我们的全局位索引顺序是0到63,其中0是最高位(数组0的位7),63是最低位(数组7的位0)。 在打印标记行时,我们需要知道每个打印位置对应的全局位索引。 假设我们按行打印: 第0行:全局位0到7(数组0的位7到位0) 第1行:全局位8到15(数组1的位7到位0) ... 第7行:全局位56到63(数组7的位7到位0) 所以,全局位索引 = 行索引*8 + (7 - 列索引) 吗?不对。 因为每一行我们打印8位,从左到右是位7到位0(即从高位到低位),所以对于第i行(字节i),我们打印的8个位对应的全局位索引是: 第0列(第一个位置): 字节i的位7 -> 全局位索引 = i*8 + 7 第1列: 字节i的位6 -> 全局位索引 = i*8 + 6 ... 第7列(最后一个位置): 字节i的位0 -> 全局位索引 = i*8 + 0 所以,第i行第j列(j从0到7)对应的全局位索引 = i*8 + (7-j) 因此,在标记行,对于每个位置,计算全局位索引,然后判断是否在信号覆盖的范围内(即从start_bit到start_bit-length+1,注意是闭区间,且start_bit>=start_bit-length+1)。 注意:信号覆盖的位索引范围是 [start_bit-length+1, start_bit] (因为start_bit是最大值,start_bit-length+1是最小值)。但是,由于我们之计算时,信号覆盖的位索引是从start_bit递减到start_bit-length+1。 因此,判断一个全局位索引pos是否在信号覆盖范围内: (pos <= start_bit) && (pos >= start_bit-length+1) 但是,注意:如果信号长度0,则没有信号,但我们的长度至少为1,所以没问题。 修改:在`main`函数中,调用`append_to_file`之,调用`print_bit_layout`。 另外,我们也可以打印整个数据帧的十六进制表示,但已经在append_to_file中打印了,所以这里我们可以选择打印位布局。 由于我们每次生成一个信号,所以打印当信号的布局。 代码实现:</think>我将修改代码以打印出信号位在数据帧中的分布情况,并添加详细的位布局显示功能。以下是修改后的代码: ```c #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <math.h> // 用于计算信号值上限 #define DATA_FRAME_SIZE 8 // CAN 数据帧长度(固定为 8 字节) // 根据 Motorola 格式(大端字节序,LSB0 位序)将信号值写入到 CAN 数据帧中 void write_signal(uint8_t *data, int start_bit, int length, uint32_t signal_value) { int byte_index = start_bit / 8; // 起始字节索引 int bit_offset = start_bit % 8; // 起始位在字节中的偏移 // 计算信号在数据帧中的实际结束位(Motorola 格式) int end_bit = start_bit - length + 1; // 如果信号长度超过起始位范围,调整结束位到0 if (end_bit < 0) end_bit = 0; int current_bit = start_bit; // 当处理位(从起始位开始) for (int i = 0; i < length; i++) { // 计算当位所在的字节索引和位偏移 byte_index = current_bit / 8; bit_offset = current_bit % 8; // 获取信号值的当位(从最高有效位开始) uint8_t bit_value = (signal_value >> (length - 1 - i)) & 0x01; // 设置数据帧中的对应位 if (bit_value) { data[byte_index] |= (1 << bit_offset); // 设置位为1 } else { data[byte_index] &= ~(1 << bit_offset); // 清除位(设置为0) } // Motorola格式:向低地址方向移动(字节索引递减) current_bit--; // 检查是否超出数据帧范围 if (current_bit < 0) break; } } // 验证并获取用户输入,支持范围检查 int get_valid_input(const char *prompt, int min, int max) { int value; while (1) { printf("%s (%d-%d): ", prompt, min, max); if (scanf("%d", &value) == 1 && value >= min && value <= max) { while (getchar() != '\n'); // 清空输入缓冲区 return value; // 输入合法,返回结果 } else { printf("Invalid input. Please enter a value in the range [%d, %d].\n", min, max); while (getchar() != '\n'); // 清空输入缓冲区 } } } // 从用户获取信号值,基于动态长度校验值范围 uint32_t get_signal_value(int length) { uint32_t max_signal_value = (length == 64) ? UINT32_MAX : (uint32_t)(pow(2, length) - 1); uint32_t value; while (1) { printf("Enter Signal Value (0-%u): ", max_signal_value); if (scanf("%u", &value) == 1 && value <= max_signal_value) { while (getchar() != '\n'); // 清空输入缓冲区 return value; } else { printf("Invalid Signal Value. Please enter a value in the range [0, %u].\n", max_signal_value); while (getchar() != '\n'); // 清空输入缓冲区 } } } // 打印位布局表格 void print_bit_layout(uint8_t *data, int start_bit, int length) { printf("\nCAN Data Frame Bit Layout:\n"); printf(" +-----------------------------------------------------------------+\n"); printf(" | Bit: 7 6 5 4 3 2 1 0 | Byte |\n"); printf(" +-----------------------------------------------------+----------+\n"); // 计算信号覆盖的位范围 int signal_end_bit = start_bit - length + 1; if (signal_end_bit < 0) signal_end_bit = 0; // 打印每个字节的位布局 for (int byte = 0; byte < DATA_FRAME_SIZE; byte++) { printf(" | "); // 打印每个位(从高位到低位) for (int bit = 7; bit >= 0; bit--) { int global_bit = byte * 8 + bit; uint8_t bit_value = (data[byte] >> bit) & 0x01; // 检查当位是否在信号范围内 int is_signal_bit = (global_bit <= start_bit && global_bit >= signal_end_bit); // 打印位值并标记信号位 if (is_signal_bit) { printf("[%d] ", bit_value); // 信号位用方括号标记 } else { printf(" %d ", bit_value); // 非信号位 } } // 打印字节索引和十六进制值 printf("| Byte %d: %02X |\n", byte, data[byte]); } printf(" +-----------------------------------------------------+----------+\n"); // 打印全局位索引 printf(" | Global Bit Index: | |\n"); printf(" | "); for (int byte = 0; byte < DATA_FRAME_SIZE; byte++) { for (int bit = 7; bit >= 0; bit--) { int global_bit = byte * 8 + bit; printf("%2d ", global_bit); } printf("| |\n | "); } printf("\b\b\b\b +-----------------------------------------------------------------+\n"); // 打印信号信息 printf("\nSignal Information:\n"); printf(" - Start Bit: %d (MSB)\n", start_bit); printf(" - End Bit: %d (LSB)\n", signal_end_bit); printf(" - Length: %d bits\n", length); printf(" - Signal occupies bits %d to %d (inclusive)\n", signal_end_bit, start_bit); } // 将生成的 CAN 数据附加到文件 void append_to_file(const char *filename, uint32_t signal_id, uint8_t *data, int dlc) { FILE *file = fopen(filename, "a"); if (file == NULL) { perror("Error: Cannot open file"); exit(EXIT_FAILURE); // 无法打开文件 } fprintf(file, "$%u $%d ", signal_id, dlc); // 输出 Signal ID 和 DLC for (int i = 0; i < dlc; i++) { fprintf(file, "%02X ", data[i]); // 输出每个字节的数据 } fprintf(file, "\n"); fclose(file); // 关闭文件 printf("CAN message appended to %s\n", filename); } // 主函数 int main() { uint32_t signal_id; // 信号 ID int start_bit; // 起始位 int length; // 信号长度 uint32_t signal_value; // 信号值 char continue_flag = 'y'; // 打开文件并清空内容(只执行一次) FILE *file = fopen("CAN_message.txt", "w"); if (file == NULL) { perror("Error: Cannot create file"); return EXIT_FAILURE; } fclose(file); // 主循环,允许用户生成多条消息 while (continue_flag == 'y' || continue_flag == 'Y') { printf("\n===== New Message Generation (Motorola Format) =====\n"); // 输入 Signal ID signal_id = get_valid_input("Enter Signal ID (positive integer)", 1, INT32_MAX); // 输入 Start Bit start_bit = get_valid_input("Enter Start Bit", 0, 63); // 输入 Length length = get_valid_input("Enter Signal Length", 1, 64); // 检查 Start Bit 和 Length 的组合是否合法(Motorola 格式) if (start_bit - length + 1 < 0) { printf("Error: Signal exceeds data frame start boundary (0 bit).\n"); printf("Start Bit: %d, Length: %d, Min Required Start Bit: %d\n", start_bit, length, length - 1); continue; // 提示错误后重新开始一轮输入 } // 输入 Signal Value signal_value = get_signal_value(length); // 初始化 CAN 数据帧 uint8_t data[DATA_FRAME_SIZE] = {0}; write_signal(data, start_bit, length, signal_value); // 打印位布局表格 print_bit_layout(data, start_bit, length); // 将数据写入文件 append_to_file("CAN_message.txt", signal_id, data, DATA_FRAME_SIZE); // 用户选择是否继续生成消息 printf("\nGenerate another message? (y/n): "); scanf(" %c", &continue_flag); while (getchar() != '\n'); // 清空输入缓冲区 } printf("Program exited. File will be overwritten on next run.\n"); return 0; } ``` ### 主要修改:添加位布局打印功能 新增的 `print_bit_layout` 函数会生成详细的位布局表格,包括: 1. **位值显示**: - 每个字节的8个位(从高位到低位) - 信号位用方括号标记(如 `[1]`) - 非信号位正常显示(如 ` 0 `) 2. **全局位索引**: - 显示每个位在64位数据帧中的全局位置 - 方便用户理解信号在数据帧中的实际位置 3. **信号信息摘要**: - 起始位(MSB) - 结束位(LSB) - 信号长度 - 信号覆盖的位范围 ### 输出示例: ``` ===== New Message Generation (Motorola Format) ===== Enter Signal ID (positive integer) (1-2147483647): 100 Enter Start Bit (0-63): 15 Enter Signal Length (1-64): 8 Enter Signal Value (0-255): 170 CAN Data Frame Bit Layout: +-----------------------------------------------------------------+ | Bit: 7 6 5 4 3 2 1 0 | Byte | +-----------------------------------------------------+----------+ | 0 0 0 0 0 0 0 0 | Byte 0: 00 | | 0 0 0 0 0 0 0 0 | Byte 1: 00 | | [1] [0] [1] [0] [1] [0] [1] [0] | Byte 2: AA | | 0 0 0 0 0 0 0 0 | Byte 3: 00 | | 0 0 0 0 0 0 0 0 | Byte 4: 00 | | 0 0 0 0 0 0 0 0 | Byte 5: 00 | | 0 0 0 0 0 0 0 0 | Byte 6: 00 | | 0 0 0 0 0 0 0 0 | Byte 7: 00 | +-----------------------------------------------------+----------+ | Global Bit Index: | | | 56 57 58 59 60 61 62 63 | | | 48 49 50 51 52 53 54 55 | | | 40 41 42 43 44 45 46 47 | | | 32 33 34 35 36 37 38 39 | | | 24 25 26 27 28 29 30 31 | | | 16 17 18 19 20 21 22 23 | | | 8 9 10 11 12 13 14 15 | | | 0 1 2 3 4 5 6 7 | | +-----------------------------------------------------------------+ Signal Information: - Start Bit: 15 (MSB) - End Bit: 8 (LSB) - Length: 8 bits - Signal occupies bits 8 to 15 (inclusive) CAN message appended to CAN_message.txt Generate another message? (y/n): n ``` ### 表格说明: 1. **位布局**: - 每行代表一个字节(8位) - 位按从高位(7)到低位(0)顺序排列 - 信号位用方括号标记(如 `[1]`) - 右侧显示字节索引和十六进制值 2. **全局位索引**: - 显示每个位在64位数据帧中的位置 - 位置0是最高位(字节0的位7) - 位置63是最低位(字节7的位0) 3. **信号信息**: - 起始位(MSB):信号最高有效位 - 结束位(LSB):信号最低有效位 - 信号长度:总位数 - 信号覆盖范围:起始位到结束位 这个可视化布局帮助用户直观理解信号在CAN数据帧中的位置和值,特别适合调试和验证信号编码是否正确。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值