19. Деревья¶
Как и связные списки, деревья состоят из узлов. Широко известно бинарное дерево, каждый узел которого содержит ссылки на два других узла (либо None ). Эти ссылки указывают на левое и правое поддеревья. Как и узлы связных списков, узлы деревьев также содержат полезные данные. Следующая диаграмма представляет дерево:

Самый верхний узел дерева называется корнем. Ссылка на корень есть ссылка на все дерево. Развивая метафору с деревом, другие узлы называют ветвями, а конечные узлы, не имеющие ссылок на другие, — листьями.
(Возможно, вам кажется странным, что дерево нарисовано корнем вверх и листьями вниз? Но это не самое странное из того, что связано с деревьями.)
В отношении деревьев также используется метафора семьи. Поэтому узел, ссылающийся на другие, иногда называют родительским*, а узлы, на которые он ссылается — дочерними. Узлы, имеющие общего родителя, называют сестринскими.
И, наконец, говоря о деревьях, пользуются словами, обозначающими стороны и направления. Мы уже упомянули левое и правое поддеревья, но также имеются направления вверх (к родителям и корню) и вниз (к детям и листьям). А все узлы, находящиеся на одинаковым расстоянием от корня, составляют уровень дерева.
Подобно связным спискам, деревья также являются рекурсивными структурами, поскольку их определение рекурсивно. Дерево представляет собой:
- пустое дерево, представленное значением None , или
- узел, содержащий данные и ссылки на деревья.
В случае бинарного дерева, узел содержит две ссылки.
19.2. Построение деревьев¶
Построение дерева похоже на построение связного списка. Каждый вызов конструктора создает один узел.
class Tree: def __init__(self, cargo, left=None, right=None): self.cargo = cargo self.left = left self.right = right def __str__(self): return str(self.cargo)
Параметр cargo , представляющий данные, может быть любого типа, а параметры left и right должны быть узлами деревьев. left и right опциональны и имеют значения по умолчанию None .
Чтобы вывести на печать узел, будем выводить его данные, cargo .
Один из способов построить дерево — снизу вверх. Создадим вначале дочерние узлы:
left = Tree(2) right = Tree(3)
Затем создадим родительский узел и свяжем его с дочерними:
tree = Tree(1, left, right);
Можно записать этот код более компактно:
>>> tree = Tree(1, Tree(2), Tree(3))
В обоих случаях, мы получим дерево, изображенное на рисунке в начале главы.
19.3. Обход деревьев¶
Всякий раз, когда вы встречаетесь с новой структурой данных, первый вопрос, заданный вами, должен быть: как перебрать все элементы этой структуры? Наиболее естественный способ обойти дерево, посетив все его узлы, — рекурсивный. Например, если узлы дерева содержат целые числа в качестве данных, то следующая функция подсчитывает их сумму:
def total(tree): if tree == None: return 0 return total(tree.left) + total(tree.right) + tree.cargo
Базовый случай здесь пустое дерево, не содержащее данных; для него возвращается 0. На каждом шаге рекурсии делаются два вызова функции total для подсчета суммы дочерних деревьев. К сумме результатов рекурсивных вызовов добавляются родительские данные, и возвращается сумма.
19.4. Деревья выражений¶
Деревья естественным образом представляют структуру выражений. В отличие от других способов представления, дерево описывает порядок вычислений однозначно. Например, инфиксное выражение 1 + 2 * 3 неоднозначно, если не принять во внимание, что умножение является более приоритетной операцией, чем сложение.
Дерево на следующем рисунке представляет это выражение:

