首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

決策表快速排序:屬性序下的粗糙集約簡算法實現

     編輯:關於C語言

決策表排序是粗糙集理論中屬性約簡的關鍵預處理步驟。本文實現了基於屬性序的快速排序算法,源自《計算機學報》相關研究,在 UCI 數據集上展現優異性能。

問題背景

決策表類似關係數據庫二維表,每行為對象,列為條件屬性+決策屬性。約簡需先對象分類,蠻力兩兩比較 O(n²) 不可行,排序後分類可降至 O(n log n)。

數據示例

原始表:          排序後(按第1列→第2列→第3列):
4 3 0             1 0 1
1 0 1             1 2 0
8 1 0             1 2 1
1 2 0             4 3 0
1 2 1             7 3 1
7 3 1             7 4 0
7 4 0             8 1 0

算法核心:多鍵值快速排序

遞歸按屬性序排序:先按第 1 屬性分區,再在相等分區內按第 2 屬性排序,以此類推。

關鍵數據結構

typedef struct {
    int *data;           // 扁平化存儲:row * attrs + col
    int rows, cols;      // 行數、屬性數
    int *tblIdx;         // 行索引排序結果
    int *posRegion;      // 正區域標記
} DecisionTable;

分區邏輯(三向切分擴展)

int partition(DecisionTable *dt, int *idx, int stage, int low, int high) {
    int ext = dt->cols;
    int *data = dt->data;
    int mid = low, hiEnd = mid + 1;
    int pivot = data[idx[low] * ext + stage];
    int counter = 0;
    
    for (int i = low + 1; i <= high; i++) {
        int val = data[idx[i] * ext + stage];
        if (val < pivot) {
            swap(&idx[mid++], &idx[i]);
            hiEnd++;
            counter++;
        } else if (val == pivot) {
            swap(&idx[hiEnd++], &idx[i]);
        }
    }
    swap(&idx[low], &idx[mid]);
    return mid;  // 返回 =pivot 區域邊界
}

遞歸多維排序

void TDQuicksort(DecisionTable *dt, int *idx, int stage, int low, int high) {
    if (stage >= dt->condAttrs || low >= high) return;
    
    int mid = partition(dt, idx, stage, low, high);
    int nextStage = stage + 1;
    
    // 處理  1)  // 多於1個元素才需下一層排序
            TDQuicksort(dt, idx, nextStage, i, j-1);
        i = j;
    }
    
    // 處理 >pivot 區域
    TDQuicksort(dt, idx, stage, mid + 1, high);
}

正區域計算

排序後,相同條件屬性的對象連續分布。掃描判斷決策屬性是否一致,標記正區域。

void loadPositiveRegion(DecisionTable *dt, int *idx, int *posRegion) {
    // 使用堆內存管理條件類
    // 比較條件屬性相同的連續塊,決策屬性一致則標記為正區域
    // 位運算優化:將多屬性打包為 BigInt 比較
}

分區矩陣構建

為約簡算法準備:按屬性重要性序遞歸分區,計算每層區塊的非空標記與平均值,指導屬性選擇。

實驗結果

數據集規模條件屬性排序耗時
Forest CoverType581,012 行540.234s
Poker Hand1,025,010 行100.359s

環境:i3-2100 + 4GB + Win7 32bit + VS2012 Release

工程優化亮點

  • 扁平化存儲:一維數組 row*cols + col,緩存友好
  • 索引間接排序:移動索引而非數據行,減少拷貝
  • 位打包比較:多屬性合併為 64 位整數,單指令比較
  • 私有堆分配:HeapCreate/HeapAlloc 避免頻繁 malloc 開銷
  • 三向切分:大量重複值時避免退化

遞歸深度控制

屬性數較多時遞歸深度可能超過棧限制,建議:

  • 尾遞歸優化(編譯器通常自動處理)
  • 顯式棧模擬遞歸
  • 限制最大屬性數或採用迭代版本

應用價值

此算法不僅服務於粗糙集約簡,同樣適用於:

  • 多列數據庫索引構建
  • OLAP 多維數據排序
  • 特徵工程中的數據預處理
  • 任何需按多鍵值排序的大規模結構化數據

決策表快速排序展示了領域知識(屬性序)與經典算法(三向快排)結合的威力。在大數據時代,這類針對結構化數據的專用排序算法,往往能超越通用庫函數數倍性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved