c++進階:Compare

關係是有序對的集合c++

  • 關係可能具備的性質定義

如下均假設R是集合A上的二元關係:算法

  1. 自反性 ,若是對於A中的每一個元素x,都有<x, x> 屬於R,則稱R具備自反性。
  2. 反自反性(irreflexivity) ,若是對於A中每一個元素x,都有<x, x>不屬於R,則稱R具備反自反性。
  3. 對稱性,若是對於R中的每一個有序對<x, y>都有對應的有序對<y, x>也屬於關係R,則稱R具備對稱性。
  4. 反對稱性,若是對於R中的每一個有序對<x, y>,且<y, x>也屬於關係R,那麼x == y必定成立,則稱R具備反對稱性。注意:有些關係既是對稱的,又是反對稱的,如相等關係;有些關係是對稱的,但不是反對稱的,如Z中的「絕對值相等」;有些關係是反對稱的,但不是對稱的,如Z中的≤和<;還有的關係既不是對稱的,又不是反對稱的。
  5. 傳遞性 對於A中的元素x, y, z, 若是<x, y>屬於R而且<y, z>屬於R,那麼<x, z>就屬於R,則稱R具備傳遞性。
  • 偏序集(partical order)

設R是集合A上的一個關係,若是R是自反的、反對稱的和可傳遞的,則稱R是集合A的偏序關係,簡稱偏序,記做「≤」。這裏的符號不只僅指咱們以前學過的具體符號,而是偏序的符號,固然小於等於號(對應的關係)自己是典型的偏序關係。
通常將一個集合A和定義在其上的偏序關係R一塊兒稱爲偏序集。
wiki定義:https://en.wikipedia.org/wiki/Partially_ordered_set#Strict_and_non-strict_partial_orders
對於集合A中的元素x和y而言,若是有序對<x, y>或者<y, x>屬於偏序關係R,則稱x和y是可比較的(comparable),不然稱x和y是不可比較的(incomparable)。若是集合A中的任意兩個元素之間是可比較的,則稱偏序關係R爲全序關係(total order)。數組

  • 全序集(total order)

對於一個偏序集A,R,若是對於A中的任意兩個元素x和y,有序對<x, y>和<y, x>至少有一個屬於關係R,則稱R爲序關係,A和R一塊兒稱爲全序集合/有序集。和上面的定義本質上是同樣的。數據結構

舉例:一個偏序集而不是全序集的例子,集合的包含關係,兩個集合間多是不可比較的。函數

  • 嚴格和非嚴格偏序關係(strict and non-strict partial orders)

上述定義的偏序集能夠認爲是非嚴格的,主要是爲了與下面的嚴格偏序集作對比:
一個嚴格偏序關係須要具備以下性質:
反自反性,傳遞性和反對稱性。記做小於號符號,和上面的定義相似,這裏僅做爲一個符號使用,固然咱們熟悉的小於號對應的關係是典型的嚴格偏序關係。flex

  • 嚴格的弱序關係(strict weak orderings)

若是一個嚴格偏序集(集合A與定義在集合A上的嚴格偏序關係R)的關係R知足:若是A上的元素x,y,z,x和y是不可比較的,y和z是不可比較的,則x和z是不可比較的。那麼稱這樣的關係爲嚴格弱序關係,也就是說具備可傳遞的不可比較性。ui

  • 等價關係(equivalence relation)

一個等價關係應該具備以下性質:
自反性,傳遞性,對稱性。
注意到,嚴格弱序集上的不可比較的關係(incomparability relation)是一種等價關係。 // 我的猜想,官方說法很模糊。
證實:
//注意理解,不可比較關係是依附於某個關係定義的,便是關係的關係。
//自反性:x和x是不可比較的,由於嚴格弱序是反自反的,因此!(xRx) && !(xRx)爲真。
//傳遞性:!(xRy) && !(yRx)爲真,!(yRz) && !(zRy)爲真,則因爲嚴格弱序關係的額外性質,便可傳遞的不可比較性,所以!(xRz) && !(zRx)爲真,不可比較關係是傳遞的
//對稱性:!(xRy) && !(yRx)爲真,則因爲邏輯運算左右兩側交換不影響結果,所以不可比較關係是對稱的。
因此說嚴格弱序關係的定義保證了定義在其上的不可比較關係是等價關係。
wiki : https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderingsurl


以上是前導知識,如今看下今天要說的c++中的一個concept:Compare。這個concept在c++的標準庫中普遍涉及並使用,例如關聯容器set和map中,算法sort中等等,url : https://en.cppreference.com/w/cpp/named_req/Compare
具體的requirements見上連接便可,總的來講就是知足Compare的類的對象是一個函數對象,等同於關係,其兩個參數等同於元素,這個關係應該是一個嚴格弱序關係。code

