→ yauhh:移向左上方,嗯 06/20 21:53
※ 引述《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