카레볶음밥
2020년 방영되었던 예능프로 '신서유기8'에서는 야식을 걸고 퀴즈를 푸는 코너가 있었다.
출연자는 종이를 뽑아 문제를 확인하고, 맞히면 원하는 메뉴를 얻는다.
틀리면 벌칙을 받는다.
참여 여부는 자유다.
인간의 보편적 가치를 건 아주 단순하고도 잔인한 방식이었다.
이날, 한 출연자가 뽑은 난이도 '상'의 문제가 등장한다.
"유튜브에서 전 세계 이용자들의 개별 특성을 분석해 좋아할 만한 영상을 자동으로 제공해 주는 이것은?"
문제를 듣자마자 그는 이게 왜 난이도 상이냐는 듯, 한껏 으쓱한 표정으로 외쳤다.
"알고리즘!"
"정답!"
PD의 선언과 동시에 야식 메뉴가 트로피처럼 출연자 손으로 이동했다.
그 출연자가 문제의 난이도가 '상'이라는 것에 고개를 갸웃했던 것은 자연스러웠다.
이미 '알고리즘'이라는 단어가 이미 일상어처럼 쓰이고 있었기 때문이다.
추천 목록에 뜬 영상을 하나만 보려다 밤을 새운 이유는 알고리즘에 낚였다는 말 한마디면 충분했다.
아무도 일부러 검색할 것 같지 않은 영상이 수십만 조회 수를 찍고 있으면 댓글창에는 비슷한 말들이 줄지어 있었다.
"이걸 검색해 들어온 사람은 없겠지? 다 나처럼 알고리즘에 뜬 거겠지?"
그런데 나는 사람들이 '알고리즘'이라는 단어를 사용하는 모습을 보면서, 마치 새 옷 안쪽에 붙은 상표가 살에 스칠 때처럼 은근히 거슬리는 느낌을 받았다.
알고리즘이라는 말은 훨씬 포괄적인 의미를 가진 단어이기 때문이다.
알고리즘이란 어떤 문제를 해결하기 위한 절차이자 방법이다.
무언가를 입력으로 받아, 정해진 순서에 따라 처리하고, 그 결과를 출력으로 내놓는 일련의 과정이다.
그리고 문제의 종류가 다르면 알고리즘도 달라진다.
목적에 따라, 상황에 따라, 쓰임새에 따라 알고리즘은 끝없이 나뉜다.
예를 들어 내비게이션을 떠올려보자.
출발지와 목적지를 입력하면 가장 빠른 길과 예상 소요 시간을 알려준다.
이때 사용되는 것은 최단거리 알고리즘이다.
반면 유튜브나 넷플릭스는 길을 안내하지 않는다.
사람의 취향을 더듬는다.
내가 무엇을 봤는지, 얼마나 오래 봤는지, 무엇을 검색했는지, 새벽 두 시에도 집중해서 봤는지 같은 데이터를 모아 아마 이걸 좋아할 것 같다는 결과를 내놓는다.
이건 그냥 알고리즘이 아니라 '추천 알고리즘'이라고 부르는 편이 좋겠다.
그런데 이 모든 과정을 뭉뚱그려 그냥 알고리즘이라고 부르고 있었던 것이다.
그건 마치 그림을 '그리는 것을 생업으로 하는 직업은 무엇인가'라는 질문에 '화가'가 아니라 '예술가'라고 답하는 것과 비슷하다.
틀린 말은 아니다.
다만, 너무 넓고, 너무 추상적이었다.
컴퓨터과학에서 알고리즘을 배우기 시작하면, 초반에 만나게 되는 개념 중 하나가 그리디 알고리즘이다.
우리말로 옮기면 탐욕 알고리즘, 욕심쟁이 알고리즘쯤 된다.
방식은 아주 단순하다.
매 순간 그때그때 가장 좋아 보이는 선택을 하며 앞으로 나아간다.
길게 고민하지 않는다.
지금 이 순간만 놓고 보면 최선이라고 생각되는 쪽을 고른다.
예를 들어 이런 문제를 떠올려보자.
어떤 금액이 주어졌을 때, 가장 적은 수의 동전으로 그 금액을 만드는 방법을 계산하는 것이다.
만들어야 할 금액이 1,000원이라면 어떨까.
사람이라면 잠깐도 고민하지 않는다.
500원짜리 두 개.
끝이다.
하지만 컴퓨터에게 이 문제를 풀도록 시키는 일은 전혀 다른 차원의 이야기다.
우선 동전이 무엇인지부터 설명해야 한다.
10원, 50원, 100원, 500원 같은 동전의 종류가 있다는 것도 하나하나 알려줘야 한다.
하다못해 저 10, 50, 100, 500이라는 것이 숫자라는 사실조차 설명해야 한다.
인간에게는 상식인 것들이, 컴퓨터에게는 모두 정의와 선언, 그리고 설명의 대상이 된다.
그 모든 준비가 끝났다고 하자.
그리디 알고리즘은 그 순간 가장 좋아 보이는 선택을 한다.
1,000원보다 작으면서 가장 값이 큰 동전 하나를 고른다.
500원이 선택되고, 남은 금액은 500원이다.
다시 한번 같은 판단을 한다.
지금 이 순간 가장 좋아 보이는 선택은 또 500원이다.
그렇게 두 개의 동전으로 1,000원이 만들어지고, 알고리즘은 멈춘다.
과정은 단순하고, 결과도 깔끔하다.
그런데 그리디 알고리즘에는 분명한 한계가 있다.
조금 그럴듯하게 말하면, 부분적으로 좋아 보이는 선택이 항상 전체에서도 좋은 선택은 아닐 수 있다는 것이다.
다시 동전 이야기로 돌아가 보자.
이번에는 700원짜리 동전이 있다고 가정해 보자.
그리디 알고리즘은 1,000원을 만들어야 하니, 역시나 그보다 작으면서 가장 큰 동전부터 집는다.
700원.
남은 금액은 300원이다.
이제 다시 같은 판단을 한다.
300원을 만들기 위해 100원을 고르고, 또 100원을 고르고, 마지막으로 100원을 하나 더 고른다.
결국 동전은 네 개.
그리디 알고리즘은 이것이 최선이라고 말한다.
최적화에 실패한 셈이다.
이럴 때 등장하는 것이 다이나믹 프로그래밍, 우리말로 하면 동적 계획법이다.
이 알고리즘은 매 순간의 선택만 보지 않는다.
가능한 경우들을 나눠서 살펴보고, 그 결과를 다시 모아 전체에서 가장 좋은 답을 찾아낸다.
조금 더 복잡하고, 계산도 오래 걸린다.
대신 700원짜리 동전이 있든, 120원짜리 동전이 새로 등장하든, 상황이 바뀌어도 가장 좋은 답을 찾아낸다.
그렇다면 여기서 이런 질문이 생긴다.
그리디 알고리즘은 별로인 알고리즘일까?
그렇지 않다.
그리디 알고리즘은 그리디 알고리즘이 잘 어울리는 자리가 있다.
우리나라 동전 체계를 떠올려보자.
700원짜리 동전은 없다.
이런 세상에서는 굳이 복잡한 계산을 할 이유가 없다.
거스름돈을 계산하는 데 그리디 알고리즘만으로도 충분하다.
괜히 계산이 오래 걸리고 머리 아픈 방법을 쓸 필요가 없는 것이다.
다만, 700원짜리 동전이 존재하는 세상이라면 조금 더 복잡한 알고리즘이 필요해질 뿐이다.
문제는 알고리즘의 우열이 아니라, 어디에 어떻게 어떤 알고리즘을 쓰느냐에 있다.
나는 동적 계획법이라는 알고리즘을 중학생 때 처음 알았다.
알고리즘 대회에 나가 문제를 풀다 보면 자주 사용하게 되는 방식이었다.
처음엔 복잡해 보였지만, 한 번 익숙해지면 꽤 믿음직한 친구가 된다.
그런데 내가 동적 계획법을 가장 반갑게 다시 만난 순간은 알고리즘 대회장이 아니라 대학원 거시경제학 강의실이었다.
그 수업에서 복잡한 수식과 영어로 적혀있던 문제는 결국 이런 질문으로 귀결됐다.
'매달 버는 소득 가운데 얼마를 쓰고, 얼마를 남겨두는 게 내 인생 전체에서 가장 만족스러운 선택일까'
지금 번 돈을 전부 써버리면 당장은 행복할 수 있다.
대신 미래는 조금 가벼워진다.
반대로 지금을 참고 투자하면 언젠가는 더 큰 행복이 돌아올지도 모른다.
그렇다고 모든 돈을 투자에 쏟아붓다가는 행복을 느끼기도 전에 배부터 고파질 가능성이 크다.
그래서 이걸 계산해 보자는 것이다.
동적 계획법을 쓰면 시험지 위에서는 답이 나온다.
언제 얼마를 쓰고, 언제 얼마를 남기면 좋을지, 꽤 그럴듯한 수식들이 줄줄이 적힌다.
그런데 이걸 정말 현실에서 그대로 쓸 수 있을까.
불가능에 가깝다.
우리는 내가 언제까지 살지, 지금의 소득이 언제까지 이어질지, 투자가 항상 잘될지 알지 못한다.
문제를 풀기 위해서는 이 모든 미래의 것들에 대해 가정을 세워야 한다.
당연하게도 가정 위에 세운 답은 현실에서는 정답이 되기 어렵다.
거슬러 줘야 할 돈이 1,000원인지 1,400원 인지도 모르는데 동전의 개수를 최적화할 수는 없지 않은가.
인생은 시험지가 아니어서 동적 계획법을 적용할 수 없다.
자주 만들던 카레 볶음밥을 만들었다.
특별히 먹고 싶은 요리가 떠오르지 않을 때, 머리를 쓰고 싶지 않을 때, 빠르게 한 끼를 해결하고 싶을 때 찾게 되는 요리다.
고기와 당근, 호박, 감자를 잘게 다져 팬에 올린다.
달궈진 팬에서 기름이 돌고, 재료들이 익어가며 제각각의 소리를 낸다.
고기는 고기대로, 채소는 채소대로 서로를 의식하다가 어느 순간부터는 같은 냄새를 풍긴다.
그 타이밍에 밥을 넣는다.
거기에 굴소스를 한 바퀴 두르고 카레 가루를 뿌린다.
조금 더 볶아주면 끝이다.
레시피랄 것도 없는, 그래서 실패할 일이 거의 없는 요리다.
아내와 함께 접시를 나눠 담고 나란히 앉아 한 숟갈씩 떠먹었다.
그런데 첫 숟갈에서부터 둘 다 잠깐 멈췄다.
맛이 없다기보다는, 뭔가가 확실히 미완의 맛이었다.
어디가 문제인지 딱 짚을 수는 없지만 분명 예전과는 달랐다.
원인을 찾기 시작했다.
밥이 조금 질었나.
카레 가루를 너무 아꼈나.
굴소스를 넣었다고 생각했는데 혹시 두르지 않고 지나친 건 아닐까.
숟가락을 오가며 이유를 찾으려 애썼지만 명확한 답은 나오지 않았다.
못 먹어줄 맛은 아니었기에 결국 우리는 식사를 마쳤다.
다만 조금은 말수가 줄어든 채로.
맛이 아쉬운 날의 식탁은 대체로 그런 분위기를 만든다.
요리라는 것도 결국은 일종의 알고리즘에 따라 진행된다.
그 알고리즘을 우리는 레시피라고 부른다.
재료를 넣는 순서가 있고, 불의 세기가 있고, 기다려야 할 시간이 있다.
입력과 과정, 그리고 결과가 분명하다.
딱 알고리즘의 정의에 들어맞는다.
그런데 이상한 일은 그다음에 벌어진다.
레시피를 그대로 따라 했는데도 사람마다 전혀 다른 요리가 나온다.
늘 같은 재료, 늘 같은 순서, 늘 같은 방식으로 만들어도 결과는 달라질 수 있다.
같은 레시피를 쥐여주고 백 명의 요리사에게 요리를 시키면 백 개의 요리가 나온다고 한다.
심지어 한 명의 요리사가 같은 레시피로 요리를 해도 어떤 날은 유난히 맛있고, 어떤 날은 별로다.
불의 세기가 조금 달랐을 수도 있고, 재료의 컨디션이 달랐을 수도 있고, 요리사의 마음이 조금 덜 집중되어 있었을 수도 있다.
아니면 그냥, 그날이 그런 날이었을지도 모른다.
정해진 레시피를 따르는 요리 하나만 놓고 봐도 이렇게 변수가 많은데, 어떻게 인생에서 매번 최고의 선택만 할 수 있겠는가.
우리는 매 순간, 지금 이 순간에서 가장 좋아 보이는 선택을 할 뿐이다.
최선을 다해 생각하고, 최선을 다해 욕심내고, 그마저도 어려울 때는 감에 의지하면서까지.
결국 우리는 완벽한 해답을 찾는 사람들이 아니라 지금 당장 가장 그럴듯한 선택을 이어가는 욕심쟁이들일지도 모른다.
그러니 지나간 선택이 후회된다 하여도 너무 오래 붙잡고 있을 필요는 없다.
그때는, 그것이 최선이었다.
아내의 후기
카레볶음밥
★3.9점
으... 오랜만에 짜디짠 점수라 셰프님께 죄송하네요.
남편이 가끔 해주던 카레 볶음밥은 늘 맛있었던 기억이 있는데, 오늘은 그 맛이 아니었어요.
카레 향도 애매하고, 밥알 상태도 애매하고, 전반적으로 참 애매꾸리한 요리였습니다.
신랑님의 생일인 3월 9일을 점수로 올립니다 ^^ 하하
P.S.
지난 글에 댓글로 제 일에 대해 위로와 응원을 보내주신 분들이 참 많았습니다.
하나하나 모두 읽으며 큰 힘을 얻었습니다.
진심으로 감사드립니다.
다행히 지원했던 새로운 부서에 합격해 이동이 확정되었습니다.
내일이면 새롭게 함께 일하게 될 동료들을 만나 첫인사를 나눌 것 같습니다.
뛰어난 분들이 많은 부서라고 들었습니다.
그 안에서 잘 해낼 수 있을지에 대한 걱정이 있지만, 원래 새로운 환경에 적응하는 일을 크게 두려워하는 편은 아니라 그 걱정이 마음을 짓누를 만큼 크지는 않습니다.
어쨌든 저는 잘 해낼 것이라 스스로를 믿습니다.
고개 숙여 다시 한번, 응원해 주신 모든 분들께 감사의 마음을 전합니다.