注意標準中的這句話:Note: comp induces a strict total ordering on the equivalence classes determined by equiv
這個嚴格弱序關係在equiv定義的等價類上是一個嚴格全序關係
//equiv就是上文中的不可比較關係(也是等價關係),原集合能夠被劃分爲不一樣的等價類,每一個等價類是一個子集合,該集合中的元素兩兩等價。
這其實很好理解,只要x和y來自不一樣的等價類,那麼<x, y>或者<y, x>至少有一個屬於嚴格弱序關係的集合--由於根據定義都不屬於的話x和y確定在一個等價類中。對象

所以,當你爲map和set以及可重複版本提供自定義類型的key時,以及對自定義類型的對象進行sort排序時(不管使用默認版本仍是提供比較函數,由於默認版本最終仍是要調用operator<)都要注意,你定義的關係須要知足嚴格弱序關係。


以後會舉一個例子說明,這種狀況並很多見,並且有時候比較複雜和隱晦。

以前寫過一個將三維物體體素化的程序(數值模擬中也叫網格剖分),該程序準備工做部分的主要流程以下:

void StlEntity::init_topo() {
//1.遍歷三角面片,構造三角面片索引表
//構造點索引表,記錄每一個點所在的三角面片索引
_create_tria_set_and_point_set_();

//合併相同點,並繼承所屬三角面片信息
_merge_point_set_();

//此時節點合併完成,且每一個節點所屬於的三角面片的索引更新完成。
//爲每一個三角面片設置頂點索引
_set_point_index_of_tria_set_();

//構建邊索引集合
_create_edge_set_();

//合併重複邊
_merge_edge_set_();

//給每一個三角面和點設置邊索引
_set_edge_index_for_tria_and_point_set_();

//拓撲檢查
topo_check();
}
  • 背景知識,能夠跳過這段不影響閱讀

準備部分主要是將STL格式文件中的數據讀入內存,而後經過分析和處理構建等價的內部表示,最後進行拓撲檢查。這麼作的緣由主要有兩個,其一是後續的體素化過程的一些處理須要特殊的數據結構支持,其二是爲了進行拓撲檢查,由於當三維實體特徵十分複雜時特別容易出現STL缺陷,例如縫隙,多餘三角面片,空洞等等,這些缺陷須要被儘早識別出來並處理掉,不然後續的算法會發生錯誤。

其中第二部分合並相同點,須要對三維點的集合作一個排序,讓三維空間中同一個點在數組中相鄰,而後經過一遍掃描工做就能夠合併相同點了。注意,理論上相同的點在表示上並不必定是相等的,由於STL文件的轉換自己具備偏差,並且導入內存時計算機表示浮點數自己會損失精度,那麼咱們如何提供三維空間點的operator<函數,才能正確使用std::sort呢?
下面是個人實現:

struct point {
double x;
double y;
double z;
...
bool operator<(const point& other) const {
  if (x < other.x) {
    return true;
  }
  if (x == other.x && y < other.y) {
    return true;
  }
  if (x == other.x && y == other.y && z < other.z) {
    return true;
  }
  return false;
}
...
};

下面證實上述operator<定義的關係在三維空間點組成的集合中是一個嚴格弱序關係。

  1. 反自反性:對於每一個三維點x, x < x表達式返回的值永遠是false,這是顯然的。(這裏基於一個假設,儘管浮點數的存儲損失精度,但對一個已經存儲在內存中的浮點數,其任何經過複製獲得的浮點數以及本身和本身的比較結果x == x應該都返回true,我不知道c++是否是保證了這一點。)
  2. 反對稱性:因爲反自反性的存在,所以反對稱性等價的表述爲:對於任何的x < y == true, 必定有y < x == false。根據上面的定義,若是x < y返回true,只多是三個分支條件中的一個成立,窮舉一下能夠發現這三種狀況下y < x都返回false。
  3. 傳遞性:若是x < y == true && y < z == true,一樣把x<y和y<z的三種狀況組合下一共有九種狀況,每一種狀況必定有x < z == true成立。
  4. 不可比較性的傳遞性:若是x和y是不可比較的,y和z是不可比較的,下面證實x和z是不可比較的,當x和y不可比較時,表達式!(x < y) && !(y < x) == true,等價的x < y || y < x == false,即x < y == false和y < x == false同時成立,則 x.x == y.x && x.y == y.y && x.z == y.z爲真,同理y.x == z.x && y.y == z.y && y.z == z.z爲真, 因此x.x == z.x && x.y == z.y && x.z == z.z爲真,帶入可知!(x < z) && !(z < x) == true,即x和z是不可比較的。

綜上,operator<定義的關係在三維空間點組成的集合中是一個嚴格弱序關係。

相關文章
相關標籤/搜索