반응형

요약

 

  • Clique: "가능한 가장 많은 노드들이 fully connected(=complete graph)로 연결된 undirected network". 
  • k-plex: clique의 n-1에 해당하는 엣지의수 n-k로 일반화하여 조금 완화한 개념
  • k-core: 각각의 노드들이 적어도 k에 연결되어있어야 하는 서브그레프
  • k-clique: k개의 노드로 구성되어있는 clique

 


 

특징

 

  1. maximal의 의미는 다른 가능한 많은 노드들이 최대한 많이 연결된 상태를 의미한다. (=더 clique로 추가 될만한 노드가 없는 경우 = fully connected 로 연결할 수 있는 노드가 없는 경우)
  2. Clique은 서로 겹칠 수 있으며, 이는 한 노드(vertice)가 다른 clique에 포함될 수 있음을 의미한다.
  3. Sparse network(서로서로 잘 연결되어있지 않는 네트웍)에서의 Clique의 존재는 어떤 응집력이 매우 좋은 집단이 있음을 의미한다. 예를 들어, 소셜 네트워크의 경우도, 대부분이 fully connected로 잘 연결되어있지 않고, 어쩌다 연결되고, 일부 연결되어있는 사람들끼리서는 다 연결되어있는 친목그룹따위가 존재한다. 
  4. Clique을 구성하는 노드가 N개인경우 N-1개의 edge가 존재한다.

 

 


설명 및 예시

 

1. Maximal: 아래와 같이 4개의 노드(vertices)가 fully connected로 되어있고 (서로 연결), 이 4개외에는 fully connected로 연결해볼만한 노드가 더이상 없다.

Clique: 4개의 노드들이 서로 연결되어있는 경우(=더이상 추가할 노드가 없는 경우). 예를 들어 5시 방향에 있는 노드는 3시방향 6시방향의 노드와 연결되어있지만, 12시, 9시 방향의 노드와는 연결되어있지 않다.

 

2. Clique내 노드끼리는 겹칠 수 있다. clique내의 서브그레프도 하나의 clique라는 것을 의미하지 않고, 여러 clique내에 노드가 겹칠 수 있음을 의미한다. 예를 들어, 아래를 보면 A-B를 기점으로 clique가 2개로 될 수 있다. 그리고, 노드A와 B는 서로 각각 clique에 해당한다.

 

 


k-plex: k-plex은 clique(competed graph)의 모두 연결되어있어야하는 조건을 완화한 개념이다. 위에서 clique은 모든 노드들이 연결되어있어야한다고 했고, 이 경우는 n-1개의 연결(엣지)가 존재한다고 했다. k-plex은 여기어 n-1의 엣지수를 n-k로 일반화하여 조금 완화한 개념이라고 보면 이해가 직관적이다. 보통 "k plex of size n"을 의미하는데, 네트워크 안에 있는 n개의 노드중 적어도 n-k가 fully connected 되어있음을 의미한다. 예) k=1일 경우, 일반적인 clique와 동일한 의미를 갖는다. k=2인 경우는 적어도 vertex들이 다 연결되어있거나, 모든 노드들이 하나에만 연결되어있어야함을 의미한다. 

 

 

아래의 예시는 1-plex을 의미한다. 우선 모든 V1,V2,V3,V4가 모두 각각에 연결되어 clique이다. 그리고, n-k(=|V|(vertex 수 -1)은 3이므로, 각각 모든 노드가 3개의 엣지를 가지면 되는지 확인하면된다. V1,V2,V3,V4가 각각 3개의 노드를 가지므로 1-plex도 된다. 따라서, 1-plex = clique이다. 

Clique 이자 1-plex

 

 

다음은 몇-plex일까? 답은 2-plex. 우선 fully connected가 아니기 때문에 clique은 아니다. 즉, 1-plex은 아니라는 것이다. 2-plex일까? |V|(=n)은 5이고 각V1 ,V2은 3개의 엣지를 갖는다. 2-plex가 되려면, 모든 노드들이 5-2개의 엣지를 가져야한다. 그러나 V3, V4, V5은 2개씩의 엣지를 갖는다. 즉 2-plex도 아니다. 그러나, 이 그레프는 각 노드들이 최소 2개의 엣지를 갖는다. 이를 표현하면 $\delta(G)=2$라고 보통 표기한다. 따라서, 2>=5-k라는 수식을 두면, 가능한 k는 3,4,5가된다.

k-core : k-plex와 유사한 컨셉은 k-core라는 것이 있다. k-core은 k-plex와 마찬가지로 "maximal subset of vertice"으로 각각의 노드들이 적어도 k에 연결되어있어야하는 것이다. 예를 들어, 5개의 노드로 구성된 2-core는 (5-2)-plex와 같다. k-core와 k-plex와의 차니는 k-cores은 겹치는 것이 없다. k-cores의 장점은 적어도 k의 연결이 있어야하기에, 반대로 k-1개 이하의 엣지를 가진 노드를을 찾아 없애면되니, 상대적으로 k의 수를 알기가 쉬워 실용적인 분석이 될 수 있다.

* 그리고 k-core은 원래 그레프 G의 서브그레프 중에 유일한 서브그레프가 된다.

 

 

k-clique : 유사한 명명으로 되는 그레프 중에, k-clique가 있으며, 이는 한 노드에서 다른 노드로 최대 k개 이상의의 거리가 없는 경우의 "maximal subset" 을 의미한다. 만일 k=1이라면, clqiue랑 동일하다. 즉 모든 노드가 1개 이하의 거리를 갖는다. 만일 k가 커지면, 점점 그레프가 커지는거고 그레프의 최대 거리가 커지는 것을 의미한다. 이 개념이 다른 설명서에는 clique with k vertices라고 소개가 되는 경우도 있는데, k=3이면 3개의 노드로 이루어진 clique가 된다.

2-clique의 예시

아래를 참고하면 쉬운 영상이 있다.

https://www.youtube.com/watch?v=V2CgqTLWxvY

반응형

Summary: set, dict은 해시함수를 이용한 해시값을 저장하고있는 해시테이블이란 자료구조를 사용하기 때문에, 빠른 탐색이 가능함. 해시는 임의의 변수(문자열 등)를 숫자로 변환하여, 매핑하는 것을 의미함. 따라서, 임의의 변수가 오더라도 숫자로 매핑할 수 있고, 이 숫자로 매핑한 경우 인덱스처럼 사용할 수 있어 빠른 검색이 가능함.

 

 

해시함수를 이용한 해시값으로 매핑 예시. (ref: https://modeling-languages.com/robust-hashing-models/)

 

 

도입: 파이썬으로 자료를 저장하다보면 많은 양의 데이터를 저장해야하는 경우가 있다. 가령, 유전정보와 같이 1번 유전자의 100번째의 위치의 DNA가 바뀌었는지 여부 뿐만아니라... 101번, 10,000,000번째의 위치가 변경되었는지, 변경되었으면 무엇으로 변경되었는지 저장한다. 문제는 이렇게 많은 정보를 저장한 것을 읽어, 특정위치(Input으로 주어지는 위치)에 변이가 있었는지 찾아야한다면? 많은 연산을 해야할 것이다. 

 

 

 


해시란(hash)?

해시는 임의의 길이를 갖는 임이의 데이터를 고정된 길이의 데이터로 매핑하는 함수를 말한다. 쉽게 말해서, 입력값을 아무거나 넣더라도, 각기 다른 출력값을 반환하는 것이다(단, 출력값의 길이는 동일 // 입력값을 동일하게 할경우 출력값은 일관성 있게 동일). 예를 들어, 가장 쉬운 해시는 mod 연산이다. mod k 연산은 어떤 숫자를 k로 나눴을 때 나머지를 구하는 연산인데 이를 통해 해시를 구현할 수 있다. 아래의 예시와 같이 임의의 숫자 13, 3, 14, 23, 22를 7로 나눠 각각 나머지를 구했다. 이런식으로 각각 원소인 13을 6으로 매핑, 3을 3으로 매핑 14을 0으로 매핑하는 것처럼 원래 데이터를 매핑하는 것을 의미한다.

 

 

mod 7 (13) A -> G
mod 7 (3) G -> A
mod 7 (14) 0 T -> C
mod 7 (23) 2 C - > T
mod 7 (22) 1 C -> T

(Table 1. mod 7 연산의 결과)

 

 

 

그런 다음에, 6을 인덱스로 해서 "A->G"라는 데이터를 저장하고, 3에 "G->A"라는 것을 저장하듯 모든 배열을 위와같이 저장한다. 그러면, 14의 내용이 무엇인지 찾고자할때, 13, 3, 14, 23, 22의 중에 14를 찾아서 따라가는 것이 아니라, 1) 14을 mod 7 (14)을 해서, 0을 얻은다음, 2) 0의 인덱스에 무엇이 저장되어있는지 확인하면 된다. 이런 방법으로하면, 상당히 긴 배열에서도 13=14냐? 3=14이냐? 23이 23이냐?? 모두 1:1로 비교하는 방법(선형탐색)을 하지 않고, 바로 검색을 할 수 있다. 이 이유가 hash를 쓰는 이유이다. 

A -> G
G -> A
0 T -> C
2 C - > T
1 C -> T

 

 

그리고, 우리는 위의 6, 3, 0, 2, 1과 같은 값들을 해시값(hash value) 또는 다이제스트(Digest)라고 부르고, 해시값과 저장되어있는 값("A->G", "G-A"...)와 같이 위의 정보를 테이블형태로 저장하고 있는 자료구조를 해시테이블(hash table)이라고 한다.

 

 

 


Hash collision: 혹시나 해시값이 중복이면 어떻게되나?

 

해시충돌의 경우는 아래와 같다. 아래처럼 14의 값과 21을 해시함수 mod 7을 했을 경우 결과값(해시값)이 동일하다. 이 경우는 해시값이 중복인 경우 (예, 0인 경우), 14에서 부터 해시값이 나온건지 21에서부터 해시값이 0이 나온것인지 구분이 필요하다.

 

 

mod 7 (13) A -> G
mod 7 (3) G -> A
mod 7 (14) 0 T -> C
mod 7 (23) 2 C - > T
mod 7 (22) 1 C -> T
mod 7 (21) 0 T -> A

 

 

위의 예시만 봐도, 위의 mod 함수를 해시함수로 쓰는 경우 해시값(output)의 충돌은 발생한다. 가장 좋은 건 해시함수를 좋은 해시함수(결과물의 충돌이 거의 없는 함수)를 쓰는 것이 좋다. 그러나, 좋은 해시함수를 쓰더라도, 해시충돌이 발생할 확률은 언제나 존재한다. 이 원인에 대한 직관적인 이해는 비둘기집의 원리와 같다. 

 

비둘기집의 원리: "차량등록번호", "휴대전화번호"처럼 차량수/휴대전화가가 등록할수 있는 번호의 개수를 초과하는 경우와 같은 원리. 비둘기집이 9개가 있고, 각 비둘기집에는 한 마리씩 비둘기가 있을 수 있다고 가정해보자. 만일 비둘기가 10마리가 있다면 어떻게될까? 9개의 집 중, 하나는 두마리가 들어가야한다. 마찬가지로 "고정길이 문자열을 반환하는 해시값은 유한하다. 따라서, 임의의 가변길이 문자열의 개수 > 반환할 수 있는 고정길이 문자열이기에, 겹칠 수 있다"는 말이다. 예를 들어, 영어 알파뱃 26개인데 정보를 10개의 고정길이 문자열로 반환하는 해시함수를 만들었다고 하자. 해시함수가 반환할 수 있는 값은 26의 10제곱이다. 그러나 입력값을 0부터 ZZZZZZZZZZZZZZZZZZZZZ까지 엄청나게 많은 은 알파벳과 숫자의 조합이라면? 매핑할 수 있는 값의 종류가 모자르다.

 

Figure. Pigeons in holes.

자세한 내용은 아래를 참고하자 (https://en.wikipedia.org/wiki/Pigeonhole_principle)

따라서, 해시값이 충돌할 경우, 여러 방안이 존재한다. 체이닝, Open addressing (선형탐사, 제곱탐사, 이중해시).. 등 여러 방법이 존재한다. 가장 쉬운 예시는, 겹치는 해시값안에는 여러 변수를 일단 배열형태로 저장한 후에, 선형탐사하는 것이다. 일단 겹치는 경우, 저장하고 훨씬 적은 수를 선형탐사해서 찾겠다는 것과 같다.

 

 


Set, Dict 에서의 hash테이블: 파이썬의 set, dict자료구조는 해시테이블을 이용한다. 즉, dict의 key와 set의 원소를 x라한다면, hash(x)을 실행시켜 같으면 x원소가 반드시 존재한다는 것으로 활용할 수 있다. 아래는 set의 해시테이블을 직접 접근한 예시이다. 아래와 같이 파이썬의 내장함수는 해시함수를 제공하고 있다.

 

>>> hash
<function hash(obj, /)>

 

그리고, 파이썬의 객체는 hash함수값을 매직매서드로 가지고있다. 아래의 "a"라는 문자의 해시값은 "8870042888964940309"이다.

 

>>> "a".__hash__() 
8870042888964940309

 

그리고 set을 하나 만들어, 해시값을 소환해보자. set 내부에 해시테이블을 직접 접근하는 방법은 찾지 못했으나, 이와 유사하게 아래와같이 각 원소의 hash값을 알고있으면 이를 통해서 검색하면 매우 빠르다.

 

>>> myset = {"a", "b"}
>>> {element.__hash__() for element in myset}

{8703158610484096297, 8870042888964940309}

 

반응형

1. 지배구조
2019면에 코웨이홀딩스가 가지고 있다가, 웅진이 다시 사드렸고 2020년에 웅진이 어려워지면서 넷마블이 사들여, 넷마블이 최대주주가 되었다. 넷마블 입장에서는 엄청난 캐시카우가 들어온샘인데, 아래는 넷마블이 주장하는 코웨이와 넷마블의 시너지이다.

개인적인 평으로 할 수 있는게 매우 많진 않아보인다. AI 빅데이터 클라우드, 데이터분석은 툴이고(how), 어떤 가치를 더 주어서 고객이 지갑을 열지(what)이 없다.


코웨이 이하 연결대상 회사는 총 9개에서 12개로 늘었다. Coway japan, coway europe, 아이오베드라는 회사를 신규 출자해서 설립하거나, 인수하면서 총 12개가 되었다.

2. 회사의 신용도
회사의 신용도는 과거 2019년 A2+에서 2021년 8월 현재 AA-까지 계속 신용도가 상승하고 있다.


2. 메인 비지니스
방문판매업과먹는물관리법하에 정수기와 가정용 기기(여기서는 에어컨, 침대 등도 포함되는 모든 기기 인듯 하다)을 판매하고 있다.
2021년 6월말 현재 국내 기준 약 641만의 렌탈 및 멤버쉽 계정이 있는데, 가정뿐만아니라 법인등 매우 많은 렌탈기기 판매가 이뤄지고있다.

사업부문은 크게 3가지로 1) 렌탈, 2) 일시불, 3) 기타 부문으로 이뤄지고 있다. 무엇을 렌탈할지로 구분하는게 아니라 구독/비구독으로 사업부분을 나눠놓았다.

부품의 국산화에 성공하여 대부분 국내에서 조달하고 있으며, 필터 자동생산라인도 갖추고 있다고하는데, 주요 매입 원재료로는 PBA 아세이, 컴프레샤 등.. 유구공장, 인천공장, 포천공장 등에서 생산중이다.

현재는 국내뿐만 아니라 말레이시아, 미국, 중국, 태국, 인도네시아, 베트남, 일본, 유럽까지 사업영역을 확장하고있으며, 연결회사들이 사업확장에 따른 법인으로 보인다



코로나 19로, 말레이시아 사업확장에 브레이크가 걸린 코웨이. 다시 재동은?

 


성장동력은?

 


각사업부별 실적은?

 

 

 

반응형

문자나 숫자를 컴퓨터끼리 송수신하기위해서는 문자나 숫자를 그대로 전송하는 것이 아니라, 이러한 숫자나 문자를 비트단위로 끊어서 전송하게된다. 예를들어 숫자 3을 보내기 위해서는 0011으로 전송하게된다. 우리가 알고 있는 디지털신호(0아니면 1)로 변환해서 보내기 용히하기 때문이다. 이때, 숫자를 16진수로 보내면 최대 한 전송단위 16까지를 보낼수있다. 이렇게 한 전송단위(16비트)을 다시 2진수로 변환하여 송수신할 수 있다. 즉, 파이썬 내부에서 다뤄지는 문자열, 숫자는 파이썬에서 생성된 객체이고, 이를 바로 트랜스포트에 그대로 싣는 것은 안된다는 것이다.

따라서, 우리는 객체를 byte으로 적절히 인코딩을 해줘서 보내고, 컴퓨터는 이를 디지털신호로 바꿔 전송한후, 컴퓨터가 16진수는 숫자를 4bit단위로 끊어서, 인식하게 된다. 아래와 같이, 16진법 앞에는 "0x"을 붙여주어, 사용한다. 앞에 접두사로 "0x"을 붙이는 이유는 컴퓨터 입장에서는 0001을 이라는 디지털 신호가 왔을때, 이게 2진법인지 8진법으로 해석해야하는지 16진법으로 해석해야하는지 모르기 때문이다. "0x"은 16진수로 신호를 해석하라는 의미가 된다.

 

그 다음에 아래의 16진법 표기법과 같이, 해석을한다. 16진법에서는 컴퓨터가 받아들이는 입장에서는 "10"에서의 "1"과 "01"에서의 "1" 동일하기 때문에, "10"을 A로 표기한다. 그 이후에 11은 B, 12은 C... 15은 F까지 표기를한다. 

10진법 Hex(16진법) Binary
0 0x00 0000
1 0x01 0001
2 0x02 0010
3 0x03 0011
4 0x04 0100
5 0x05 0101
6 0x06 0110
7 0x07 0111
8 0x08 1000
9 0x09 1001
10 0x0A 1010
11 0x0B 1011
12 0x0C 1100
13 0x0D 1101
14 0x0E 1110
15 0x0F 1111

 

