Wednesday, August 5, 2015

Today we discuss the logic to retrieve groups from LDAP. As you might know, LDIF is the query we specify for retrieving these groips. Very often the results are large in number causing the message SIZE_EXCEEDED from a query like this:
     ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
     ld = ldap.initialize("ldaps://myserver:636")
     ld.set_option(ldap.OPT_REFERRALS, 0)
     ld.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
     ld.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
     ld.set_option( ldap.OPT_X_TLS_DEMAND, True )
     ld.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
     ld.simple_bind_s(email, password)
     base_dn="OU=myOU,OU=Groups,DC=adobenet,DC=global,DC=my,DC=com"
     filter = "(|(cn=*))"
     results = ld.search_s(base_dn,ldap.SCOPE_SUBTREE, filter, ['sn'])
     print repr(results)

     return results

Instead we could do this:
     groups = []
     sizelimit = SIZELIMIT
     # If we have a sizelimit, we'll get results one by one so that we
     # can stop processing once we've hit the limit.
     if sizelimit:
       all = 0
     else:
       all = 1
     ix = 0
     cookie = ''
     while True:
      paged_results_control = SimplePagedResultsControl(
        ldap.LDAP_CONTROL_PAGE_OID, True, (PAGE_SIZE, cookie))
      serverctrls = [paged_results_control]
      msgid = ld.search_ext(base_dn, ldap.SCOPE_SUBTREE,
                                 filter, attrlist=['sn'], attrsonly=0, serverctrls=serverctrls) #, clientctrls=None, timeout=TIMEOUT, sizelimit=SIZELIMIT)
      res = ld.result3(msgid=msgid, timeout=TIMEOUT)
      unused_code, results, unused_msgid, serverctrls = res
      for result in results:
        ix += 1
        users.append(result)
        if sizelimit and ix >= sizelimit:
          break
      if sizelimit and ix >= sizelimit:
        break
      cookie = None
      for serverctrl in serverctrls:
        if serverctrl.controlType == ldap.LDAP_CONTROL_PAGE_OID:
          unused_est, cookie = serverctrl.controlValue
          if cookie:
            paged_results_control.controlValue = (PAGE_SIZE, cookie)
          break
      if not cookie:
        break

     return groups


#codingexercise
Question: Use node rotations to convert a binary search tree to a sorted double-linked list.
Answer : The conversion process begins form the root node. If the root node of a binary search tree has a left child, a right rotation occurs. The left child becomes the new root. This process is repeated until there are no left nodes at the root. The root’s right child is traversed until there is a node encountered with a left child. The steps above are then repeated here and the repetitions continue until the leaf node. At this point, we have a singly linked list. It can be made a doubly linked list by linking the parents.

Node ConvertToList(Node root)
{
 Node cur = root;
 Node head = null;
 Node parent = null;
 While (cur){
  While (cur && cur.left)
    {
        cur =  Right-Rotate(cur, parent);
     }
     if (head == null) head = cur;
    parent = cur;
    cur = cur. Right;
}
 CreateDLList(head);
}

Node Right-Rotate(Node root, Node parent)
{
Node cur = root;
Node left = cur.left;
Cur.left = left.right;
Left.right = cur;
Cur = left;
  If (parent != null)
     Parent.right = cur;
Return cur;
}

void CreateDLList(Node root)
{
 Node cur = root;
 If (cur != null) {
    Node next = cur.right;
    While (next ) {
Next.left = cur;
Cur = next;
Next = cur.right;
}
}
}

Tuesday, August 4, 2015


#codingexercise
Question : A robot starts at cell (0,0) of a grid with m rows and n columns. It can move to the left, right, up and down, and moves one cell for a step. It cannot enter cells where the digit sum of the row index and the col index are greater than a threshold k.

For example, when k is 18, the robot can reach cell (35, 37) because 3 + 5 + 3  + 7 = 18. But it cannot reach cell ( 35, 38)  because 3 + 5 + 3 + 8 = 19

Solution :

Int GetCountOfMoves( int threshold, int rows, int cols)

{

Var visited = new bool[rows, cols];

For (int I = 0; I < rows; I++)

    For (int j = 0; j < rows; j ++)

       Visited[i][j] = false;

Return Move(threshold, rows, cols, 0, 0, ref visited);

}

