Co ma wspólnego niszczenie lasów z projektami IT? Istnieje bardzo ciekawe badanie odnośnie tego pierwszego zagadnienia, które powinno wymusić ciekawe przemyślenia odnośnie naszego IT - i co najważniejsze pokazać jasno, że kierunek samoorganizacji jest słusznym kierunkiem towarzysze!
Eksperyment był zorganizowany przez ekonomistkę Elinor Ostrom i odbył się w 1994 roku. Początek jest niepozorny :
- Mamy ośmiu studentów
- Każdy ma 25 żetonów (które mają być po eksperymencie zamienione na prawdziwe pieniądze)
- Żetony inwestować można na dwóch rynkach
- Rynek pierwszy oferuje stały mały zysk
- Rynek drugi jest ciekawszy. Inwestując w ten rynek zyskujemy wiele - ale jest jedno ale - im więcej osób inwestuje w ten rynek tym mniejszy zysk otrzymujemy, aż w pewnym momencie inwestycje zaczynają przynosić straty
Być może jeszcze nie widać naturalnego powiązania z gównem w projektach IT ale to nic nie szkodzi. Sytuację pomogą zrozumieć nam mamuty ( a w zasadzie ich mięso)
Jak się robiło projekty 10 000BC
Wesoła gromadka jaskiniowców liczy 5 osobników. Biegaja oni codziennie na polowanie i starają się kamieniem czy dzidą trafić mamuta. Nawet jeśli pomiędzy naszymi jaskiniowcami istnieją jakieś różnice w zdolnościach myśliwskich to i tak intuicyjnie wiedzą, że polując w grupie każdy z nich ma większe szanse zasnąć dziś z pełnym brzuchem.
Mamut jest dosyć nieprzewidywalny. Nie da się zrobić wykresu Gantta z planem polowania. Roadmapa też zbytnio się nie przydaje. W całym procesie jest dużo miejsca na przypadkowość i szczęście/nieszczęście. Tego dnia Mamuta upolował akurat Roman. Teoretycznie to Roman powinien dostać awans... znaczy największy kawał mięsa (całego mamuta i tak nie zje). Ale Roman jeszcze nie był na szkoleniu managerskim i intuicyjnie przeczuwa, że za jakiś czas to on będzie miał mniej szczęścia i będzie potrzebował pomocy swoich towarzyszy. Postanawia się równoprawnie podzielić mięsem (chociaż sam zatrzymał dla siebie kieł żeby mieć +5 do lansu we wiosce - 100tys lat później jego potomkowie będą w tym celu używać certyfikatów).
Pytanie czy Roman postępuje rozsądnie dzieląc się mięsem ze wszystkimi. Wiesiek już raz go uratował od głodu gdy ten miał skręconą nogę ale z sprawa z Bytomirem wygląda inaczej. Bytomir ostatnio jakośnic nie upolował. Niby coś tam biegał ale nic z tego nie wynikało. Roman ma dylemat czy robi aby na pewno dobrze dzieląc się mięsem z Boromirem. Ponieważ system karny jeszcze się nie rozwinął w wiosce Romana, więc nie wie on, że dylemat, który przeżywa to dylemat więźnia...
Dylemat więźnia - symulacja w scali
Jeśli ktoś nie słyszał to dylemat więźnia to coś takiego : Złapano dwóch więźniów - jeśli obydwoje milczą - dostają 6 miesięcy , jeśli obydwoje sypią - to dostają po 2 lata a jeśli jeden sypie a drugi milczy to ten co sypał wychodzi na wolność a milczący dostaje 5 lat.
\ | X | Y |
X | 6 miechów | 5 lat |
Y | 0 | 2 lata |
Więźniowie tak jak i nasi jaskiniowcy mogą przyjąć pewne taktyki. Poniżej mała wypocona symulacja w scali, która powinna pomóc zrozumieć pewne konsekwencje wyborów
class Caveman(val id: Int) {
private var value = 10;
def updateValue(addition: Int) = { value = value + addition }
override def toString = id + " : " + value
}
Każdy jaskiniowiec zaczyna grę z określoną ilością "wartości". Wartości będzie przybywać lub ubywać w zależności od przyjętej strategii interakcji. Zdefiniujmy dwa typy interakcji
abstract class Interaction() {
def result(otherResponse: Interaction): (Int, Int)
}
object Positive extends Interaction {
override def result(otherResponse: Interaction): (Int, Int) = {
otherResponse match {
case Positive => (2, 2)
case Negative => (-5, 5)
}
}
}
object Negative extends Interaction {
override def result(otherResponse: Interaction): (Int, Int) = {
otherResponse match {
case Positive => (5, -5)
case Negative => (-2, -2)
}
}
}
\ | Positive | Negative |
Positive | 2 | -5 |
Negative | 5 | -2 |
Więc jeśli obydwaj jaskiniowcy współpracują zyskują wartość 2. Jeśli obydwoje się próbują oszukać tracą 2. Zaś jeśli jeden wydyma drugiego to ten pierwszy otrzymuje nagrodę 5 a drugi karę -5. Jak więc zagrają nasi jaskiniowcy? Na początek mają do wyboru dwie strategie
abstract trait InteractionStrategy {
protected val interactionHistory = Map[Int, Interaction]()
val id: Int
def interact(other: InteractionStrategy): (Int, Int)
def interactionType(cavemanID: Int): Interaction
}
trait Naive extends InteractionStrategy {
override def interactionType(cavemanID: Int) = Positive
override def interact(other: InteractionStrategy): (Int, Int) = {
Positive.result(other.interactionType(this.id))
}
}
trait Aggresive extends InteractionStrategy {
override def interactionType(cavemanID: Int) = Negative
override def interact(response: InteractionStrategy): (Int, Int) = {
Negative.result(response.interactionType(id))
}
}
Strategia Naiwna zawsze oczekuje współpracy a strategia Negatywna zawsze chce wydymać partnera.
def main(args: Array[String]): Unit = {
val hungerValue = -1
val caveman1 = new Caveman(1) with Naive
val caveman2 = new Caveman(2) with Naive
val caveman3 = new Caveman(3) with Naive
val caveman4 = new Caveman(4) with Naive
val caveman5 = new Caveman(5) with Naive
val group = List(caveman1, caveman2, caveman3, caveman4, caveman5)
for (i <- 1 to 10; firstCaveman <- group; secondCaveman <- group if firstCaveman.id != secondCaveman.id) {
val interactionResult = firstCaveman.interact(secondCaveman)
firstCaveman.updateValue(interactionResult._1)
secondCaveman.updateValue(interactionResult._2)
firstCaveman.updateValue(hungerValue)
firstCaveman.updateValue(hungerValue)
}
group.foreach(println(_))
}
Uwagi i wnioski do sprawozdania
Na początek niech każdy jaskiniowiec reprezentuje naiwną strategię - zaczynamy od wartości=10.
1 : 90 2 : 90 3 : 90 4 : 90 5 : 90
Całkiem nieźle - w trakcie 10 rund i interakcji każdego z każdym nasi jaskiniowcy zyskali po 80 jednostek wartości. No ale co gdy w końcu pojawi się ktoś kto zechce dymać frajerów?
val caveman1 = new Caveman(1) with Naive val caveman2 = new Caveman(2) with Aggresive val caveman3 = new Caveman(3) with Naive val caveman4 = new Caveman(4) with Naive val caveman5 = new Caveman(5) with Naive 1 : -50 2 : 330 3 : -50 4 : -50 5 : -50
No i wydymał ich - koniec snów o Utopii - co się stanie jak coraz więcej osób przyjmie taką postawę?
val caveman1 = new Caveman(1) with Naive val caveman2 = new Caveman(2) with Aggresive val caveman3 = new Caveman(3) with Naive val caveman4 = new Caveman(4) with Aggresive val caveman5 = new Caveman(5) with Naive 1 : -190 2 : 190 3 : -190 4 : 190 5 : -190
Frajerzy są coraz bardziej dymani ale z drugiej strony cwaniacy muszą się dzielić zyskiem. A co gdy każdy przycwaniaczy?
val caveman1 = new Caveman(1) with Aggresive val caveman2 = new Caveman(2) with Aggresive val caveman3 = new Caveman(3) with Aggresive val caveman4 = new Caveman(4) with Aggresive val caveman5 = new Caveman(5) with Aggresive 1 : -230 2 : -230 3 : -230 4 : -230 5 : -230
Nasza populacja wymarła. Okazuje się, że bycie kimś naiwnym opłaca się gdy wszyscy są naiwni. Z drugiej strony bycie cwaniakiem opłaca się najbardziej wśród frajerów. Miałem kiedyś kolegę, który jeździł na mecze i napierdalał kogo się da. Opowiadał, że raz na meczu pucharowym grali gdzieś na wsi i tam miejscowi przywitali ich z uśmiechem chlebem i solą na zawodach. No i ci z widzewa się cieszyli, że w 20 wpie***olili tam 100 osobom. Etyka postępowania była zakorzeniona tak w jednych jak i w drugich. Wielu ludzi, którzy ustanawiają procedury w korporacjach błędnie zakładają, że ludzie przyjmują strategie logicznie i świadomie - dlatego procesy i procedury lubią nie działać - ale o tym za chwilę. Zobaczmy inną ciekawą strategię.
Tit for tat
Tit for tat w spełnia jedno prawoo - "czyń bliźniemu swemu co on tobie uczynił" - w kodzie to będzie wyglądało mniej więcej tak :
trait TitForTat extends InteractionStrategy {
override def interactionType(cavemanID: Int): Interaction = {
interactionHistory.get(cavemanID).getOrElse(Positive)
}
override def interact(response: InteractionStrategy): (Int, Int) = {
val otherInteraction = response.interactionType(id)
val interactionResult = interactionType(response.id).result(response.interactionType(id))
interactionHistory.put(response.id, otherInteraction)
interactionResult
}
}
Tutaj kod robi się bardziej skomplikowany (chociaż nie wiem czy tylko dlatego, że strategia jest bardziej złożona czy dlatego, że dopiero raczkuję w scali). Tutaj nie ma przebaczenia - pamiętamy co nam zrobili inni i odwdzięczamy się im tym samym. Strategia wydaje się być idealna - będziemy niszczyć cwaniaków i współpracować z tymi, którzy chcą współpracować. Zobaczmy.
val caveman1 = new Caveman(1) with Naive val caveman2 = new Caveman(2) with TitForTat val caveman3 = new Caveman(3) with Naive val caveman4 = new Caveman(4) with Naive val caveman5 = new Caveman(5) with Naive 1 : 90 2 : 90 3 : 90 4 : 90 5 : 90
To było do przewidzenia - wszyscy współpracują
val caveman1 = new Caveman(1) with Naive val caveman2 = new Caveman(2) with TitForTat val caveman3 = new Caveman(3) with Naive val caveman4 = new Caveman(4) with Aggresive val caveman5 = new Caveman(5) with Naive 1 : -50 2 : 7 3 : -50 4 : 197 5 : -50
Cwaniak ma się dobrze ale TitforTat przetrwał jednocześnie wspierając współpracę.
val caveman1 = new Caveman(1) with TitForTat val caveman2 = new Caveman(2) with TitForTat val caveman3 = new Caveman(3) with Naive val caveman4 = new Caveman(4) with Aggresive val caveman5 = new Caveman(5) with TitForTat 1 : 7 2 : 7 3 : -50 4 : -62 5 : 4
Przy trzech TitforTat cwaniak został spacyfikowany ale nie ma jeszcze widocznego zysku. Zwiększmy trochę gromadę.
val caveman1 = new Caveman(1) with TitForTat val caveman2 = new Caveman(2) with TitForTat val caveman3 = new Caveman(3) with TitForTat val caveman4 = new Caveman(4) with Aggresive val caveman5 = new Caveman(5) with TitForTat val caveman6 = new Caveman(6) with TitForTat val caveman7 = new Caveman(7) with TitForTat val caveman8 = new Caveman(8) with TitForTat 1 : 67 2 : 67 3 : 67 4 : -333 5 : 64 6 : 64 7 : 64 8 : 64
No i cwaniak jest totalnie zmasakrowany a grupa kwitnie. Gdzie jest haczyk? haczyk jest w tej linijce kodu :
Ta implementacja TitForTat zakłada optymistyczny początek - a co jeśli np. zaczynamy z kimś współpracę i źle odczytamy jego intencje?
val caveman1 = new Caveman(1) with TitForTat val caveman2 = new Caveman(2) with TitForTat val caveman3 = new Caveman(3) with TitForTat val caveman4 = new Caveman(4) with Aggresive val caveman5 = new Caveman(5) with TitForTat val caveman6 = new Caveman(6) with TitForTat val caveman7 = new Caveman(7) with TitForTat val caveman8 = new Caveman(8) with TitForTat 1 : -410 2 : -410 3 : -410 4 : -410 5 : -410 6 : -410 7 : -410 8 : -410
Totalna rozpierducha. Czy można coś dalej z tym zrobić? Przydałoby się dać jakoś druga szansę spróbować szukać porozumienia. Okazuje się, że istnieje dosyć prosta strategia, która jest w stanie przeskoczyć ten problem ale istnieje też jeden mały warunek...
Entering Pavlov
Z tego co zrozumiałem chodzi o innego Pavlova niż tego do psa. Idea strategi Pavlova jest prosta - jeśli nie zyskałeś nic w tej interakcji to następnym razem spróbuj czegoś innego.
Taktyka wygląda tak (TitforTat cały czas ustawione na negatyw) :
trait Pavlov extends InteractionStrategy {
override def interactionType(cavemanID: Int): Interaction = {
interactionHistory.get(cavemanID).getOrElse(Negative)
}
override def interact(response: InteractionStrategy): (Int, Int) = {
val otherInteraction = response.interactionType(id)
val myInteraction = interactionType(response.id)
val interactionResult = interactionType(response.id).result(response.interactionType(id))
updateHistory(response, myInteraction, interactionResult)
interactionResult
}
def complementaryInteraction(interaction: Interaction) = {
interaction match {
case Positive => Negative
case Negative => Positive
}
}
private def updateHistory(response: InteractionStrategy, myInteraction: Interaction, interactionResult: (Int, Int)): Option[com.wlodar.virtues.Interaction] = {
if (interactionResult._1 > 0)
interactionHistory.put(response.id, myInteraction)
else
interactionHistory.put(response.id, complementaryInteraction(myInteraction))
}
}
val caveman1 = new Caveman(1) with TitForTat val caveman2 = new Caveman(2) with TitForTat val caveman3 = new Caveman(3) with TitForTat val caveman4 = new Caveman(4) with Pavlov val caveman5 = new Caveman(5) with TitForTat 1 : -155 2 : -155 3 : -155 4 : 34 5 : -151
Nie zadziała to tylko w jednym przypadku - jeśli TitForTat nie zajęły się cwaniakami
val caveman1 = new Caveman(1) with Pavlov val caveman2 = new Caveman(2) with Aggresive val caveman3 = new Caveman(3) with Pavlov val caveman4 = new Caveman(4) with Pavlov val caveman5 = new Caveman(5) with Pavlov 1 : -197 2 : 50 3 : -187 4 : -177 5 : -167
Między podsumowanie
Wygląda na to, że najlepiej dla grupy będzie gdy najpierw odpowiednia liczba osób przyjmie strategie TitForTat by wyeliminować cwaniaków a następnie zmienią rolę na bardziej "pro-współpracującą".
Ok co mamy :
- Eksperyment z żetonami - do tego jeszcze wrócimy
- Podział dóbr wspólnych stanowił podstawę przetrwania struktur pierwotnych
- W przypadku interakcji możemy przyjąć wiele strategii - to co tutaj opisałem to jedynie amatorskie muśnięcie po teorii gier
- Wraz z ewolucja systemu zmienia się skuteczność poszczególnych ról
Cialdini i Teoria wpływu na ludzi
http://lubimyczytac.pl/ksiazka/66811/wywieranie-wplywu-na-ludzi-teoria-i-praktyka - to pozycja, którą podnieca się masa wanna-be managerów od pralek wydobywających z niej pseudotechniki wpływu i pseudo-zarzadzania. Co nie zmienia faktu, że książka jest w istocie swoistą skarbnicą wiedzy psychologicznej. Pamiętam kiedy pierwszy raz ja przeczytałem miałem tzw. moment "brainfuck" - "Jakim to ku*wa prawem moje zachowania kontrolują jakieś instynkty?".
A jednak. Książka porusza kilka ciekawych "praw" (zasada autorytetu - to trzeba zneutralizować jak najszybciej jeśli chce się eksplozji kreatywności w zespole). Jednym z nich jest Zasada wzajemności - która to tłumaczy dlaczego w tesco stoją sobie młode laski zapraszając na degustację. Jednym ze słynnych przypadków wspomnianych w książce jest akcja Hari kriszna (czy jak to się tam pisze) z dawaniem kwiatków na lotnisku i oczekiwaniem w zamian datku. Co by nie mówić zasada wzajemności a w zasadzie zasada współpracy jest zakorzeniona w ludziach i więle technik manipulacyjnych ją wykorzystuje.
Zresztą nie tyczy się to tylko ludzi. W książce "Origins of virtue", której okładka powinna być widoczna po lewej stronie, znajduje się masa przykładów ze świata zwierząt. Nietoperze, które pamiętają jaki osobnik podzielił się z nimi jedzeniem, poprzez małpy wchodzące w sojusze a kończąc na delfinach. I to jest ciekawy przykład zawarty w książce bo według autora istnieje podgatunek delfina o bardzo rozwiniętej strukturze społecznej (i relatywnie rozwiniętym mózgu). Osobniki tego gatunku nie tylko pamiętają, które jednostki z nimi dobrze współpracowały ale generalnie które grupy jako takie przysłużyły im się pomocą. A wynik współpracy też jest ciekawy bo polega na pomocy przy porywaniu i gwałceniu samic delfinów. To taki ukłon w kierunku tych co to mówią, że ludzie są źli a królestwo zwierząt to utopia.
Ok czyli mamy taki oto obraz : współpraca to naturalny stan grupy ale co jakiś czas pojawi się cwaniak ze strategią eksploatacji zasobów grupy. I ludzie wymyślili prawo aby temu przeciwdziałać - czy prawo działa? Na pewnow pewnych przypadkach może działać lepiej.
Cwaniak aka Free Rider aka Wesoły Czesiek i problem "wspólnego pastwiska"
W 1968 niejaki ekolog Garrett Hardin opisał następujący problem - mamy ogólnie dostępne pastwisko - gdy każdy z mieszkańców wsi będzie maksymalizował swój zysk i wypasał wszystkie swoje krowy to trawa nie odrośnie i wszyscy stracą. W tym przypadku najlepiej wyjdzie jedna osoba, która łamie reguły podczas gdy inni ich przestrzegają.
Więc może ustalić odgórne prawa, które będą przestrzegane i wszystko będzie super. Jedna osoba wypasa jedną krowę i już. I dupa - zdjęcie obok przedstawia przykład przestrzegania prawa. To okolice dworca PKP Widzew. Generalnie tam leży masa śmieci i jakoś ludzie mają w dupie prawo. I może jakieś trole beda mówić, ze to tylko w Polsce ale wspomniana na samym początku Elinor Ostrom twierdziła inaczej. (Zresztą w książce "Origins of virtue" można znaleźć masę przykładów z całego świata jak nacjonalizacja dóbr wspólnych doprowadziła do ich masowej eksploatacji)
Przypomnijmy zasady eksperymentu :
- Mamy ośmiu studentów
- Każdy ma 25 żetonów (które mają być po eksperymencie zamienione na prawdziwe pieniądze)
- Żetony inwestować można na dwóch rynkach
- Rynek pierwszy oferuje stały mały zysk
- Rynek drugi jest ciekawszy. Inwestując w ten rynek zyskujemy wiele - ale jest jedno ale - im więcej osób inwestuje w ten rynek tym mniejszy zysk otrzymujemy, aż w pewnym momencie inwestycje zaczynają przynosić straty
Jest to symulacja eksploatacji pastwiska. Gdy tylko jedna osoba to robi zyskuje ale gdy więcej osób zaczyna brać w tym udział tracą wszyscy. Eksperyment był bardzo ciekawy i można o nim sobie poczytać więcej :
- Gdy studenci inwestowali niezależnie bez komunikacji - osiągnęli 21% możliwego zysku
- Gdy pozwolono im się komunikować 55% - przy jednej komunikacji , 73% - przy nielimitowanej komunikacji
- 37% - gdy zabroniono komunikacji ale postawiono jakieś odgórnie narzucone zasady karania free riderów- czyli tych którzy ciągle inwestowali w drugi rynek
- I uwaga! Gdy studenci mogli komunikować się dowolnie i mieli możliwość opracowania swoich własnych zasad kar - 93%!
Wnioski dla IT
I teraz poprzez analogię. Mamy sobie projekt IT, który jest oficjalnie własnością firmy. Firma sankcjonuje prawa, które są tak naprawdę ogólnikami "dbać o jakość", "dbać o dobro projektu". Można kontrolować każdy aspekt życia projektu podobnie jak można patrolować 24/7 każdy hektar lasu policyjnym helikopterem. Ani jedno ani drugie nie jest efektywne.
Przekazanie teamowi własności do projektu (oczywiście nie prawnej własności ale wykonawczej - czyli jakiej użyć technologii, jakiego repo itd) to początek. Inną kwestia jest edukacja. Jeśli np. Mamy populację kaczek, która jest traktowana jako własność lokalnej społeczności i faktycznie społeczność się nią opiekuje ale nie wie, że kaczek nie można karmić chlebem (słyszałem, że to im pęcznieje tam w brzuchu i zdychają) to pomimo, że każdy wykazuje strategię dobra ogółu to dojdzie do tragedii poprzez brak wiedzy. Podobnie gdy np. team nie rozumie konsekwencji wyboru konkretnej technologii wtedy potrzebuje zewnętrznej wiedzy - ale nie mylić tego z zewnętrznym kontrolowaniem!
To trochę tak jak przypadek kolesia, o którym ostatnio czytałem. Nie pamiętam nazwiska ale generalnie chodziło o to, ze w latach 70 poprzedniego wieku pojechał do wietnamu edukować ludzi w zakresie racjonalnego żywienia. Zamiast narzucać rozwiązania znalazł rodziny, które już być może nieświadomie respektowały reguły poprawnego żywienia i zadbał o to aby poprzez te rodziny odbyła się edukacja większej populacji. W korpo to by odbyło się poprzez zwołanie meetingu i wystosowanie nowych praw i regulaminów co w praktyce średnio działa. Kiedyś był u nas koleś, który chciał na siłę wprowadzić scalę - jedyne co mu się udało to skutecznie obrzydzić każdemu ten język. Kluczem tutaj jest racjonalna edukacja a nie nacisk.
Przekazanie mocy zespołowi może rozwiązać problem free riderów w grupie - czyli takich małych opierdalaczy gdy team pracuje - (no chyba, że wszyscy są nerdami jaskiniowymi i pojawi się jeden cwaniaczek z wysokim EQ - problem jaki może wyniknąć w przypadku tzw. zjawiska naturalnego lidera). Problem gdy grupa działa w narzuconej strukturze hierarchii i free riderem okaże się tzw manager czy tzw. lider. Tutaj nawet nie chodzi o opierdalanie się ale o maksymalizowanie zysków własnych kosztem grupy. Czyli np. wymuszanie na ludziach napieprzania po nocach dla realizacji jakiegoś nierealnego deadlinu. Manager ma premie, kod jest zjebany a ludzie wypaleni - jeśli to nie jest projekt z cyklu "tych złotych" to długookresowo firma traci.
Świetne! Bardzo dobrze poukładane sylogizmy - ciekawa konstrukcja wywodu. Ma sens! Kupuję :)
OdpowiedzUsuńOsobiście język mnie trochę drażni, ale już taka to uroda - nie każdemu się musi podobać.
A ja się nauczyłem nowego słowa - Sylogizm ;)
OdpowiedzUsuń