Узлами дерева, представляющего выражение, могут быть операнды, например, 1 и 2 , и операторы, + , * и другие. Операнды будут листьями, а узлы-операторы будут ссылаться на узлы-операнды. (Все используемые нами операторы являются бинарными, то есть, имеют ровно два операнда.)
Можно построить это дерево таким образом:
>>> tree = Tree('+', Tree(1), Tree('*', Tree(2), Tree(3)))
При взгляде на это дерево не возникает вопроса о порядке операций. Вначале выполняется умножение для того, чтобы вычислить второй операнд для сложения, и затем выполняется сложение.
Деревья выражений имеют многочисленные применения. Далее в этой главе деревья используются для того, чтобы переводить выражения в постфиксную, префиксную или инфиксную запись. Похожие деревья используются внутри компиляторов для синтаксического анализа, оптимизации и трансляции программ.
19.5. Обход дерева выражения¶
Мы можем обойти дерево выражения и вывести его на печать таким образом:
def print_tree(tree): if tree == None: return print tree.cargo, print_tree(tree.left) print_tree(tree.right)
Как видите, для вывода дерева на печать мы вначале выводим корень, затем левое поддерево, затем правое. Такой способ обхода дерева называется предупорядоченным обходом, или обходом в прямом порядке, потому, что родительский узел посещается перед посещением дочерних узлов. Выведем наше дерево на печать:
>>> tree = Tree('+', Tree(1), Tree('*', Tree(2), Tree(3))) >>> print_tree(tree) + 1 * 2 3
Такая форма записи выражения отличается и от постфиксной, и от инфиксной. Запись, в которой операторы предшествуют операндам, называется префиксной.
Вы, наверное, уже заподозрили, что при обходе дерева другим способом получится другая запись выражения. Так оно и есть. Например, будем выводить на печать поддеревья прежде их родителя:
def print_tree_postorder(tree): if tree == None: return print_tree_postorder(tree.left) print_tree_postorder(tree.right) print tree.cargo,
Результат, 1 2 3 * + , является постфиксной записью! Такой порядок обхода дерева называется поступорядоченным, или обходом в обратном порядке. В самом деле, вначале выводятся листья, в к конце — корень.
Наконец, для выполнения симметричного обхода нужно вначале вывести левое поддерево, затем его родителя, и затем правое дерево:
def print_tree_inorder(tree): if tree == None: return print_tree_inorder(tree.left) print tree.cargo, print_tree_inorder(tree.right)
Получам инфиксную запись выражения: 1 + 2 * 3 .
Если быть до конца честными, то нужно сказать, что мы допустили существенное упрощение. Иногда для записи инфиксных выражений нужно использовать скобки, чтобы сохранить порядок выполнения операций. Поэтому симметричный обход не всегда достаточен для генерации полноценного инфиксного выражения.
Тем не менее, после некоторой доработки, дерево выражений и его обход разными способами предоставляют средства для перевода выражений из одной формы в другую.
Если в процессе симметричного обхода дерева мы будем следить за тем, на каком уровне дерева находимся, мы сможем получить графическое представление дерева:
def print_tree_indented(tree, level=0): if tree == None: return print_tree_indented(tree.right, level+1) print ' ' * level + str(tree.cargo) print_tree_indented(tree.left, level+1)
Параметр level (англ.: уровень) сообщает нам, на каком уровне дерева мы находимся. Изначально он равен 0. Каждый раз, когда мы делаем рекурсивный вызов, мы передаем level+1 в качестве параметра, поскольку уровень дочернего узла всегда на 1 больше, чем уровень родительского. Данные узла при выводе на печать сдвигаются вправо пропорционально уровню. Получаем следующее:
>>> print_tree_indented(tree) 3 * 2 + 1
Если взглянуть на полученный вывод сбоку, можно увидеть подобие дерева, изображенного на рисунке выше.
19.6. Построение дерева выражения¶
В этом разделе мы выполним разбор инфиксных выражений и построим соответствующие им деревья. Например, выражение (3 + 7) * 9 даст нам следующее дерево:

Мы упростили рисунок, опустив имена атрибутов.
Синтаксический анализатор, или парсер, который мы напишем, будет работать с выражениями, включающими числа, скобки и операторы + и * . Будем исходить из предположения, что исходное выражение уже разбито на лексемы, которые помещены в список Python (получите этот список сами в качестве упражнения). Список лексем для выражения (3 + 7) * 9 следующий:
['(', 3, '+', 7, ')', '*', 9, 'end']
Лексема end играет роль ограничителя списка, предотвращая выход парсера за его границу.
Первая функция, которую мы напишем, это функция get_token , принимающая в качестве параметров список лексем и ожидаемую лексему. Функция сравнивает ожидаемую лексему с первой в списке. Если они равны, лексема удаляется из списка, и функция возвращает True . В противном случае возвращается False :
def get_token(token_list, expected): if token_list[0] == expected: del token_list[0] return True else: return False
Так как переменная token_list ссылается на изменяемый объект, сделанные в функции изменения доступны через любую переменную, ссылающуюся на тот же объект.
Следующая функция, get_number , работает с операндами. Если следующая лексема в списке token_list является числом, то get_number удаляет ее из списка и возвращает узел, содержащий это число. В противном случае возвращается None .
def get_number(token_list): x = token_list[0] if type(x) != type(0): return None del token_list[0] return Tree(x, None, None)
Прежде чем идти дальше, стоит протестировать функцию get_number . Присвоим список чисел переменной token_list , вызовем get_number и выведем на печать результат, а также то, что осталось в token_list :
>>> token_list = [9, 11, 'end'] >>> x = get_number(token_list) >>> print_tree_postorder(x) 9 >>> print token_list [11, 'end']
Следующая необходимая нам функция, это get_product (англ.: получить произведение), которая строит дерево для произведения. Простое произведение имеет два числа в качестве операндов, например, 3 * 7 .
Вот версия get_product для простых произведений.
def get_product(token_list): a = get_number(token_list) if get_token(token_list, '*'): b = get_number(token_list) return Tree ('*', a, b) else: return a
Предполагая, что get_number возвращает узел с первым операндом, присваиваем его переменной a . Если следующая лексема * , то получам второй операнд и строим дерево выражения с помощью a , b и оператора произведения.
Если же следующая лексема не * , то возвращаем узел-лист первого операнда, a . Приведем два примера:
>>> token_list = [9, '*', 11, 'end'] >>> tree = get_product(token_list) >>> print_tree_postorder(tree) 9 11 *
>>> token_list = [9, '+', 11, 'end'] >>> tree = get_product(token_list) >>> print_tree_postorder(tree) 9
Как видно из второго примера, единственный операнд рассматривается как своего рода произведение. Хотя это выглядит необычно, такой прием оказывается полезным.
А теперь возьмем более сложное произведение, например, 3 * 5 * 13 . Это выражение можно рассматривать как произведение произведений, а именно: 3 * (5 * 13) . Получаем следующее дерево:

Немного доработав get_product , мы сможем иметь дело с произведениями произвольной длины:
def get_product(token_list): a = get_number(token_list) if get_token(token_list, '*'): b = get_product(token_list) # this line changed return Tree('*', a, b) else: return a
Другими словами, произведение может быть либо деревом с единственным узлом, либо деревом с корнем * , дочерним узлом-операндом слева и дочерним узлом-произведением справа. Рекурсивные определения, подобные этому, уже должны казаться вам привычными.
Протестируем новую версию функции со сложным произведением:
>>> token_list = [2, '*', 3, '*', 5 , '*', 7, 'end'] >>> tree = get_product(token_list) >>> print_tree_postorder(tree) 2 3 5 7 * * *
А теперь реализуем синтаксический разбор сумм. И снова воспользуемся несколько неожиданным определением. Сумма для нас либо дерево с корнем + , дочерним узлом-произведением слева и дочерним узлом-суммой справа, либо дерево с единственным узлом-произведением.
Если вы приглядитесь к этому определению повнимательнее, то обнаружите замечательное свойство: мы можем представить любое выражение без скобок как сумму произведений. На этом свойстве основывается наш алгоритм синтаксического разбора.
Функция get_sum пробует построить дерево с дочерним узлом-произведением слева и дочерним узлом-суммой справа. Но если функция не обнаруживает + , она просто возвращает произведение.
def get_sum(token_list): a = get_product(token_list) if get_token(token_list, '+'): b = get_sum(token_list) return Tree('+', a, b) else: return a
Протестируем функцию с выражением 9 * 11 + 5 * 7 :
>>> token_list = [9, '*', 11, '+', 5, '*', 7, 'end'] >>> tree = get_sum(token_list) >>> print_tree_postorder(tree) 9 11 * 5 7 * +
Мы почти закончили, осталось только научиться работать со скобками. В любом месте выражения, где может быть число, может быть также сумма, заключенная в скобки. Изменим get_number так, чтобы обрабатывать подвыражения:
def get_number(token_list): if get_token(token_list, '('): x = get_sum(token_list) # get the subexpression get_token(token_list, ')') # remove the closing parenthesis return x else: x = token_list[0] if type(x) != type(0): return None token_list[0:1] = [] return Tree(x, None, None)
Протестируем этот код с выражением 9 * (11 + 5) * 7 :
>>> token_list = [9, '*', '(', 11, '+', 5, ')', '*', 7, 'end'] >>> tree = get_sum(token_list) >>> print_tree_postorder(tree) 9 11 5 + 7 * *
Наш парсер обработал скобки корректно, сложение выполняется перед умножением.
Финальной версии get_number было бы неплохо дать другое имя, лучше описывающее ее функциональность.
19.7. Обработка ошибок¶
До сих пор при разработке парсера мы полагали, что на вход поступают корректные выражения. Например, когда мы достигаем конца подвыражения, мы полагаем, что следующей лексемой будет закрывающая скобка. Однако, если это не так, программа должна справиться с ситуацией.
def get_number(token_list): if get_token(token_list, '('): x = get_sum(token_list) if not get_token(token_list, ')'): raise 'BadExpressionError', 'missing parenthesis' return x else: # the rest of the function omitted
Предложение raise создает исключение; в данном случае мы создаем новый вид исключения с именем BadExpressionError . Если функция, вызвавшая get_number , или другая функция в текущем стеке вызовов обрабатывает это исключение, то программа сможет продолжить работу. Иначе Python выведет сообщение об ошибке и завершится.
19.8. Дерево животных¶
В этом разделе мы разработаем небольшую программу, которая использует дерево для построения базы знаний.
Программа, взаимодействуя с пользователем, создает дерево вопросов и названий животных. Вот пример выполнения этой программы:
Are you thinking of an animal? y Is it a bird? n What is the animal's name? dog What question would distinguish a dog from a bird? Can it fly If the animal were dog the answer would be? n Are you thinking of an animal? y Can it fly? n Is it a dog? n What is the animal's name? cat What question would distinguish a cat from a dog? Does it bark If the animal were cat the answer would be? n Are you thinking of an animal? y Can it fly? n Does it bark? y Is it a dog? y I rule! Are you thinking of an animal? n
Вот дерево, которое строит этот диалог:

Каждый опрос программа начинает с корня дерева, и задает содержащийся в нем вопрос. В зависимости от ответа, программа переходит к левому или правому дочернему узлу и задает вопрос, содержащийся в этом узле. И так далее, пока не будет достигнут конечный узел-лист. Тогда программа высказывает догадку. Если эта догадка не верна, программа просит пользователя ввести название нового животного и вопрос, который позволит отличить это животное от животного, предложенного программой. Затем к дереву добавляется новый узел с вопросом и названием животного, введенными пользователем.
Вот код программы:
def yes(ques): ans = raw_input(ques).lower() return ans[0] == 'y' def animal(): # start with a singleton root = Tree("bird") # loop until the user quits while True: print if not yes("Are you thinking of an animal? "): break # walk the tree tree = root while tree.left != None: prompt = tree.cargo + "? " if yes(prompt): tree = tree.right else: tree = tree.left # make a guess guess = tree.cargo prompt = "Is it a " + guess + "? " if yes(prompt): print "I rule!" continue # get new information prompt = "What is the animal's name? " animal = raw_input(prompt) prompt = "What question would distinguish a %s from a %s? " question = raw_input(prompt % (animal, guess)) # add new information to the tree tree.cargo = question prompt = "If the animal were %s the answer would be? " if yes(prompt % animal): tree.left = Tree(guess) tree.right = Tree(animal) else: tree.left = Tree(animal) tree.right = Tree(guess)
Вспомогательная функция yes печатает приглашение и принимает ввод пользователя. Если ответ пользователя начинается с y или Y, то функция возвращает True .
Условием внешнего цикла в функции animal является True . Это значит, что цикл будет продолжаться до тех пор, пока не выполнится предложение break (в случае, когда пользователь не задумал животное).
Во внутреннем цикле while происходит перемещение по дереву от корня к листьям, управляемое ответами пользователя.
Когда к дереву добавляется новый узел, текущий узел получает новый вопрос и два дочерних узла: один с новым животным и один с оригинальным (первоначальным) вопросом.
Недостаток этой программы в том, что когда она завершается, она забывает обо всем, чему вы ее научили! Решите эту проблему в качестве упражнения.
19.9. Глоссарий¶
бинарный оператор Оператор, требующий два операнда. бинарное дерево Дерево, каждый узел которого ссылается на ноль, один или два дочерних узла. дочерний узел дерева Узел, на который ссылается родительский узел. корень дерева Узел дерева, не имеющий родительского. лист дерева Узел дерева, не имеющий дочерних узлов. подвыражение Выражение в скобках, рассматриваемое как операнд объемлющего выражения. предупорядоченный обход дерева Способ обхода дерева, при котором каждый узел посещается перед посещением его дочерних узлов. префиксная запись Способ записи математического выражения, при котором оператор предшествует операндам. поступорядоченный обход дерева Способ обхода дерева, при котором каждый узел посещается после посещения его дочерних узлов. родительский узел дерева Узел, ссылающийся на другие (дочерние) узлы. сестринские узлы дерева Узлы, имеющие общий родительский узел. симметричный обход дерева Способ обхода дерева, при котором для каждого узла вначале посещается левый дочерний узел, затем сам этот узел, затем правый дочерний узел. уровень дерева Множество узлов, равноотстоящих от корня.
19.10. Упражнения¶
- Измените функцию print_tree_inorder так, чтобы она ставила скобки вокруг каждого оператора с парой операндов. Работает ли она корректно и однозначно? Всегда ли необходимы скобки?
- Напишите лексический анализатор, то есть, функцию, которая принимает строку с выражением и возвращает список лексем.
- Найдите еще места в функциях, работающих с деревом выражения, где могут возникнуть ошибки, и добавьте соответствующие предложения raise . Протестируйте ваш код с некорректными выражениями.
- Придумайте различные способы сохранения дерева животных в файл. Реализуйте тот, который считаете самым простым.
Дерево целей: что такое и как построить
“Как построить дом?”, “Как съесть слона?”, “Как выучить английский?”, “Как избавить бизнес от бардака?” Решить эти глобальные (и не очень) задачи поможет дерево целей.
Простым языком объясним, что такое дерево целей, как его построить, как применять технологию на практике и какую выгоду от этого можно получить.
Что такое дерево целей
Дерево целей — методика постановки целей и ее декомпозиция на задачи, которые делятся на еще более простые шаги. В результате человек приходит к конкретному списку действий, приводящих к достижению замысла. Получается графическая схема, напоминающая дерево, во главе которой находится глобальная цель.
В отличие от привычного планирования, каждый этап на дереве ведет на следующий уровень и связан с глобальным намерением. Т.е. подъем на одну маленькую ступеньку неминуемо ведет к подъему на следующую. Когда большой замысел разделен на понятные действия, достигнуть его гораздо проще.
Дерево целей используется в личных вопросах, в разработке стратегических планов компании, в маркетинге, разработке продуктов. Оно позволяет:
- выявить узкие места;
- понять над чем работать в ближайшее время;
- декомпозировать процессы.
Техника снимает страх перед большой недостижимой целью. Когда есть четкий план с простыми и понятными действиями, двигаться гораздо проще.