Python 내부에서 이러한 구조체를 사용할 수 있게 내장함수가 구현되어있는데, stuct (structure)을 사용하면 구현할 수 있다. 예를 들어, 아래와 같이 5를 한 byte 사이즈로 표현하면 0x05가 될 것이고, 4개의 byte로 표현하면 0x가 4개로 이루어진 hexadecimal이 표현된다.

# hexadecimal.py
import struct

a = struct.pack('b', 5)
print(a)

b = struct.pack('i', 5)
print(b)

b'\x05'
b'\x05\x00\x00\x00'

 

아래와 같이 2개 이상의 문자또는 숫자를 보내야하는 경우에는 포맷에 그 크기에 맞춰 포맷팅을 보내면 된다. 그렇지 않으면 아래의 예시의 a와 같이 패킹을 할 수 없다. 5,5을 16진법으로 표현할 방법이 없기 때문이다. 

import struct

b = struct.pack('ii', 5, 5)
print(b)
# b'\x05\x00\x00\x00\x05\x00\x00\x00


a = struct.pack('b', 5, 5)
print(a)
# Traceback (most recent call last):
#   File "hexadecimal.py", line 3, in <module>
#     a = struct.pack('b', 5, 5)
# struct.error: pack expected 1 items for packing (got 2)
반응형

 

 

fixture 란?


단위 테스트를 위해서, fixture을 이용하면 사전에 미리 정의된 신뢰할만하고 일관성있는 테스트를 이용할 수  있다. fixture은 환경이나 데이터셋에 대해서도 테스트해볼 수 있다. 이 fixture은 "step"과 "data"을 정의하고 이 테스트를 

 

fixture을 이용한 서비스, 상태, 조작환경등이 인자(argument)을 통해 모두 접근가능하고, 각 fixture는 보통 파라미터를 지정해준다. 그리고 pytest을 이용할 때, 어떤 함수를 테스트할것인지 @pytest.fixture 와 같이 "@"데코레이터를 이용해서 설정할 수 있다.

 

@pytest.mark.parametrize(ids=?) 내 ids란?? 

parameterize로 전달해주는 파라미터에 대해서 string으로 각 아이디를 줄 수 있고, 이는 "-k"을 옵션을 이용해서 특별한 파라미터(케이스)에 대해서만 실행해볼 수도 있다.

 

@pytest.fixture(scope=??):


scope범위에 따라 데코레이터를 달아준 함수의 실행범위가 달라진다. 예를 들어, scope="function"인 경우는 데코레이터를 달아준 함수를 매번 call해서 사용하고, 소멸된다. 한편, scope="module"로 지정하면 ".py"파일 내에서는 무조건 1번만 생성된다. 한편 scope="session"인 경우는 최초 테스트 실행시 단 한번만 객체가 실행되며, 각 테스트에서 이 하나의 객체가 호출된다. 

Reference: https://velog.io/@gyuseok-dev/pytest-pytest.fixture

https://velog.io/@dahunyoo/Test-fixture-on-Pytest

 

yeild 사용


yield은 보통 제너레이터에서 lazy하게 데이터를 불러올떄 사용한다. pytest에서는 테스트 실해 후에 환경정리, 테스트 데이터들을 정리할 때 yield 을 이용할 수 있다. yield는 호출한 테스트케이스가 실행된 후 종료되어도 마지막까지 실행되게끔 해주는 키워드이다.

반응형

+ Recent posts