Int Move(int threshold, int rows, int cols, int row, int col, ref bool [,] visited)

{

Int count = 0;

If (check(threshold, rows, cols, row, col, ref visited)) {

Visited[row, col]  = true;

Return 1 + Move(threshold, rows, cols, row-1, col, ref visited)

+ Move(threshold, rows, cols, row, col+1, ref visited)

+ Move(threshold, rows, cols, row+1, col, ref visited)

+ Move(threshold, rows, cols, row, col-1, ref visited) ;

}

Return count;

}

bool Check(int threshold, int rows, int cols, int row, int col, ref bool [,] visited)

{

If ( row < 0 || col < 0 || row >= rows || col >= cols || getDigitsSum(row) + getDigitsSum(col) >= threshold || visited[row,col] ) return false;

Return true;

}

Int getDigitsSum(int number)

{

Int sum = 0;

While (number)

{

Sum += number % 10;

Number /= 10;

}

Return sum;

}




1 / 4

Interview Questions:

Question : A robot starts at cell (0,0) of a grid with m rows and n columns. It can move to the left, right, up and down, and moves one cell for a step. It cannot enter cells where the digit sum of the row indexand the col index are greater than a threshold k.

For example, when k is 18, the robot can reach cell (35, 37) because 3 + 5 + 3  + 7 = 18. But it cannot reach cell ( 35, 38)  because 3 + 5 + 3 + 8 = 19

Solution :

Int GetCountOfMoves( int threshold, int rows, int cols)

{

Var visited = new bool[rows, cols];

For (int I = 0; I < rows; I++)

   For (int j = 0; j < rows; j ++)

      Visited[i][j] = false;

Return Move(threshold, rows, cols, 0, 0, ref visited);

}

Int Move(int threshold, int rows, int cols, int row, int col, ref bool [,] visited)

{

Int count = 0;

If (check(threshold, rows, cols, row, col, ref visited)) {

Visited[row, col]  = true;

Return 1 + Move(threshold, rows, cols, row-1, col, ref visited)

+ Move(threshold, rows, cols, row, col+1, ref visited)

+ Move(threshold, rows, cols, row+1, col, ref visited)

+ Move(threshold, rows, cols, row, col-1, ref visited) ;

}

Return count;

}

2 / 4

bool Check(int threshold, int rows, int cols, int row, int col, ref bool [,] visited)

{

If ( row < 0 || col < 0 || row >= rows || col >= cols || getDigitsSum(row) + getDigitsSum(col) >= threshold || visited[row,col] ) return false;

Return true;

}

Int getDigitsSum(int number)

{

Int sum = 0;

While (number)

{

Sum += number % 10;

Number /= 10;

}

Return sum;

}


Question: How do you find the median from a stream of numbers? The median of a set of numbers is the middle one when they are arranged in order. If the count of numbers is even, the median is defined as the average value of the two numbers in the middle.

Answer: we could keep two heaps – one for the lower half of the series and the other for the higher half of the series.  The heaps should differ in their sizes by at most one node. In such a case we can insert the new number into the max heap first, then pop the greatest number from the max heap and push it into the min heap Since the number pushed is greater than the max heap, all the numbers  in the min heap are still greater than the numbers in the max heap

This is true even if the count of numbers encountered so far is odd.

If the count of numbers is odd, then the median is the first element from the minheap otherwise it’s the average of the min and max heaps.

void Insert ( int num)

{

if ((minHeap.size() + maxHeap.size()) %2 == 1) {

       if(maxHeap.size() > 0 && num < maxHeap[0]) {

                     maxHeap.push_back(num);

                      push_heap(maxHeap.begin(), maxHeap.end(), less<int>());

                      num = maxHeap[0];

                      pop_heap(maxHeap.begin(), maxHeap.end(), less<int>());

                      maxHeap.pop_back();

       }

        minHeap.push_back(num);

        push_heap(minHeap.begin(), minHeap.end(), greater<int>());

}

else

{

        if(minHeap.size()> 0 && minHeap[0] < num) {

minHeap.push_back(num);

push_heap(minHeap.begin(). minHeap.end(), greater<int>());

num = minHeap[0];

pop_heap(minHeap.begin(), minHeap.end(), greater<int>());

minHeap.pop_back();

       }

      maxHeap.push_back(num);

      push_heap(maxHeap.begin(), maxHeap.end(), less<int>());

}

}

