看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《yauhh (喲)》之銘言: : ※ 引述《liu23829 (做人別太跩)》之銘言: : : 而且此區塊移動整理後,並無法形在某區塊右下和下方皆為0元素,故停止 : : 重點還是“非0元素的移動”,針對鎖定的行,做列的移動,再針對 : : 移動後非0元素所在列做行的移動,以此類推,而判別停止的條件有2 : : 1.形成某區塊右下和下方皆為0元素,則停止,遮閉該區塊所在的行與列,考慮剩下的區塊 : : 2.移動後無法形成右方和下方皆為0元素,也要停止 : : 演算式我想不出來,能幫忙的感激不盡~~~~ : 矩陣的運算很少,算一算只有加法,乘法,轉置. : 還有,可能包含你所說的行互換跟列互換. : 我猜你想要的是: : 將矩陣做任意次序的行互換或列互換,使矩陣元素盡可能貼齊對角線. : 那我想,可以先寫個函數將一列 1xN 或 Mx1 矩陣用二進位換算法算成數值: : int ToBinary(double string[], int len) { : int result = 0; : for (int i=0; i<len; i++) { : result *= 2; : result += (string[i] == 0)? 0 : 1; : } : return result; : } : 然後,對你所指定的矩陣: : double matrix[][6] = { : {0.5,0,0,0.0,0}, : {0,2,0,0,3,2}, : {0,0,2,0,1,0}, : {0,0.333,0,0,0,0}, : {1,0,0,2,0,0} : }; : for (int i=0; i<5; i++) { : for (int j=0; j<6; j++) { : cout << matrix[i][j] << '\t'; : } : cout << endl; : } : cout << endl; : 先對行排序,再對列排序: : cout << "Sort columns: " << endl; : for (int i = 1; i<6; i++) { : for (int j = 0; j<6-i; j++) { : double *p = new double[5]; : double *q = new double[5]; : for (int k=0; k<5; k++) { : p[k] = matrix[k][j]; : q[k] = matrix[k][j+1]; : } : if (ToBinary(p, 5) < ToBinary(q, 5)) { : for (int k=0; k<5; k++) { : matrix[k][j] = q[k]; : matrix[k][j+1] = p[k]; : } : } : delete p; : delete q; : } : } : for (int i=0; i<5; i++) { : for (int j=0; j<6; j++) { : cout << matrix[i][j] << '\t'; : } : cout << endl; : } : cout << endl; : cout << "Sort rows: " << endl; : for (int i = 1; i<5; i++) { : for (int j = 0; j<5-i; j++) { : double *p = new double[6]; : double *q = new double[6]; : for (int k=0; k<6; k++) { : p[k] = matrix[j][k]; : q[k] = matrix[j+1][k]; : } : if (ToBinary(p, 6) < ToBinary(q, 6)) { : for (int k=0; k<6; k++) { : matrix[j][k] = q[k]; : matrix[j+1][k] = p[k]; : } : } : delete p; : delete q; : } : } : for (int i=0; i<5; i++) { : for (int j=0; j<6; j++) { : cout << matrix[i][j] << '\t'; : } : cout << endl; : } : cout<< endl; : 先對行排序再對列排序,輸出為: : ----------------------------------------- : 0.5 0 0 0 0 0 : 0 2 0 0 3 2 : 0 0 2 0 1 0 : 0 0.333 0 0 0 0 : 1 0 0 2 0 0 : Sort columns: : 0.5 0 0 0 0 0 : 0 3 2 2 0 0 : 0 1 0 0 2 0 : 0 0 0.333 0 0 0 : 1 0 0 0 0 2 : Sort rows: : 1 0 0 0 0 2 : 0.5 0 0 0 0 0 : 0 3 2 2 0 0 : 0 1 0 0 2 0 : 0 0 0.333 0 0 0 : 請按任意鍵繼續 . . . : ----------------------------------------- : 看起來不漂亮,有個2跑在右上角. 那就接著再做一次行排序與列排序, : 結果是: : ----------------------------------------- : Sort columns: : 1 2 0 0 0 0 : 0.5 0 0 0 0 0 : 0 0 3 2 2 0 : 0 0 1 0 0 2 : 0 0 0 0.333 0 0 : Sort rows: : 1 2 0 0 0 0 : 0.5 0 0 0 0 0 : 0 0 3 2 2 0 : 0 0 1 0 0 2 : 0 0 0 0.333 0 0 : 請按任意鍵繼續 . . . : ----------------------------------------- : 做到這裡大概再也排不動了. : 對照前面你所導出的結果,我這個結果還要再把一二列互換,三四列互換. : 並將第六行插到二三行之間. : 在我的方法中,也許我可以改寫 int ToBinary(double string[], int len) 函數, : 使它判斷 : * - - - - - : 大於 : * * - - - - : 而後者又大於 : - * - - - - : 就會有適合的排列結果. 我解釋一下,並不是向對角線靠攏,我強調的非0元素的移動,基本上是向左上方移動 透過基本兩列與兩行的互換,為何一開始要定義J=1,這個意思是從一個矩陣的第一行 開始來做非0元素的移動,所以要鎖定第一行,在第一行裡有非0元素就透過兩列的互換 使非0元素往上移,0元素往下移 上述的例子,在第一次的列移動後(R5→R2),第一行變成[0.5,1,0,0,0],此時 第一行中,非0元素所在的列為1、2列, 定義Ib1(這個意思是第一次移動後非0元素所在的列個數為2,故Ib1=2) 再針對這2列(也就是1、2列,做非0元素的行移動,第一次的行移動為C2→C4) 非0往左靠,0往右靠, 移動後定義Jb1(針對第1、2列行移動後,含一非0元素以上所在的行個數為2,Jb1=2) 再針對此2行(也就是1、2行)做列的移動,非0往上,0往下,所以會有Ib2之後Jb2 所以它是有迴圈關係的,在移動的過程,非0元素會慢慢形成區塊 這種移動方式才有辦法使某區塊形成右下和下方皆為0元素,當然如果不能,就停止 -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.167.147.155
yauhh:移向左上方,嗯 06/20 21:53