Чтобы съесть слона, его нужно разделать на множество маленьких кусочков.
Структура дерева целей
Херри Алдер сформулировал 4 принципа построения дерева целей:
- Большой замысел располагается наверху, внизу — конкретные задачи к ее достижению.
- Цели низкого уровня подчиняются целям более высокого уровня.
- Каждая задача способствует достижению более крупной цели. И так по иерархии.
- Низкоуровневые цели — это не цели, а задачи — спланированные действия.
Если представлять методику в виде дерева, то:
- ствол — это большая цель или проблема, которую необходимо решить;
- крупные ветки — задачи первого уровня;
- мелкие ветки — задачи и действия второго, третьего и т.д. порядка.
В результат получается графическая наглядная схема с изображением стадий. Так видно с чего следует начать, чего ожидать и какие ресурсы понадобятся.
Количество веток-шагов может быть любым. Чем подробнее разбит каждый этап, тем проще начать действовать и достигать поставленного намерения. Когда нужно приготовить салат оливье, вставать с дивана не так уж и хочется. Но когда понимаешь, что сейчас можно составить список продуктов, к вечеру сходить в магазин, завтра сварить овощи, а послезавтра их почистить и порезать, то миссия уже не кажется столь непосильной.
Графическое изображение помогает человеку чётко продумать план достижения намеченного.
Зачем строить дерево целей
1. Концентрация на цели
В жизни много дел, которые приходят в хаотичном порядке. Если тратить время на то, что не ведет к большой цели, она не будет достигнута. Каждый раз, когда приходит очередная задача, оцените необходимость ее выполнения. Дерево целей помогает отсеять лишнее и сконцентрироваться на том, что важно.
2. Определение конкретных шагов
Распишите глобальную проблему на маленькие дейсвия и начните их выполнять снизу вверх. Так цель будет реализована.
Строить дерево можно для личных или рабочих вопросов, выбирать глобальную или небольшую миссию.
Этапы построения дерева целей
1. Определение и формулировка глобальной цели или проблемы, которую надо решить. От точности формулировки будет зависеть, куда в итоге вы придете. Из формулировки становится понятно, что сразу реализовать намерение не получится. На схеме — это «ствол» дерева.
2. Оценка текущей ситуации и имеющихся ресурсов.
3. Декомпозиция большой цели на подцели. Четко и детально опишите каждую “ветвь”.
4. Разбивка подцелей на задачи. Максимально детализируйте, так придете к пониманию, что является важным, а что можно отодвинуть.
5. Разделение задач на шаги. Разбивайте, пока не дойдете до элементарного действия, для выполнение которого не нужно прилагать усилия.

Для каждого этапа назначьте хотя бы приблизительный срок выполнения. В результате получится схема шагов с описанием ресурсов. На ней будет виден тайминг выполнения и зависимость стадий друг от друга.
Основные принципы
1. Благоразумие. Оцените существующее положение. Учитывайте возможности личности и ресурсы, которые есть в наличии.
2. Конкретность. Четко формулируйте цель и сами стадии.
3. Достижимость. Каждый этап должен быть достижим. Определите результат для каждого шага.
4. Ограниченность во времени. Назначьте реальный срок выполнения.
5. Согласованность. Шаги не должны противоречить друг другу по логике и времени исполнения.
6. Поиск ресурсов. Для воплощения каждого этапа находятся время, деньги, люди, которые могут помочь.
Дерево целей и структура компании
Также дерево целей можно построить для организации. Наверху будет стоять миссия компании, на основе которой выстраивается стратегия организации. А ветки — будут результатом декомпозиции глобальной миссии на конкретные задачи, которые стоят перед отделами маркетинга, продаж и т.д. Для определения результативности для каждого этапа должны быть назначены конкретные KPI и метрики. Так бизнес сможет определить направления развития и отсекать, все что не попадает в дерево целей.
- миссия проекта должна быть сформулирована максимально точно;
- для каждого шага должны быть определены показатели, чтобы их достижение можно было проверить.
Когда дерево целей используется для организации работы бизнеса или предприятия, то его строение должно соответствовать структуре компании. Таким образом, чтобы каждый отдел достигал поставленных перед ними задач. В дальнейшем это приведет к реализации цели и замысла предприятия. Для бизнеса — это наиболее удобное и эффективное построение дерева.
Например, цель бизнеса — увеличение прибыли. Ее разбивают на две подцели — увеличение потока клиентов и снижение потерь и издержек. Их разбивают на задачи. В процессе приходит понимание о найме дополнительного маркетолога и специалиста для создания оптимизированных текстов в блог. Перед маркетологом ставят задачи подключения новых каналов и назначают метрики, которые бы оценили эффективность работы. Главное — максимально расписать каждый процесс и составить список необходимых этапов.