4 / 4

int GetMedian()

{

int size = minHeap.size() + maxHeap.size();

if (size == 0)

          throw exception;

int median == 0;

if (size % 2  == 1)

      median = minHeap[0];

else

      median = (minHeap[0] + maxHeap[0])/2;

return median;

}

Monday, August 3, 2015

#codingexercise
Design an algorithm to lay out cells on phone keyboards in order to minimize key presses.
Given the current layout on the phone dialpad, let us see why is it not sufficient. To spell the word snow, we need to press the key 7  four times to advance the letter to be typed to s followed by the 6 key twice to spell n followed by the 6 key three times to spell o followed by the 9 key once to spell w. This takes 10 key presses.
Knowing that I and w are the most frequently typed keys, by just interchanging the two letters will reduce the number of key presses.
In other words, if we use greedy choice to find the most frequent letters and place them on a key with the lowest index. followed by another round that can keep the next round of frequent letters on the next lower index and so on.
Therefore we have
int GetMinKeyPress(int keys, int[] frequencies) {

Array.sort(frequencies);
int letters = frequencies.length;
int presses = 0;
for (int I = letters - 1; I >= 0; I--)
{
   int j = letters -I -1;
   presses += frequencies[I] * (j/keys + 1);
}
return presses;
}

Push and pop sequences
If the pushing sequence is {1,2,3,4,5} then {4,5,3,2,1} is a possible popping sequence while {4,3,5,1,2} is not because the last two elements cannot be popped in the order that they were pushed.
Given two sequences, check if push and pop sequences are possible.
bool IsPopSequence(int[] push, int[] pop, int len)
{
   bool ret = false;
   int startPop = 0;
   int nextPop = startPop;
   int startPush = 0;
   int nextPush = startPush;
   var stk = new stack();
   if (push.length == len && pop.length == len && len > 0) {
   while (nextPop - startPop < len)
   {
      while(stk.IsEmpty() == false || stk. top() != Pop[nextPop])
       {
        if (nextPush - startPush == len)
           break;
        stk.Push(Push[nextPush]);
        nextPush++;
        }
        if (stk. top() != Pop[nextPop])
           break;
        stk.Pop();
        nextPop++;
   }
   if (stk.IsEmpty() && nextPop - startPop == len)
       ret = true;
}
   return ret;
 
}

Sunday, August 2, 2015


Overworked and Overwhelmed – the mindfulness alternative

Scott Eblin gives a handbook of more mindful work for the 24x7 professional arguing that even small increases in mindfulness can lead to big changes in productivity and quality of life. In this summary, we will learn :

The real costs of living in a chronic state of fight or flight.

What mindfulness means and how to begin practicing it.

How to find the right physical, mental and spiritual routines so you can be at your best.

To discover your true purpose and to define success for you

Scott argues that when your calendar is packed and you feel you are battling with work, family and community commitments, you might feel like its becoming crazier lately. There are two factors that is different today than it was in yester years – one companies want to do more and more with less and less and two the advent of smartphones has made it all too easy to remain attached to work.

To add to this, any kind of leadership – be it technical  or supervisory requires the presence at a personal, team and organization levels and we can’t just appear exhausted when we are on the spot.

So what’s the alternative ? Mindfulness based stress reduction programs founder Jon Kabat-Zinn says “Mindfulness is the awareness that arises by paying attention on purpose in the presence moment and non-judgementally.” In other words we have a choice to engage in the present without wasting efforts on thinking if its good or bad. Through awareness and intention, mindfulness sets you up for high performance.

The barriers to mindfulness include :

Mental chatter : we don’t have define this one as most of us are familiar with it. Knowing it means we can overcome it

Distractions: You will likely be distracted every 11 minutes and it will take you about 25 minutes to get back.

Lack of awareness in your story: There’s always the immediate picture and the big picture. We might be missing one or both

The trouble is we don’t anticipate that stroke or collapse when we realize we have stretched too far. That moment of truth is when we realize we need to take action. Why not earlier ?

To go into some details about what the body is enduring, the brain is just as much an organ as any other and has just as much expectation to get tired as any other. Although we are not fighting or taking flight from sabre tooth tigers, we feel the threats similarly even today. In this state, the toll on the body can be severe.


Scott argues that you need to ask yourself two questions to guage your health. What do you do when you are at your best ? And what are the routines that will enable you to be in that zone ?

To answer the first question, do the following:

1)      Find a quite place where you wont be distracted for say half-hour.

2)      Remember when you were in this zone. – label them as home, work or community arena

3)      Remember how it felt.- for example if you were calm, creative, focused or collaborative.

4)      Look for common denominators-  These are the patterns that repeat in different experiences.

5)      And congratulate yourself on finding out from the above on what makes you best

Of course to do these, you have to battle the pressure of time. So let’s look at some time management tips:

Recognize and overcome the tyranny of the present.

Ask if this is really even necessary.

Push your calendar’s reset button – can you delegate or outsource ?

Schedule the most important rocks first.

Give yourself time for some conscious thoughts.

Set boundaries and guardrails  - you may have to communicate this to those around you.

Use Yes and no strategically.

Tame the distraction dragon.

And finally consider your impact.

These ten principles will let you manage your time much more efficiently than before.

To go back and answer the second question, here are seven principles for choosing and following the routines that work for you.

Strive for rhythm not balance

Start where you are

Feed your sweet spot

Choose what is easy to do and likely to make a difference.

Ditch the dogma

Take baby steps

And remember that less is more.

Never neglect your health in practicing the routines found from above. For example, movement is all the more desirable because it is healthy, productive and confidence building. Similarly sleep rejuvenates mind and body. And so does eating right.

And now for the mental routines, rely on your killer app – breathing. You don’t have to spend a lot of time thinking about it. Just notice your breathing and keep coming back to it.

Also, here are some routines to navigate the time frames of the mind.

Reduce regret and remorse about the past – breathe, learn some lessons and take those actions now

Play with the present- if your mind wanders off, just notice it and come back to it. For example, be mindful of the temperature of the water and the froth from the soap if you are cleaning pots and pans.

And visualize away your worries about the future. Since worry has made you notice it already, take steps to move towards more productive thoughts.

In case you already noticed, we think a lot about others. Consequently relationships matter. If relationship suffers, your results, your health and your humanity suffers. You can combat these with paying attention to it since you know they will be affected.  You can take steps like feeling grateful, reading self improvement literature, repetitive prayer or meditation and finally journaling.

Having talked about extrinsic factors, you can remind yourself that not everything is in your control. So don’t expect too much or too narrow. Instead take a look at the success that comes with mindful work. Consider the full range of outcomes from transactional to transformational The transformational ones require far more energy, time and attention. Its what makes your startup succeed or as it did for Jim Campbell to bring back jobs to America. These are the outcomes that are large scale and need your mindfulness to factor in opportunities for transformation.

Lastly, since we are not gifted with everything but we all have gifts, align your mindfulness with your strengths.
#codingexercise
Find the minimal number of coins to make a change for an amount t$ given that the denominations are  v1, v2, ... vn and there is unlimited number of coins for each denomination.
For example, given a value t  = 15$ and a set of coins with denominations 1,3,9,10 the answer is three because coins with values 3 + 3 + 6 = 15.