Дерево целей налаживает управление внутри организации. Качественное планирование позволяет масштабировать компанию. Без постановки целей, предприятие словно движется в темноте:
- бизнес не растет и не развивается;
- нет понимания кто, и за что отвечает;
- не понятна эффективность сотрудников;
- действия, не привязанные к задачам, тратят время и деньги компании;
- прибыль не растет.
Дерево целей помогает избежать таких ошибок, так как отражает ответственных за выполнение, сроки исполнения и необходимые средства. Дерево целей — эффективный инструмент, который позволяет декомпозировать цели компании. Оно дает понимание, куда предприятие движется и, как развивается.
Преимущества и недостатки технологии
Дерево целей — лучшая технология для постановки и реализации целей. Она помогает найти быстрые пути, ведущие к задуманному, отсекает неэффективные действия, экономит время и деньги, которые можно распределить на другие задачи.
Плюсы дерева целей:
- Легкость восприятия. Наглядная графическая схема воспринимается проще, чем текст.
- Иерархичность и взаимосвязь. Все этапы логично переходят из один в другой и реализация одного шага ведет к достижению другого. Благодаря наглядности в последовательности выполнения нет путаницы.
- Структурированность. Определены дедлайны, исполнители, последовательность выполнения и необходимые ресурсы для каждой подцели.
- Персонализация. Технология подстраивается под специфику организации и личностные особенности.
- Простота контроля. Заранее известны дедлайны и этапы исполнения.
Минусы дерева целей:
- Неправильно выделенные шаги не приведут к должному результату. Поэтому так важно правильно формулировать и определять критерии измерения достижения результата.
- Невозможность вносить изменения. Если в процессе оказывается, что какой-то этап не реализовать, придется менять строение всего дерева и начинать заново.
- Невозможность заменить одну стадию на другую или пропустить какой-то шаг. Все ветки тесно связаны между собой.
Примеры построения дерева целей
1. Цель — поступление в ВУЗ.
Представим себе абитуриента, который решил быть врачом. Чтобы этого достигнуть, следует определить ресурсы и выделить шаги. Также выбрать ВУЗ, чтобы понять требования к поступлению и оценить возможность переезда в другой город.
Ресурсы: качество школьных знаний, финансовые возможности семьи, связи.
К примеру, семья не может оплатить обучение, нет знакомств, которое бы помогли при поступлении, а знания школьника на среднем уровне.
В зависимости от ресурсов выделяют задачи.
1. Поступить на бюджетное отделение;
- начать дополнительные занятия с репетитором; (найти учителя, выделить время).
- пойти на курсы при университете (найти подходящие курсы по подготовке)
2. Найти подработку для оплаты репетитора/ будущего обучения; (составить резюме, откликаться на предложения, изучить как проходить собеседования).
Для каждого конкретного случая для реализации цели будут составлены разные задачи. К примеру, если семья может оплатить обучение или обладает связями в университете, то пункты будут совсем другие.
2. Цель — увеличение дохода.
Предположим, женщина в декрете решила увеличить доход. Она выделяет две подцели:
1. Организация пассивного дохода:
- открытие сберегательного счета;
- инвестирование;
- выбор выгодных условий для кешбека;
- переезд к маме, чтобы сдавать собственное жилье.
2. Поиск активного дохода:
- выход на работу (устроить ребенка в детский сад или нанять няню);
- смена работы (анализ вакансий — создание и размещение резюме, собеседования);
- смена профессии (получение образования, выбор учебного заведения);
- фрилансерство (прохождение курсов, создание тестовых заданий, размещение на бирже фрилансеров);
У предпринимателя с такой же целью будут совершенно другие ресурсы, а значит и другие шаги к реализации.
Заключение
Дерево целей — один из эффективных способов планирования и управления задачами.
Оно наглядно отражает структурированный план реализации любой сложности, с учетом дедлайнов и ресурсов. Оно:
- помогает оценить недостающие средства и поставить задачи для их восполнения или решить как использовать имеющиеся средства.
- показывает зависимость и влияние задач друг от друга, значимость в общем результате.
- удобно в использовании для решения бизнес вопросов и личных целей, например, финансовых или по саморазвитию.
- помогает бизнесу разбить стратегию на показатели по каждый сфере управления.
- иерархично: один шаг помогает перейти на следующий этап и подчиняется ему.
- уникально, так как учитывает личные условия, текущее положение, ресурсы и возможности.
- помогает проанализировать варианты развития той или иной ситуации.
Дерево целей помогает стратегически мыслить и лучше планировать действия. Оно эффективно не только в бизнесе, но и в обычной жизни. Его создание не требует навыков, но показывает куда и ради чего стоит двигаться. Постройте дерево целей и начните использовать в жизни.
Что такое дерево решений и как его создать?
Нужно тщательно взвесить сложное решение? Попробуйте воспользоваться программой для создания деревьев решений. Читайте, как они устроены, где и как используются, как их создавать, и другую полезную информацию.
Читается за 8 мин.
Хотите создать собственную диаграмму? Попробуйте Lucidchart. Это быстро, легко и совершенно бесплатно.
Что такое дерево решений?
Дерево решений — разновидность схемы, где показаны возможные последствия принятия серии связанных между собой решений. Такой подход позволяет отдельным лицам и целым организациям взвесить разные варианты действий, принимая во внимание вовлеченные затраты, преимущества и уровни вероятности. Деревья решений применяются как в неформальных дискуссиях, так и в разработке алгоритмов для прогнозирования оптимального варианта действий математическим способом.
Дерево решений, как правило, начинается с одного узла, от которого ответвляются возможные варианты. Каждый из них затем ведет к дополнительным узлам, которые разветвляются на новые варианты. В итоге, вся схема приобретает форму дерева.
Узлы дерева решений символизируют одно из трех — вероятность, решение или конечный результат. Узел вероятности изображается в виде круга и сопровождается пометками с вероятностью того или иного результата. Узел решения отображается в виде квадрата и символизирует решение, которое необходимо принять. Ну а конечный узел указывает финальный результат, к которому ведет ветвь решений.
Деревья решений также можно составлять из символов для блок-схем, которые иногда удобнее воспринимать и усваивать.
Символы дерева решений
| Фигура | Название | Значение |
|---|---|---|
| Узел решения | Решение, которое необходимо принять | |
| Узел вероятности | Указывает несколько возможных результатов | |
| Ветви альтернативы | Каждая ветвь символизирует возможный результат или действие | |
| Отклоненная альтернатива | Вариант, который не был выбран | |
| Конечный узел | Символизирует конечный результат |
Как составить дерево решений
Прежде всего, определитесь, как вы планируете создавать дерево решений. Вы можете нарисовать его вручную на бумаге или доске либо воспользоваться специальной программой. В любом случае процедура создания дерева такова:
1. Начните с основного решения. Представьте его в виде небольшого квадрата и проведите вправо линии, каждая из которых символизирует возможное решение или действие. Подпишите каждую линию соответствующим образом.
2. Добавьте узлы принятия решений и узлы вероятности, соблюдая следующие правила:
- если требуется принять еще одно решение, нарисуйте новый прямоугольник;
- если точный результат неизвестен, нарисуйте круг (круги символизируют узлы вероятност