Notice that from the coin sorting problem discussed earlier, we use the optimal substructure as the sub-problem without the inclusion of the last coin
In order to pay the amount t, the last coin must be <= t-1 in order to be included in the amount t when the coins are sorted.
Hence we use the recurrence, f(t) = min(f(t-vi)) + 1, where 0 < i <= n
int GetMinCount(int total, int [] coins)
{
int[] counts = new int[total+1];
counts[0] = 0;
const int max = Int32.MaxValue;
for(int i = 1 i<= total; ++i) {
   int count = max;
   for (int k = 0; k < coins.length;k++) {
          if (i - coins[k] > = 0 && count > counts[i - coins[k]])
              count = counts[i - coins[k]]
   }
   if (count < max )
       counts[i] = count + 1;
   else
       counts = max;
}
 return counts[total];

Saturday, August 1, 2015

Today we conclude the book review of the Road to Reinvention.
Now that we know a compelling story and storytelling can make a difference for operational changes, let us look into how to overhaul the culture:
The East LA neighborhood of Boyle Heights is a rough place with a history of poverty, crime and prison sentences. Father Gregory Boyle set out to create a radical change by overhauling the culture and giving them a second chance to thrive in the environment. He created a business that expanded from a bakery to many other lines.
The author describes six common threads of cultural brilliance:
1. Fuel passion: Every great invention, breakthrough and advance of humankind began with a passion. The bigger the purpose, the more passion it evokes.
2. Hunt and kill assumptions: assumptions become unwritten rules. To forge new ground, find and remove these.
3. Never stand still : To think that success is permanent is a big trap.
4. Embrace oddball ideas : The creative leaps that ultimately drive biggest gains often sound weird initially
5. Stick it to the man: Disruptive cultures have a healthy sense of irreverence.
6. Fight to win: Competition is a powerful mechanism to rally the team around a common cause and then pursue victory with a vengeance.

Once the operational and cultural changes have been brought about, its time to pay attention to the customer. As Harley Davidson floundered as a company, some of the employees took control and saved the brand by finding a large new set of customers and emotionally charging the existing core.
Accept the death of one size fits all. Savvy businesses attack specific segments. The author gives an example of Bella Donna that opened Europe's first hotel floor designed by and dedicated exclusively to women.Every assumption was challenged to create a new style of room. In other words, if you feel stuck, its time to discover new customers.
Finally the author reminds us that we should focus on our own self. Getting to the next level of career means something different to each of us. The thing all of us have in common, even the best of the best, is the opportunity to break through to a higher level of performance and achievement.
The steps for a personal reinvention plan include:
1) Set a clear vision: Keeping you focused will help fight adversity.
2) Do a gap assessment : As you build your reinvention plan, identify the soft spots
3) Identify costs and sacrifices: All things worth doing require sacrifice and commitment. Make sure you know the parameters going in.
4) Find mentors: Getting inspired by others, can be the difference maker in your reinvention efforts.
5) Conduct a premortem: find out all ways that things can off track.
6) Build accountability markers: Putting a system of penalties and rewards in place will boost your ability to achieve.
7) Track, measure and refine: Tracking weekly performance in specific areas will allow you to keep yourself focused and on track.
Forge your legacy says the author which means that when you rebuild yourself, the more you help the world, the more commercial success you'll likely gain.
Think of the following as important muscles to build:
Empathy: the best business leaders carefully manage the emotional state of those around them
Compassion: Business leaders are quick to pick favorites when admonishing the laggards. Instead use labels to commemorate others' work.
Courage: Let go of the worry demon and develop courage.
Positivity: Replace blame with gratitude
Discipline: Carving out 5 to 10 percent of your time to remain focused will improve your performance.
Creativity: This is your most important sustainable competitive advantage.
Grit: Good old fashioned grit has been statistically linked to being the No.1 indicator of high performance.

Conclusion: Proactive reinvention is a route that leads to success. You are the only one who can make that choice.

Friday, July 31, 2015

The road to reinvention Book Summary continued from a few posts earlier
One of the reasons that Polaroid tumbled down to bankruptcy was that its leaders were resisting change especially after a historic success against rival Kodak. Instead of opening up new possibilities of innovation, the company seemed to narrow its tunnel vision. Each suggestion was stonewalled with the objection “We can’t do that. We can’t cannibalize our core business!” 
In their version of the world, survival is the only goal; forget about growing and thriving. Regardless of our industries and no matter how powerful our organizations may be, we can’t prevent disruption. Instead of sprinting towards cannibalization, it left the opportunity on the table to be seized by a newcomer Instagram that ironically was popular to make digital photos resemble like old polaroids. 
A good litmus test to ensure you H.O.S.E the competition by delivering a new product or service is  
  1. High Value : Unless it solves a real problem in a meaningful way, forget about it. 
  1. Original: Keep your offering uniquely so it always stands out 
  1. Significant:  Go big by breaking the mold of the past and launching something that truly matters. 
  1. Emotionally Charged: If your product evokes passion, customers will line up to buy. 
Contrast the example above with that of Quicken loans which at the peak of its success wanted to make a successful reinvention for a far bigger impact. And it did. Quicken loans grew the business from an  already record high 30 billion in loans to 70 billion in loans by applying to technology to serve customers better and no product innovation. 
Operational Innovation, coined by Michael Hammer, is the concept of overhauling the way a company does business in an effort to create a significant competitive advantage. In essence, it rewrites the rules of the game. To kick off operational change, do the following: 1) make the case for a change 2)set an audacious goal, 3) do a friction audit, 4) bypass who for what and 5) borrow ideas from other industries. 
Create vivid experiences says the author of this book. And he gives the example of running a karate studio by connecting the customers sense to with the details of the whole company. He calls it the Five Senses test. One thing he notes from how the customers feel, hear, see, taste or smell in your business is to keep it consistent because even if you do 99 % of things perfectly. It’s the 1 percent mismatch that people will most remember. 
Nick Morgan is a master storyteller who has written memorable and inspiring speeches for elected officials. There are five kinds of stories that can help you drive your audience to act. These are: 
Quests:  These begin with ordinary people in an ordinary situation and takes them to a goal which may not be logical but it is believable and that’s why its powerful 
A strange land: The heroes suddenly find themselves in a new landscape, one with an unknown terrain, language or rules. A master then helps us to not only survive but thrive. 
Love Stories : Two people fall in love, fall out and find love again. This is the right story for people to get along better. 
Rags to riches stories: These help us believe that ordinary people still have a chance to succeed in a society that seems stacked against us 
Revenge stories: These stories reassert the order that society all too often fails to provide 
By applying these basic patterns, you can use storytelling effectively. 
Stories are only good only when they are delivered. 
  1. Keep it simple : Make your communications dead simple for anyone who reads it. 
  1. Make it clear : Expunge vagueness, ambiguity and imprecision 
  1. Speak to your audience, not yourself: Expunge vagueness, ambiguity and imprecision 
  1. Keep it brief : “be bold, be brief, be gone” 
  1. Make it memorable : People will remember stories and feelings far more than details and figures. 
  1. Activate with action: Start with the end goal in mind, and make sure your communications all lead to the desired outcome. 
#codingexercise
Double 
GetProductNthEveryFifthPower (Double [] A, Double  p)

{

If ( A== null) return 0;

Return A.GetProductNthEveryFifthPower(p);

}




1 / 1

This is a continuation of the interview question and answers on binary trees:

1) Question: Given a binary tree, create its mirror image:

Solution:

Void Mirror (Node root)

{

 if root == null return;

 var temp = root.left;

 root.left = root.right;

 root.right = temp;

 Mirror (root.left);

 Mirror(root.right);

}

2) Determine if a binary tree is symmetrical?

Bool isSymmetrical(Node root)

{

 Node clone = MakeCopy(root);

 Mirror(clone);

 isSymmetrical(root, clone);

}

IsSymmetrical (Node root, Node mirror)

{

 if (root == NULL && mirror == NULL) return true;

 if (root == NULL || mirror == NULL) return false;

 if (root.data != mirror.data) return false;

 return IsSymmetrical(root.left, mirror.right) && IsSymmetrical(root.right, mirror.left);

}

Thursday, July 30, 2015

Simplex Algorithm (discussion continued from previous writeup)
We saw that the Simplex can be started at the origin and we know what to do if we are at the origin. But if our current vertex u is elsewhere. The trick is to transform u into the origin.And we shift the entire co-ordinate system from x1, x2, .. xn to  the local view from u and denoted by y1, y2 … yn to the n hyperplanes that define and enclose u. Specifically, if one of these enclosing inequalities is a.xi <= b, then the distance from a point x to the particular “wall” is yi = bi – ai.x

The n equations  of this type, one per wall, defines the yi’s as linear functions of xi’s and this relationship can be inverted to express the xi’s as a linear function of the yis. Thus we can represent the entire LP in terms of they y’s.

By shifting the co-ordinate system we don’t change anything from the earlier optimal value but the objective function does change. The transformations include:
1)   the inequalities y >= 0, which are simply the transformed versions of the inequalities defining u
2)   u itself is now the origin
3)   The cost function becomes max cu + transformed-cost-vector. y


The simplex algorithm is now fully defined. It moves from vertex to neighbouring vertex stopping when the objective function is locally optimal. At this point, the coordiantes of the local cost vector are all zero or negative. A vertex with this property must also be globally optimal.