Finding the ideal partner
Kwicien, Jack . Employee Benefit Adviser ; New York Vol. 10, Iss. 2, (Feb 2012): 44.
ProQuest document link
ABSTRACT
For example, if your business currently offers group benefits and you see that your firm is currently passing up a
huge opportunity by not offering voluntary benefits, perhaps partnering with a firm that specializes in these
product lines would make sense. The alliance partner presumably has: domain expertise; carrier relationships;
technological capabilities; and sales channel partners, for example. And the alliance partner candidate in turn may
be looking to affiliate with a larger firm that has: benefits plan design expertise; access to different carrier
relationships; and a large number of group benefits clients who are undoubtedly making plan changes that create
benefits gaps which could be satisfied by voluntary benefits offerings. Clearly these two businesses would be
synergistic, and could greatly benefit from each other's expertise and relationships. That would also be true of
businesses such as a property and casualty broker, a retirement planning firm, a human resource consulting
practice, or even a small payroll company.
Don't be afraid to "think outside the box" when it comes to considering potential alliance candidates. Today's
competitor or administrator or vendor may be tomorrow's ideal strategic partner depending upon what you are
trying to accomplish. Think broadly and strategically about what will benefit your clients and customers most in
the future. Don't focus on the way you conduct business today. Think about how you want to be conducting
business two or five years from now and the roadmap that will get you there.
As we talk with benefits advisers all over the country, the forward thinking, select few are looking at their existing
customer base, capabilities, and their own business models and are contemplating methods to adapt their
practices. They are evaluating their client value proposition in light of today's market realities and emphasizing the
expertise and capabilities that they possess and that will be relevant today and several years from now. I think
there is real value to this kind of self-examination. If you do not think your firm can be objective in evaluating its
capabilities, contact us and we will assist you. An ideal alliance partner candidate would possess some or all of the
following characteristics:
FULL TEXT
Many of us are growing tired of the colder weather just as we grow weary of the grind of health care reform
updates and downdrafts. And all of us are ready for the economy to improve in a meaningful and sustained
manner. In some respects it is our winter of discontent. Not to mix literary references, but it is the best of times
and it is the worst of times. Which will it be for you? That depends on whether your glass is half empty or half full.
And it depends on whether you have a plan to succeed.
Last ...
Finding the ideal partner Kwicien, Jack . Employee Benefi
1. Finding the ideal partner
Kwicien, Jack . Employee Benefit Adviser ; New York
Vol. 10, Iss. 2, (Feb 2012): 44.
ProQuest document link
ABSTRACT
For example, if your business currently offers group benefits
and you see that your firm is currently passing up a
huge opportunity by not offering voluntary benefits, perhaps
partnering with a firm that specializes in these
product lines would make sense. The alliance partner
presumably has: domain expertise; carrier relationships;
technological capabilities; and sales channel partners, for
example. And the alliance partner candidate in turn may
be looking to affiliate with a larger firm that has: benefits plan
design expertise; access to different carrier
relationships; and a large number of group benefits clients who
are undoubtedly making plan changes that create
benefits gaps which could be satisfied by voluntary benefits
offerings. Clearly these two businesses would be
2. synergistic, and could greatly benefit from each other's
expertise and relationships. That would also be true of
businesses such as a property and casualty broker, a retirement
planning firm, a human resource consulting
practice, or even a small payroll company.
Don't be afraid to "think outside the box" when it comes to
considering potential alliance candidates. Today's
competitor or administrator or vendor may be tomorrow's ideal
strategic partner depending upon what you are
trying to accomplish. Think broadly and strategically about
what will benefit your clients and customers most in
the future. Don't focus on the way you conduct business today.
Think about how you want to be conducting
business two or five years from now and the roadmap that will
get you there.
As we talk with benefits advisers all over the country, the
forward thinking, select few are looking at their existing
customer base, capabilities, and their own business models and
are contemplating methods to adapt their
practices. They are evaluating their client value proposition in
light of today's market realities and emphasizing the
expertise and capabilities that they possess and that will be
relevant today and several years from now. I think
there is real value to this kind of self-examination. If you do not
3. think your firm can be objective in evaluating its
capabilities, contact us and we will assist you. An ideal alliance
partner candidate would possess some or all of the
following characteristics:
FULL TEXT
Many of us are growing tired of the colder weather just as we
grow weary of the grind of health care reform
updates and downdrafts. And all of us are ready for the
economy to improve in a meaningful and sustained
manner. In some respects it is our winter of discontent. Not to
mix literary references, but it is the best of times
and it is the worst of times. Which will it be for you? That
depends on whether your glass is half empty or half full.
And it depends on whether you have a plan to succeed.
Last month we discussed business planning and the need for a
succession plan. That seems to have resonated
with a number of you given that so many readers are grappling
with how to morph their business model while
growing their revenues. We provided the rationale for having a
written business plan and explained that it is both a
strategic and tactical exercise that serves a multitude of
purposes. We provided an outline of the potential content,
and we discussed succession planning.
4. This month, we want to address strategic alliances as one aspect
of business planning, expanding your
capabilities, and adapting to the market conditions. In an ideal
world, a strategic alliance will permit you to
enhance your value proposition and your client offering without
having to build or buy the resources, skills and
capabilities. And ultimately, your alliance partner might be a
great merger candidate at some point in the future.
Consequently, developing an alliance might be your personal
succession plan or even your exit strategy. So
https://www.proquest.com/trade-journals/finding-ideal-
partner/docview/922256598/se-2?accountid=14872
https://www.proquest.com/trade-journals/finding-ideal-
partner/docview/922256598/se-2?accountid=14872
selecting the right alliance partner requires focused
consideration of the attributes of the ideal partnering
relationship. The strengths and opportunity areas of your
business will determine who the ideal candidate will be.
Evaluating potential candidates is about finding business
partners that have complementary practices. This way
both businesses benefit from not having to spend time or money
on building a new entity.
Self assessment
As we talk with benefits advisers all over the country, the
5. forward thinking, select few are looking at their existing
customer base, capabilities, and their own business models and
are contemplating methods to adapt their
practices. They are evaluating their client value proposition in
light of today's market realities and emphasizing the
expertise and capabilities that they possess and that will be
relevant today and several years from now. I think
there is real value to this kind of self-examination. If you do not
think your firm can be objective in evaluating its
capabilities, contact us and we will assist you. An ideal alliance
partner candidate would possess some or all of the
following characteristics:
* Complementary domain expertise
* Synergistic products or services
* Carrier relationships (preferably not of the duplicative
variety)
* Compatible technological capabilities
* New sales channels or markets
* Compatible management style, business model, structure and
corporate culture
* Shared vision for the future of both of the businesses involved
Invariably the best place to start is with an honest assessment of
6. the strengths and weaknesses of your business
today. Only you are likely to really know where the gaps in
your firm's capabilities exist and how to bridge those
gaps. And be honest with yourself. Treat it as though your life
depended upon it, because in many respects, your
financial livelihood does.
The ideal partner
Depending upon the nature of the strengths and deficiencies of
your business will largely determine who the ideal
alliance partner candidate will be for your specific business
practice. So the evaluation of potential merger
candidates is largely about finding business partners that have
complementary or synergistic business practices,
wherein both businesses benefit from not having to build a new
practice with all the attendant time and expense
associated with the creation of a new business entity.
For example, if your business currently offers group benefits
and you see that your firm is currently passing up a
huge opportunity by not offering voluntary benefits, perhaps
partnering with a firm that specializes in these
product lines would make sense. The alliance partner
presumably has: domain expertise; carrier relationships;
technological capabilities; and sales channel partners, for
7. example. And the alliance partner candidate in turn may
be looking to affiliate with a larger firm that has: benefits plan
design expertise; access to different carrier
relationships; and a large number of group benefits clients who
are undoubtedly making plan changes that create
benefits gaps which could be satisfied by voluntary benefits
offerings. Clearly these two businesses would be
synergistic, and could greatly benefit from each other's
expertise and relationships. That would also be true of
businesses such as a property and casualty broker, a retirement
planning firm, a human resource consulting
practice, or even a small payroll company.
The state of ultimate compatibility may not be achievable in all
cases, but the parties should strive to come as
close as possible to approaching the business and the strategic
alliance with a single and like-minded purpose.
After all, you may all be working together for another 10-15
years and you are certainly linking your financial
fortunes together in a nearly inextricable manner. You may as
well be comfortable with each other and enjoy
working together while presumably making yourselves
wealthier. Clearly you would not ally yourself with another
firm unless you were convinced that the financial rewards were
significantly greater than going it alone. But on the
8. other hand, there is no reason to pursue greater wealth if you
will be miserable in the process. This comes under
the heading of 'life is too short.'
Value proposition
Here are some of the key strategic benefits that can result from
a strategic alliance:
* Strengthen the management team
* Acquire new skills and expertise
* Broaden the product set
* Increase the top-line revenue potential and accelerate growth
* Achieve operational efficiencies
* Improve profitability
* Qualification for more lucrative carrier contracts and
contingencies
* Enhance technology capabilities
* Perpetuate one or both businesses
* Provide an exit strategy
All these are valid reasons to consider a strategic alliance.
Which applies to your business? Is there more than one
9. reason that applies to your circumstances?
Don't be afraid to "think outside the box" when it comes to
considering potential alliance candidates. Today's
competitor or administrator or vendor may be tomorrow's ideal
strategic partner depending upon what you are
trying to accomplish. Think broadly and strategically about
what will benefit your clients and customers most in
the future. Don't focus on the way you conduct business today.
Think about how you want to be conducting
business two or five years from now and the roadmap that will
get you there.
Yesterday's message will not resonate amidst today's clamor
about reform and change. You need to position
yourself as a change "agent" - a change management expert that
provides prudent guidance during periods of
uncertainty. That has to be part of your value proposition in
today's environment. Otherwise, can you honestly say
that your clients consider you their trusted adviser? If not, they
may just find another organization that engenders
that kind of trust. If change is coming anyway, maybe now is a
good time to reinvent yourself.
I know that our industry has been a cauldron of change over the
last 35 years, and Darwinian logic still applies: the
10. strong and the prepared will survive. As for the rest, well we
have a fairly good idea what will happen to the rest. If
you are an antelope, you don't have to be faster than the lion.
You just need to be faster than the slowest antelopes
in your herd. Would you rather adapt or become extinct?
Consider forming a strategic alliance as a method for adapting
your business to the new market realities.
Reach Kwicien of Daymark Advisors at [email protected]
Credit: By Jack Kwicien
DETAILS
Subject: Business plans; Succession planning; Corporate
planning; Business models; Health
care policy; Candidates; Alliances
Business indexing term: Subject: Business plans Succession
planning Corporate planning Business models
Publication title: Employee Benefit Adviser; New York
Volume: 10
Issue: 2
First page: 44
11. LINKS
Linking Service
Terms and Conditions Contact ProQuest
Publication year: 2012
Publication date: Feb 2012
Section: YourBusiness
Publisher: SourceMedia
Place of publication: New York
Country of publication: United States, New York
Publication subject: Business And Economics--Management
ISSN: 1545-3839
Source type: Trade Journal
Language of publication: English
Document type: News
ProQuest document ID: 922256598
Document URL: https://www.proquest.com/trade-
journals/finding-ideal-
partner/docview/922256598/se-2?accountid=14872
12. Copyright: (Copyright c 2009 SourceMedia, Inc. All Rights
Reserved.)
Last updated: 2021-09-13
Database: ProQuest One Academic
https://www.proquest.com/trade-journals/finding-ideal-
partner/docview/922256598/se-2?accountid=14872
https://www.proquest.com/trade-journals/finding-ideal-
partner/docview/922256598/se-2?accountid=14872
https://resolver.ebscohost.com/openurl?ctx_ver=Z39.88-
2004&ctx_enc=info:ofi/enc:UTF-
8&rfr_id=info:sid/ProQ:abitrade&rft_val_fmt=info:ofi/fmt:kev:
mtx:journal&rft.genre=article&rft.jtitle=Employee%20Benefit%
20Adviser&rft.atitle=Finding%20the%20ideal%20partner:%20S
electing%20the%20right%20partner%20requires%20focused%2
0consideration%20of%20the%20attributes%20that%20make%20
up%20the%20ideal%20partnering%20relationship&rft.au=Kwici
en,%20Jack&rft.aulast=Kwicien&rft.aufirst=Jack&rft.date=201
2-02-
01&rft.volume=10&rft.issue=2&rft.spage=44&r ft.isbn=&rft.btit
le=&rft.title=Employee%20Benefit%20Adviser&rft.issn=15453
839&rft_id=info:doi/
https://www.proquest.com/info/termsAndConditions
http://about.proquest.com/go/pqissupportcontactFinding the
ideal partner
New folder/Heap.cs
using System;
using System.Collections.Generic;
using System.Linq;
13. using System.Text;
using System.Threading.Tasks;
namespace Tester.cs
{
public class Heap<K, D> where K : IComparable<K>
{
// This is a nested Node class whose purpose is to
represent a node of a heap.
private class Node : IHeapifyable<K, D>
{
// The Data field represents a payload.
public D Data { get; set; }
// The Key field is used to order elements with regard to
the Binary Min (Max) Heap Policy, i.e. the key of the parent
node is smaller (larger) than the key of its children.
public K Key { get; set; }
// The Position field reflects the location (index) of the
node in the array-based internal data structure.
14. public int Position { get; set; }
public Node(K key, D value, int position)
{
Data = value;
Key = key;
Position = position;
}
// This is a ToString() method of the Node class.
// It prints out a node as a tuple ('key
value','payload','index')}.
public override string ToString()
{
return "(" + Key.ToString() + "," + Data.ToString() +
"," + Position + ")";
}
}
15. // ------------------------------------------------------------------
---------------
// Here the description of the methods and attributes of the
Heap<K, D> class starts
public int Count { get; private set; }
// The data nodes of the Heap<K, D> are stored internally
in the List collection.
// Note that the element with index 0 is a dummy node.
// The top-most element of the heap returned to the user
via Min() is indexed as 1.
private List<Node> data = new List<Node>();
// We refer to a given comparer to order elements in the
heap.
// Depending on the comparer, we may get either a binary
Min-Heap or a binary Max-Heap.
// In the former case, the comparer must order elements in
the ascending order of the keys, and does this in the descending
order in the latter case.
private IComparer<K> comparer;
16. // We expect the user to specify the comparer via the given
argument.
public Heap(IComparer<K> comparer)
{
this.comparer = comparer;
// We use a default comparer when the user is unable to
provide one.
// This implies the restriction on type K such as 'where
K : IComparable<K>' in the class declaration.
if (this.comparer == null) this.comparer =
Comparer<K>.Default;
// We simplify the implementation of the Heap<K, D>
by creating a dummy node at position 0.
// This allows to achieve the following property:
// The children of a node with index i have indices 2*i
and 2*i+1 (if they exist).
data.Add(new Node(default(K), default(D), 0));
}
17. // This method returns the top-most (either a minimum or a
maximum) of the heap.
// It does not delete the element, just returns the node
casted to the IHeapifyable<K, D> interface.
public IHeapifyable<K, D> Min()
{
if (Count == 0) throw new
InvalidOperationException("The heap is empty.");
return data[1];
}
// Insertion to the Heap<K, D> is based on the private
UpHeap() method
public IHeapifyable<K, D> Insert(K key, D value)
{
Count++;
Node node = new Node(key, value, Count);
data.Add(node);
UpHeap(Count);
18. return node;
}
private void UpHeap(int start)
{
int position = start;
while (position != 1)
{
if (comparer.Compare(data[position].Key,
data[position / 2].Key) < 0) Swap(position, position / 2);
position = position / 2;
}
}
private void DownHeap(int start)
{
int rightChild,leftChild = start;
while(start<Count)
19. {
leftChild = leftChild * 2;
int smallChild = start;
rightChild = leftChild + 1;
if (comparer.Compare(data[rightChild].Key,
data[leftChild].Key) < 0)
smallChild = rightChild;
if (comparer.Compare(data[start].Key,
data[smallChild].Key) < 0)
break;
else
Swap(start, smallChild);
start = smallChild;
}
}
// This method swaps two elements in the list representing
the heap.
20. // Use it when you need to swap nodes in your solution,
e.g. in DownHeap() that you will need to develop.
private void Swap(int from, int to)
{
Node temp = data[from];
data[from] = data[to];
data[to] = temp;
data[to].Position = to;
data[from].Position = from;
}
public void Clear()
{
for (int i = 0; i <= Count; i++) data[i].Position = -1;
data.Clear();
data.Add(new Node(default(K), default(D), 0));
Count = 0;
}
21. public override string ToString()
{
if (Count == 0) return "[]";
StringBuilder s = new StringBuilder();
s.Append("[");
for (int i = 0; i < Count; i++)
{
s.Append(data[i + 1]);
if (i + 1 < Count) s.Append(",");
}
s.Append("]");
return s.ToString();
}
// TODO: Your task is to implement all the remaining
methods.
// Read the instruction carefully, study the code examples
from above as they should help you to write the rest of the code.
22. public IHeapifyable<K, D> Delete()
{
// You should replace this plug by your code.
Node node = null;
if (Count == 0)
throw new InvalidOperationException("The heap is
empty.");
else
{
node = data[1];
data[1] = data[Count];
Count--;
DownHeap(1);
}
return node;
//throw new NotImplementedException();
}
// Builds a minimum binary heap using the specified data
23. according to the bottom-up approach.
public IHeapifyable<K, D>[] BuildHeap(K[] keys, D[]
data)
{
throw new NotImplementedException();
}
public void DecreaseKey(IHeapifyable<K, D> element, K
new_key)
{
data[element.Position] = new Node(new_key,
data[element.Position].Data, element.Position);
UpHeap(element.Position);
}
public IHeapifyable<K, D>
DeleteElement(IHeapifyable<K, D> element)
{
Node elem = data[element.Position];
data.RemoveAt(element.Position);
24. return elem;
}
public IHeapifyable<K, D> KthMinElement(int k)
{
return data[k];
}
}
}
New folder/IHeapifyable.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
25. namespace Tester.cs
{
public interface IHeapifyable<K, D>
{
D Data { get; set; }
K Key { get; set; }
int Position { get; }
}
}
New folder/Tester.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
26. namespace Tester.cs
{
class Tester
{
private class IntAscendingComparer : IComparer<int>
{
public int Compare(int A, int B)
{
return Math.Sign(A - B);
}
}
private class IntDescendingComparer : IComparer<int>
{
public int Compare(int A, int B)
{
return -1 * Math.Sign(A - B);
28. Heap<int, string> minHeap = null;
Heap<int, string> maxHeap = null;
IHeapifyable<int, string>[] nodes = null;
string result = "";
// test 1
try
{
Console.WriteLine("nnTest A: Create a min-heap
by calling 'minHeap = new Heap<int, string>(new
IntAscendingComparer());'");
minHeap = new Heap<int, string>(new
IntAscendingComparer());
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
result = result + "A";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
29. + minHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 2
try
{
Console.WriteLine("nnTest B: Run a sequence of
operations: ");
for (int i = 0; i < Math.Min(names.Length,
IDs.Length); i++)
{
Console.WriteLine("nInsert a node with name {0}
(data) and ID {1} (key).", names[i], IDs[i]);
IHeapifyable<int, string> node =
minHeap.Insert(IDs[i], names[i]);
if (!(node.Position == certificateAdd[i] &&
minHeap.Count == i + 1)) throw new Exception("The min-heap
30. has a wrong structure");
Console.WriteLine(" :: SUCCESS: min-heap's
state " + minHeap.ToString()) ;
}
result = result + "B";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 3
try
{
31. Console.WriteLine("nnTest C: Run a sequence of
operations: ");
for (int i = 0; i < certificateDelete.Length; i++)
{
Console.WriteLine("nDelete the minimum
element from the min-heap.");
IHeapifyable<int, string> node =
minHeap.Delete();
if (node.Key != certificateDelete[i]) throw new
Exception("The extracted node has a wrong key");
if (minHeap.Count != certificateDelete.Length - i -
1) throw new Exception("The heap has a wrong number of
elements");
if (certificateDelete.Length - i - 1 > 0)
{
if ((minHeap.Min().Key != certificateDelete[i +
1]) && (minHeap.Min().Position != 1)) throw new
Exception("The min-heap has a wrong structure");
}
Console.WriteLine(" :: SUCCESS: min-heap's
state " + minHeap.ToString());
}
32. result = result + "C";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 4
try
{
Console.WriteLine("nnTest D: Delete the minimum
element from the min-heap.");
IHeapifyable<int, string> node = minHeap.Delete();
Console.WriteLine("Last operation is invalid and
must throw InvalidOperationException. Your solution does not
match specification.");
33. result = result + "-";
}
catch (InvalidOperationException)
{
Console.WriteLine(" :: SUCCESS:
InvalidOperationException is thrown because the min-heap is
empty");
result = result + "D";
}
catch (Exception)
{
Console.WriteLine(" :: FAIL: min-heap's state " +
minHeap.ToString());
Console.WriteLine("Last operation is invalid and
must throw InvalidOperationException. Your solution does not
match specification.");
result = result + "-";
}
// test 5
34. try
{
Console.WriteLine("nnTest E: Run a sequence of
operations: ");
Console.WriteLine("nInsert a node with name {0}
(data) and ID {1} (key).", names[0], IDs[0]);
IHeapifyable<int, string> node =
minHeap.Insert(IDs[0], names[0]);
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nBuild the min-heap for the
pair of key-value arrays with n[{0}] as keys and n[{1}] as data
elements", String.Join(", ", IDs), String.Join(", ", names));
nodes = minHeap.BuildHeap(IDs, names);
Console.WriteLine("Last operation is invalid and
must throw InvalidOperationException. Your solution does not
match specification.");
result = result + "-";
}
catch (InvalidOperationException)
{
35. Console.WriteLine(" :: SUCCESS:
InvalidOperationException is thrown because the min-heap is
not empty");
result = result + "E";
}
catch (Exception)
{
Console.WriteLine(" :: FAIL: min-heap's state " +
minHeap.ToString());
Console.WriteLine("Last operation is invalid and
must throw InvalidOperationException. Your solution does not
match specification.");
result = result + "-";
}
// test 6
try
{
Console.WriteLine("nnTest F: Run a sequence of
operations: ");
36. Console.WriteLine("nClear the min-heap.");
minHeap.Clear();
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nBuild the min-heap for the
pair of key-value arrays with n[{0}] as keys and n[{1}] as data
elements", String.Join(", ", IDs), String.Join(", ", names));
nodes = minHeap.BuildHeap(IDs, names);
if (minHeap.Count !=
certificateMinHeapBuild.Length) throw new Exception("The
resulting min-heap has a wrong number of elements.");
if (nodes.Length != certificateMinHeapBuild.Length)
throw new Exception("The size of the resulting array returned
by BuildHeap() is incorrect.");
for (int i = 0; i < nodes.Length; i++)
{
if (!(nodes[i].Position ==
certificateMinHeapBuild[i])) throw new Exception("The min-
heap has a wrong structure");
}
result = result + "F";
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
37. }
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 7
try
{
Console.WriteLine("nnTest G: Run a sequence of
operations: ");
IHeapifyable<int, string> node = nodes[nodes.Length
- 1];
38. Console.WriteLine("nDelete the minimum element
from the min-heap.");
minHeap.Delete();
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nDelete the minimum element
from the min-heap.");
minHeap.Delete();
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nRun DecreaseKey(node,0) for
node {0} by setting the new value of its key to 0", node);
minHeap.DecreaseKey(node, 0);
if (minHeap.Count !=
certificateMinHeapBuild.Length - 2) throw new Exception("The
resulting min-heap has a wrong number of elements");
if (!((node.Position == 1) && (minHeap.Min().Key
== node.Key))) throw new Exception("The min-heap has a
wrong structure");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
39. result = result + "G";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 8
try
{
Console.WriteLine("nnTest H: Run a sequence of
operations: ");
Console.WriteLine("nCreate a max-heap by calling
'maxHeap = new Heap<int, string>(new
IntDescendingComparer());'");
40. maxHeap = new Heap<int, string>(new
IntDescendingComparer());
Console.WriteLine(" :: SUCCESS: max-heap's state "
+ maxHeap.ToString());
Console.WriteLine("nBuild the max-heap for the
pair of key-value arrays with n[{0}] as keys and n[{1}] as data
elements", String.Join(", ", IDs), String.Join(", ", names));
nodes = maxHeap.BuildHeap(IDs, names);
if (maxHeap.Count !=
certificateMaxHeapBuild.Length) throw new Exception("The
resulting max-heap has a wrong number of elements");
if (nodes.Length != certificateMaxHeapBuild.Length)
throw new Exception("The size of the resulting array returned
by BuildHeap() is incorrect.");
for (int i = 0; i < nodes.Length; i++)
{
if (!(nodes[i].Position ==
certificateMaxHeapBuild[i])) throw new Exception("The max-
heap has a wrong structure");
}
result = result + "H";
Console.WriteLine(" :: SUCCESS: max-heap's state "
+ maxHeap.ToString());
41. }
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: max-heap's state
" + maxHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 9
try
{
Console.WriteLine("nnTest I: Run a sequence of
operations: ");
IHeapifyable<int, string> node = nodes[4];
Console.WriteLine("nDelete the Richard element
from the min-heap.");
42. IHeapifyable<int, string> r =
minHeap.DeleteElement(node);
if (!r.Data.Equals(node.Data)) throw new
Exception("The deleted node is the incorrect node.");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
if (minHeap.Count !=
certificateMinHeapBuild.Length - 3) throw new Exception("The
resulting min-heap has a wrong number of elements");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
result = result + "I";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
43. result = result + "-";
}
// test 10
try
{
Console.WriteLine("nnTest J: Run a sequence of
operations: ");
Console.WriteLine("min-heap's state " +
minHeap.ToString());
IHeapifyable<int, string> node =
minHeap.KthMinElement(4);
if (!node.Data.Equals("John")) throw new
Exception("The 4th deleted node" + node.ToString() + " is the
incorrect node.");
Console.WriteLine(" :: SUCCESS: 4th Node is " +
node.ToString());
44. if (minHeap.Count !=
certificateMinHeapBuild.Length - 3) throw new Exception("The
resulting min-heap has a wrong number of elements");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
result = result + "J";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); }
catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
Console.WriteLine("nn ------------------- SUMMARY -
------------------ ");
Console.WriteLine("Tests passed: " + result);
Console.ReadKey();
45. }
}
}
SIT221 Data Structures and Algorithms Trimester 1, 2022
1
Practical Task 8.1
(Credit Task)
Submission deadline: 11:59 pm, May 15
Discussion deadline: 11:59 pm, May 27
Task Objective
The objective of this task is to study implementation of a Binary
Heap, a data structure which is seen as a
special case of a complete binary tree.
Background
Like a binary tree, a heap consists of a collection of nodes that
can be considered as building blocks of the
data structure. The tree structure that a binary heap represents is
complete; that is, every level, except
possibly the last one, is completely filled, and all nodes are as
46. far left as possible. This makes a binary heap
with � nodes be always of a �(log�) height. In addition to the
standard binary tree properties, a binary heap
must also adhere to the mandatory Heap Ordering property. The
ordering can be one of the two types:
- The Min-Heap Property: the value of each node is greater than
or equal to the value of its parent,
with the minimum-value element at the root.
- The Max-Heap Property: the value of each node is less than or
equal to the value of its parent, with
the maximum-value element at the root.
Note that a binary heap is not a sorted structure and can be
regarded as partially ordered. Indeed, there is
no particular relationship among nodes on any given level, even
among siblings. From a practical perspective,
a binary heap is a very useful data structure when one needs to
remove the object with the lowest (or highest,
in case of the max-heap ordering) priority.
A binary heap can be uniquely represented by storing its level
order traversal in an array or an array-based
collection like a list (also known as a vector). Note that the
links between nodes are not required. For the
convenience of implementation, the first entry of the array with
index 0 is skipped; it contains a dummy
(default) element. Therefore, the root of a heap is the second
item in the array at index 1, and the length of
the array is � + 1 for a heap with � data elements. This implies
that for the �!" element of the array the
following statements are valid:
- the left child is located at index 2 ∙ �;
- the right child is located at index 2 ∙ � + 1;
47. - the parent is located uniquely at index ⌊ �/2⌋ .
Insertion of a new element initially appends it to the end of a
heap as the last element of the array at index
� + 1. The Heap Ordering property is then repaired by
comparing the added element with its parent and
moving the added element up a level (swapping positions with
the parent). This process is commonly known
as “UpHeap”, or “Heapify-Up”, or “Sift-Up”. The comparison is
repeated until the parent is larger (or smaller,
in case of the max-heap ordering) than or equal to the
percolating element. The worst-case runtime of the
algorithm is �(log�), since we need at most one swap on each
level of a heap on the path from the inserted
node to the root.
The minimum (or maximum, in case of the max-heap ordering)
element can be found at the root, which is
the element of the array located at index 1. Deletion of the
minimum element first replaces it with the last
element of the array at index �, and then restores the Heap
Ordering property by following the process
known as “DownHeap”, or “Heapify-Down”, or “Sift-Down”.
Similar to insertion, the worst-case runtime is
�(log�).
SIT221 Data Structures and Algorithms Trimester 1, 2022
2
Task Details
In this task, work through each of the following steps to
complete the task:
48. 1. Explore the source code attached to this task. Create a new
Microsoft Visual Studio project and
import the enclosed Heap.cs, IHeapifyable.cs, and Tester.cs
files. Your newly built project should
compile and work without errors. The objective of the task is to
develop the missing functionality of
the Heap<K,D> class. The Heap.cs contains a template of the
Heap<K,D>. The Tester.cs contains a
prepared Main method that should help you to build a fully-
functional data structure. It enables a
number of tests important for debugging and testing of the
Heap<K,D> class and its interfaces for
runtime and logical errors.
2. Find the nested Node class presented inside the Heap<K,D>
and explore its structure. This is a generic
class that represents a node of a binary heap. Think about it as
an atomic data structure itself that
serves the Heap<K,D> as a building block. It is a data structure
consisting of
- a generic type raw data (a payload),
- a generic type key necessary to place the node with regard to
the order of nodes existing in
the Heap<K,D>, and
- an integer-valued position (index) that locates the node in the
array-based collection of nodes
of the Heap<K,D>.
Because both K and D types are generic, the key and the data
may be of an arbitrary type: a string,
49. an integer, or a user-defined class. Finally, note that the Node
class is ready for you to use. It
provides the following functionality:
- Node(K key, D value, int position)
Initializes a new instance of the Node class associated with the
specified generic key. The node records
the given generic data as well as its own index-based position
within the array-based collection of data
nodes privately owned by the related Heap<K,D>.
- D Data
Property. Gets or sets the data of generic type D associated with
the Node.
- K Key
Property. Gets or sets the key of generic type K assigned to the
Node.
- Position
Property. Gets or sets the index-based position of the Node in
the array-based collection of nodes
constituting the Heap<K,D> .
- string ToString()
Returns a string that represents the current Node.
The Node class implements the IHeapifyable<K,D> interface,
which is defined in the attached
IHeapifyable.cs. Note that this interface is parametrized by the
same two generic data types as the
Heap<K,D>. The reason for the use of the interface is that the
Node class is a data structure internal
to the Heap<K,D>, therefore an instance of the Node must not
be exposed to a user. It must remain
hidden for the user in order to protect the integrity of the whole
50. data structure. Otherwise,
manipulating the nodes directly, the user may easily corrupt the
structure of a binary heap and
violate the important Heap-Ordering rule. Nevertheless, because
the user needs access to the data
that the user owns and stores inside a binary heap, the Node
implements the interface that permits
reading and modifying the data. Therefore, the primal purpose
of the IHeapifyable<K,D> is to
record and retrieve the data associated with a particular node
and track the position of the node in
the array-based collection of nodes of the Heap<K,D>.
SIT221 Data Structures and Algorithms Trimester 1, 2022
3
Check the IHeapifyable<K,D> interface to see that the only
property it allows to change is the Data.
The other two properties, the Key and the Position, are read-
only. Note that the value of a key is
set at the time the node is added to a heap. It then can be
changed only via dedicated operations,
like DecreaseKey. The Heap<K,D> is entirely responsible for
Position, thus modification of this
property by the user is impossible.
3. Proceed with the given template of the Heap<K,D> class and
explore the methods that it has
implemented for you for the purpose of example, in particular:
- Heap(IComparer<K> comparer)
51. Initializes a new instance of the Heap<K,D> class and stores the
specified reference to the object that
enables comparison of two keys of type K.
- Count
Property. Gets the number of elements stored by the
Heap<K,D>.
- IHeapifyable<K, D> Min()
Returns the element with the minimum (or maximum) key
positioned at the top of the Heap<K,D>,
without removing it. The element is casted to the
IHeapifyable<K,D>. The method throws
InvalidOperationException if the Heap<K,D> is empty.
- IHeapifyable<K, D> Insert(K key, D value)
Inserts a new node containing the specified key-value pair into
the Heap<K,D>. The position of the new
element in the binary heap is determined according the Heap-
Order policy. It returns the newly created
node casted to the IHeapifyable<K,D>.
- void Clear()
Removes all nodes from the Heap<K,D> and sets the Count to
zero.
- string ToString()
Returns a string representation of the Heap<K,D>.
Rather than an array, the Heap<K,D> utilizes the native .NET
Framework List<T> generic collection as
52. the internal data structure. This collection is dynamic as
opposed to an array, which is static. This fact
should simplify your work. Furthermore, note that the internal
structure of the Heap<K,D> can be
explored only implicitly through the positions of the nodes
constituting it.
As you may have noticed, the comparison of nodes is performed
by the comparator originally set
within the constructor of the Heap<K,D>. Providing different
comparator to the constructor will
change the behaviour of the Heap<K,D>. When keys are ordered
in ascending order, the Heap<K,D>
acts as a min-heap. When the comparator orders keys in
descending order, the Heap<K,D> behaves
as a max-heap.
4. You must complete the Heap<K,D> class and provide the
following functionality to the user:
- IHeapifyable<K, D> Delete()
Deletes and returns the node casted to the IHeapifyable<K,D>
positioned at the top of the Heap<K,D>.
This method throws InvalidOperationException if the
Heap<K,D> is empty.
- IHeapifyable<K, D>[] BuildHeap(K[] keys, D[] data)
Builds a binary heap following the bottom-up approach. Each
new element of the heap is derived by the
key-value pair (keys[i],data[i]) specified by the method’s
parameters. It returns an array of nodes casted
to the IHeapifyable<K,D>. Each node at index � must match its
key-value pair at index � of the two input
arrays. This method throws InvalidOperationException if the
Heap<K,D> is not empty.
53. - DecreaseKey(IHeapifyable<K, D> element, K new_key)
Decreases the key of the specified element presented in the
Heap<K,D>. The method throws
InvalidOperationException when the node stored in the
Heap<K,D> at the position specified by the
SIT221 Data Structures and Algorithms Trimester 1, 2022
4
element is different to the element. This signals that the given
element is inconsistent to the current state
of the Heap<K,D>.
Note that you are free in writing your code that is private to the
Heap<K,D> unless you respect all
the requirements in terms of functionality and signatures of the
specified methods.
5. Now you are required to implement some non-standard
operations to your Heap �. Firstly,
implement a �������������(�) operation that removes
element �[�] from the min-heap �
consisting of � elements in a logarithmic �(log�) time. Note
that the �[�] does not need to be the
minimum-key element in �. Also, naturally, � has to maintain
the Min-Heap Property after deletion
of �[�]. Include as a comment in your code a brief analysis of
your code’s running time as a function
of � elements.
54. 6. Min Heap allows us to have a Min operation in a constant
�(1) time. Now create a new function
��ℎ ����������(��� �) that finds the �!" minimum
element in �(�log�) time, where 1 ≤ � ≤ �.
Remember that both insertion and removal in a binary min-heap
of size � takes a �(log�) time.
Include as a comment in your code a brief analysis of your
code’s running time as a function of �
elements.
7. As you progress with the implementation of the Heap<K,D>
class, you should start using the Tester
class to thoroughly test the Heap<K,D> aiming on the coverage
of all potential logical issues and
runtime errors. This (testing) part of the task is as important as
writing the Heap<K,D> class. The
given version of the testing class covers only some basic cases.
Therefore, you should extend it with
extra cases to make sure that your data structure is checked
against other potential mistakes.
Expected Printout
Appendix A provides an example printout for your program. If
you are getting a different printout then your
implementation is not ready for submission. Please ensure your
program prints out Success for all tests
before submission.
Further Notes
- Explore the material of chapter 9.4 of the SIT221 course book
“Data structures and algorithms in Java”
(2014) by M. Goodrich, R. Tamassia, and M. Goldwasser. You
may access the book on-line for free from
the reading list application in CloudDeakin available in
Resources ® Additional Course Resources ®
55. Resources on Algorithms and Data Structures ® Course Book:
Data structures and algorithms in Java. As
a supplementary material, to learn more about the theory part
and implementation issues of binary
heaps, you may refer to the Section 9.2.3 of Chapter 9 of
SIT221 Workbook available in CloudDeakin in
Resources ® Additional Course Resources ® Resources on
Algorithms and Data Structures ® SIT221
Workbook .
- You may find exploring the content of chapter 9.3 of the
course book “Data Structures and Algorithms in
Java” by Michael T. Goodrich, Roberto Tamassia, and Michael
H. Goldwasser (2014) useful to solve these
tasks. You may access the book on-line for free from the
reading list application in CloudDeakin available
in Resources ® Additional Course Resources ® Resources on
Algorithms and Data Structures ® Course
Book: Data structures and algorithms in Java.
- The lecture notes of week 6 may be the best material to
understand the logic behind a binary heap and
its array-based implementation.
SIT221 Data Structures and Algorithms Trimester 1, 2022
5
Marking Process and Discussion
To get your task completed, you must finish the following steps
strictly on time.
56. 1. Work on your task either during your allocated lab time or
during your own study time.
2. Once the task is complete you should make sure that your
program implements all the required
functionality, is compliable, and has no runtime errors.
Programs causing compilation or runtime
errors will not be accepted as a solution. You need to test your
program thoroughly before
submission. Think about potential errors where your program
might fail. Note we can sometime use
test cases that are different to those provided so verify you have
checked it more thoroughly than
just using the test program provided.
3. Submit your solution as an answer to the task via the
OnTrack submission system. This first
submission must be prior to the submission “S” deadline
indicated in the unit guide and in OnTrack.
4. If your task has been assessed as requiring a “Redo” or
“Resubmit” then you should prepare a new
submission. You will have 1 (7 day) calendar week from the day
you receive the assessment from the
tutor. This usually will mean you should revise the lecture, the
readings indicated, and read the unit
discussion list for suggestions. After your submission has been
corrected and providing it is still
before the due deadline you can resubmit.
5. If your task has been assessed as correct, either after step 3
or 4, you can “discuss” with your tutor.
This first discussion must occur prior to the discussion “D”.
6. Meet with your tutor to demonstrate/discuss your submission.
57. Be on time with respect to the
specified discussion deadline.
7. The tutor will ask you both theoretical and practical
questions. Questions are likely to cover lecture
notes, so attending (or watching) lectures should help you with
this compulsory interview part. The
tutor will tick off the task as complete, only if you provide a
satisfactory answer to these questions.
8. If you cannot answer the questions satisfactorily your task
will remain on discussion and you will
need to study the topic during the week and have a second
discussion the following week.
9. Please note, due to the number of students and time
constraints tutors will only be expected to mark
and/or discuss your task twice. After this it will be marked as a
“Exceeded Feedback”.
10. Note that we will not check your solution after the
submission deadline and will not discuss it after
the discussion deadline. If you fail one of the deadlines, you
fail the task and this reduces the chance
to pass the unit. Unless extended for all students, the deadlines
are strict to guarantee smooth and
on-time work through the unit.
11. Final note, A “Fail” or “Exceeded Feedback” grade on a
task does not mean you have failed the unit.
It simply means that you have not demonstrated your
understanding of that task through OnTrack.
Expected Printout
This section displays the printout produced by the attached
Tester class, specifically by its Main method. It is
58. based on our solution. The printout is provided here to help
with testing your code for potential logical errors.
It demonstrates the correct logic rather than an expected
printout in terms of text and alignment.
Test A: Create a min-heap by calling 'minHeap = new Heap<int,
string>(new IntAscendingComparer());'
:: SUCCESS: min-heap's state []
Test B: Run a sequence of operations:
Insert a node with name Kelly (data) and ID 1 (key).
:: SUCCESS: min-heap's state [(1,Kelly,1)]
SIT221 Data Structures and Algorithms Trimester 1, 2022
6
Insert a node with name Cindy (data) and ID 6 (key).
:: SUCCESS: min-heap's state [(1,Kelly,1),(6,Cindy,2)]
Insert a node with name John (data) and ID 5 (key).
:: SUCCESS: min-heap's state
59. [(1,Kelly,1),(6,Cindy,2),(5,John,3)]
Insert a node with name Andrew (data) and ID 7 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(6,Cindy,2),(5,John,3),(7,Andrew,4)]
Insert a node with name Richard (data) and ID 8 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(6,Cindy,2),(5,John,3),(7,Andrew,4),(8,Richard,5)]
Insert a node with name Michael (data) and ID 3 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(6,Cindy,2),(3,Michael,3),(7,Andrew,4),(8,Richard,
5),(5,John,6)]
Insert a node with name Guy (data) and ID 10 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(6,Cindy,2),(3,Michael,3),(7,Andrew,4),(8,Ric hard,
5),(5,John,6),(10,Guy,7)]
Insert a node with name Elicia (data) and ID 4 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(4,Elicia,2),(3,Michael,3),(6,Cindy,4),(8,Richard,5)
,(5,John,6),(10,Guy,7),(7,Andrew,8)]
60. Insert a node with name Tom (data) and ID 2 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(2,Tom,2),(3,Michael,3),(4,Elicia,4),(8,Richard,5),(
5,John,6),(10,Guy,7),(7,Andrew,8),(6,Cindy,9)]
Insert a node with name Iman (data) and ID 9 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(2,Tom,2),(3,Michael,3),(4,Elicia,4),(8,Richard,5),(
5,John,6),(10,Guy,7),(7,Andrew,8),(6,Cindy,9),(9,Iman,10)]
Insert a node with name Simon (data) and ID 14 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(2,Tom,2),(3,Michael,3),(4,Elicia,4),(8,Richard,5),(
5,John,6),(10,Guy,7),(7,Andrew,8),(6,Cindy,9),(9,Iman,10),(
14,Simon,11)]
Insert a node with name Vicky (data) and ID 12 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(2,Tom,2),(3,Michael,3),(4,Elicia,4),(8,Richard,5),(
5,John,6),(10,Guy,7),(7,Andrew,8),(6,Cindy,9),(9,Iman,10),(
14,Simon,11),(12,Vicky,12)]
Insert a node with name Kevin (data) and ID 11 (key).
:: SUCCESS: min-heap's state
[(1,Kelly,1),(2,Tom,2),(3,Michael,3),(4,Elicia,4),(8,Richard,5),(
5,John,6),(10,Guy,7),(7,Andrew,8),(6,Cindy,9),(9,Iman,10),(
14,Simon,11),(12,Vicky,12),(11,Kevin,13)]
61. Insert a node with name David (data) and ID 13 (key).
SIT221 Data Structures and Algorithms Trimester 1, 2022
7
:: SUCCESS: min-heap's state
[(1,Kelly,1),(2,Tom,2),(3,Michael,3),(4,Elicia,4),(8,Richard,5),(
5,John,6),(10,Guy,7),(7,Andrew,8),(6,Cindy,9),(9,Iman,10),(
14,Simon,11),(12,Vicky,12),(11,Kevin,13),(13,David,14)]
Test C: Run a sequence of operations:
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(2,Tom,1),(4,Elicia,2),(3,Michael,3),(6,Cindy,4),(8,Richard,5),
(5,John,6),(10,Guy,7),(7,Andrew,8),(13,David,9),(9,Iman,10
),(14,Simon,11),(12,Vicky,12),(11,Kevin,13)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(3,Michael,1),(4,Elicia,2),(5,John,3),(6,Cindy,4),(8,Richard,5),
(11,Kevin,6),(10,Guy,7),(7,Andrew,8),(13,David,9),(9,Iman,
10),(14,Simon,11),(12,Vicky,12)]
62. Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(4,Elicia,1),(6,Cindy,2),(5,John,3),(7,Andrew,4),(8,Richard,5),
(11,Kevin,6),(10,Guy,7),(12,Vicky,8),(13,David,9),(9,Iman,1
0),(14,Simon,11)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(5,John,1),(6,Cindy,2),(10,Guy,3),(7,Andrew,4),(8,Richard,5),(
11,Kevin,6),(14,Simon,7),(12,Vicky,8),(13,David,9),(9,Ima
n,10)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(6,Cindy,1),(7,Andrew,2),(10,Guy,3),(9,Iman,4),(8,Richard,5),(
11,Kevin,6),(14,Simon,7),(12,Vicky,8),(13,David,9)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(7,Andrew,1),(8,Richard,2),(10,Guy,3),(9,Iman,4),(13,David,5)
,(11,Kevin,6),(14,Simon,7),(12,Vicky,8)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(8,Richard,1),(9,Iman,2),(10,Guy,3),(12,Vicky,4),(13,David,5),
(11,Kevin,6),(14,Simon,7)]
63. Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(9,Iman,1),(12,Vicky,2),(10,Guy,3),(14,Simon,4),(13,David,5),
(11,Kevin,6)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(10,Guy,1),(12,Vicky,2),(11,Kevin,3),(14,Simon,4),(13,David,
5)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(11,Kevin,1),(12,Vicky,2),(13,David,3),(14,Simon,4)]
Delete the minimum element from the min-heap.
SIT221 Data Structures and Algorithms Trimester 1, 2022
8
:: SUCCESS: min-heap's state
[(12,Vicky,1),(14,Simon,2),(13,David,3)]
Delete the minimum element from the min-heap.
64. :: SUCCESS: min-heap's state [(13,David,1),(14,Simon,2)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state [(14,Simon,1)]
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state []
Test D: Delete the minimum element from the min-heap.
:: SUCCESS: InvalidOperationException is thrown because the
min-heap is empty
Test E: Run a sequence of operations:
Insert a node with name Kelly (data) and ID 1 (key).
:: SUCCESS: min-heap's state [(1,Kelly,1)]
Build the min-heap for the pair of key-value arrays with
[1, 6, 5, 7, 8, 3, 10, 4, 2, 9, 14, 12, 11, 13] as keys and
[Kelly, Cindy, John, Andrew, Richard, Michael, Guy, Elicia,
Tom, Iman, Simon, Vicky, Kevin, David] as data elements
65. :: SUCCESS: InvalidOperationException is thrown because the
min-heap is not empty
Test F: Run a sequence of operations:
Clear the min-heap.
:: SUCCESS: min-heap's state []
Build the min-heap for the pair of key-value arrays with
[1, 6, 5, 7, 8, 3, 10, 4, 2, 9, 14, 12, 11, 13] as keys and
[Kelly, Cindy, John, Andrew, Richard, Michael, Guy, Elicia,
Tom, Iman, Simon, Vicky, Kevin, David] as data elements
:: SUCCESS: min-heap's state
[(1,Kelly,1),(2,Tom,2),(3,Michael,3),(4,Elicia,4),(8,Richard,5),(
5,John,6),(10,Guy,7),(6,Cindy,8),(7,Andrew,9),(9,Iman,10),(
14,Simon,11),(12,Vicky,12),(11,Kevin,13),(13,David,14)]
Test G: Run a sequence of operations:
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(2,Tom,1),(4,Elicia,2),(3,Michael,3),(6,Cindy,4),(8,Richard,5),
(5,John,6),(10,Guy,7),(13,David,8),(7,Andrew,9),(9,Iman,10
66. ),(14,Simon,11),(12,Vicky,12),(11,Kevin,13)]
SIT221 Data Structures and Algorithms Trimester 1, 2022
9
Delete the minimum element from the min-heap.
:: SUCCESS: min-heap's state
[(3,Michael,1),(4,Elicia,2),(5,John,3),(6,Cindy,4),(8,Richard,5),
(11,Kevin,6),(10,Guy,7),(13,David,8),(7,Andrew,9),(9,Iman,
10),(14,Simon,11),(12,Vicky,12)]
Run DecreaseKey(node,0) for node (13,David,8) by setting the
new value of its key to 0
:: SUCCESS: min-heap's state
[(0,David,1),(3,Michael,2),(5,John,3),(4,Elicia,4),(8,Richard,5),
(11,Kevin,6),(10,Guy,7),(6,Cindy,8),(7,Andrew,9),(9,Iman,1
0),(14,Simon,11),(12,Vicky,12)]
Test H: Run a sequence of operations:
Create a max-heap by calling 'maxHeap = new Heap<int,
string>(new IntDescendingComparer());'
:: SUCCESS: max-heap's state []
67. Build the max-heap for the pair of key-value arrays with
[1, 6, 5, 7, 8, 3, 10, 4, 2, 9, 14, 12, 11, 13] as keys and
[Kelly, Cindy, John, Andrew, Richard, Michael, Guy, Elicia,
Tom, Iman, Simon, Vicky, Kevin, David] as data elements
:: SUCCESS: max-heap's state
[(14,Simon,1),(9,Iman,2),(13,Davi d,3),(7,Andrew,4),(8,Richard,
5),(12,Vicky,6),(10,Guy,7),(4,Elicia,8),(2,Tom,9),(6,Cindy,
10),(1,Kelly,11),(3,Michael,12),(11,Kevin,13),(5,John,14)]
Test I: Run a sequence of operations:
Delete the Richard element from the min-heap.
:: SUCCESS: min-heap's state
[(0,David,1),(3,Michael,2),(5,John,3),(4,Elicia,4),(9,Iman,5),(11
,Kevin,6),(10,Guy,7),(6,Cindy,8),(7,Andrew,9),(12,Vicky,10
),(14,Simon,11)]
:: SUCCESS: min-heap's state
[(0,David,1),(3,Michael,2),(5,John,3),(4,Elicia,4),(9,Iman,5),(11
,Kevin,6),(10,Guy,7),(6,Cindy,8),(7,Andrew,9),(12,Vicky,10
),(14,Simon,11)]
Test J: Run a sequence of operations:
min-heap's state
[(0,David,1),(3,Michael,2),(5,John,3),(4,Elicia,4),(9,Iman,5),(11
,Kevin,6),(10,Guy,7),(6,Cindy,8),(7,Andrew,9),(12,Vicky,10
68. ),(14,Simon,11)]
:: SUCCESS: 4th Node is (5,John,-1)
:: SUCCESS: min-heap's state
[(0,David,1),(3,Michael,2),(10,Guy,3),(6,Cindy,4),(4,Elicia,5),(
11,Kevin,6),(12,Vicky,7),(14,Simon,8),(7,Andrew,9),(9,Iman
,10),(5,John,11)]
------------------- SUMMARY -------------------
Tests passed: ABCDEFGHIJ
Code Handout/Student/Heap.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Heap
{
69. public class Heap<K, D> where K : IComparable<K>
{
// This is a nested Node class whose purpose is to
represent a node of a heap.
private class Node : IHeapifyable<K, D>
{
// The Data field represents a payload.
public D Data { get; set; }
// The Key field is used to order elements with regard to
the Binary Min (Max) Heap Policy, i.e. the key of the parent
node is smaller (larger) than the key of its children.
public K Key { get; set; }
// The Position field reflects the location (index) of the
node in the array-based internal data structure.
public int Position { get; set; }
public Node(K key, D value, int position)
{
Data = value;
70. Key = key;
Position = position;
}
// This is a ToString() method of the Node class.
// It prints out a node as a tuple ('key
value','payload','index')}.
public override string ToString()
{
return "(" + Key.ToString() + "," + Data.ToString() +
"," + Position + ")";
}
}
// ------------------------------------------------------------------
---------------
// Here the description of the methods and attributes of the
Heap<K, D> class starts
public int Count { get; private set; }
71. // The data nodes of the Heap<K, D> are stored internally
in the List collection.
// Note that the element with index 0 is a dummy node.
// The top-most element of the heap returned to the user
via Min() is indexed as 1.
private List<Node> data = new List<Node>();
// We refer to a given comparer to order elements in the
heap.
// Depending on the comparer, we may get either a binary
Min-Heap or a binary Max-Heap.
// In the former case, the comparer must order elements in
the ascending order of the keys, and does this in the descending
order in the latter case.
private IComparer<K> comparer;
// We expect the user to specify the comparer via the given
argument.
public Heap(IComparer<K> comparer)
{
72. this.comparer = comparer;
// We use a default comparer when the user is unable to
provide one.
// This implies the restriction on type K such as 'where
K : IComparable<K>' in the class declaration.
if (this.comparer == null) this.comparer =
Comparer<K>.Default;
// We simplify the implementation of the Heap<K, D>
by creating a dummy node at position 0.
// This allows to achieve the following property:
// The children of a node with index i have indices 2*i
and 2*i+1 (if they exist).
data.Add(new Node(default(K), default(D), 0));
}
// This method returns the top-most (either a minimum or a
maximum) of the heap.
// It does not delete the element, just returns the node
casted to the IHeapifyable<K, D> interface.
public IHeapifyable<K, D> Min()
73. {
if (Count == 0) throw new
InvalidOperationException("The heap is empty.");
return data[1];
}
// Insertion to the Heap<K, D> is based on the private
UpHeap() method
public IHeapifyable<K, D> Insert(K key, D value)
{
Count++;
Node node = new Node(key, value, Count);
data.Add(node);
UpHeap(Count);
return node;
}
private void UpHeap(int start)
{
74. int position = start;
while (position != 1)
{
if (comparer.Compare(data[position].Key,
data[position / 2].Key) < 0) Swap(position, position / 2);
position = position / 2;
}
}
// This method swaps two elements in the list representing
the heap.
// Use it when you need to swap nodes in your solution,
e.g. in DownHeap() that you will need to develop.
private void Swap(int from, int to)
{
Node temp = data[from];
data[from] = data[to];
data[to] = temp;
data[to].Position = to;
75. data[from].Position = from;
}
public void Clear()
{
for (int i = 0; i<=Count; i++) data[i].Position = -1;
data.Clear();
data.Add(new Node(default(K), default(D), 0));
Count = 0;
}
public override string ToString()
{
if (Count == 0) return "[]";
StringBuilder s = new StringBuilder();
s.Append("[");
for (int i = 0; i < Count; i++)
{
76. s.Append(data[i + 1]);
if (i + 1 < Count) s.Append(",");
}
s.Append("]");
return s.ToString();
}
// TODO: Your task is to implement all the remaining
methods.
// Read the instruction carefully, study the code examples
from above as they should help you to write the rest of the code.
public IHeapifyable<K, D> Delete()
{
// You should replace this plug by your code.
throw new NotImplementedException();
}
// Builds a minimum binary heap using the specified data
according to the bottom-up approach.
public IHeapifyable<K, D>[] BuildHeap(K[] keys, D[]
77. data)
{
// You should replace this plug by your code.
throw new NotImplementedException();
}
public void DecreaseKey(IHeapifyable<K, D> element, K
new_key)
{
// You should replace this plug by your code.
throw new NotImplementedException();
}
public IHeapifyable<K, D>
DeleteElement(IHeapifyable<K, D> element)
{
// You should replace this plug by your code.
throw new NotImplementedException();
}
public IHeapifyable<K, D> KthMinElement(int k)
78. {
// You should replace this plug by your code.
throw new NotImplementedException();
}
}
}
Code Handout/Student/IHeapifyable.cs
namespace Heap
{
public interface IHeapifyable<K, D>
{
D Data { get; set; }
K Key { get; }
int Position { get; }
}
}
79. Code Handout/Student/Tester.cs
using System;
using System.Collections.Generic;
namespace Heap
{
class Tester
{
private class IntAscendingComparer : IComparer<int>
{
public int Compare(int A, int B)
{
return Math.Sign(A - B);
}
}
private class IntDescendingComparer : IComparer<int>
81. int[] certificateMaxHeapBuild = new int[] { 11, 10, 14,
4, 5, 12, 7, 8, 9, 2, 1, 6, 13, 3 };
// ------------------------ test instance (end)
Heap<int, string> minHeap = null;
Heap<int, string> maxHeap = null;
IHeapifyable<int, string>[] nodes = null;
string result = "";
// test 1
try
{
Console.WriteLine("nnTest A: Create a min-heap
by calling 'minHeap = new Heap<int, string>(new
IntAscendingComparer());'");
minHeap = new Heap<int, string>(new
IntAscendingComparer());
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
result = result + "A";
82. }
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 2
try
{
Console.WriteLine("nnTest B: Run a sequence of
operations: ");
for (int i = 0; i < Math.Min(names.Length,
IDs.Length); i++)
{
Console.WriteLine("nInsert a node with name {0}
(data) and ID {1} (key).", names[i], IDs[i]);
83. IHeapifyable<int, string> node =
minHeap.Insert(IDs[i], names[i]);
if (!(node.Position == certificateAdd[i] &&
minHeap.Count == i + 1)) throw new Exception("The min-heap
has a wrong structure");
Console.WriteLine(" :: SUCCESS: min-heap's
state " + minHeap.ToString());
}
result = result + "B";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 3
84. try
{
Console.WriteLine("nnTest C: Run a sequence of
operations: ");
for (int i = 0; i < certificateDelete.Length; i++)
{
Console.WriteLine("nDelete the minimum
element from the min-heap.");
IHeapifyable<int, string> node =
minHeap.Delete();
if (node.Key != certificateDelete[i]) throw new
Exception("The extracted node has a wrong key");
if (minHeap.Count != certificateDelete.Length - i -
1) throw new Exception("The heap has a wrong number of
elements");
if (certificateDelete.Length - i - 1 > 0)
{
if ((minHeap.Min().Key != certificateDelete[i +
1]) && (minHeap.Min().Position != 1)) throw new
Exception("The min-heap has a wrong structure");
}
85. Console.WriteLine(" :: SUCCESS: min-heap's
state " + minHeap.ToString());
}
result = result + "C";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 4
try
{
Console.WriteLine("nnTest D: Delete the minimum
element from the min-heap.");
IHeapifyable<int, string> node = minHeap.Delete();
Console.WriteLine("Last operation is invalid and
86. must throw InvalidOperationException. Your solution does not
match specification.");
result = result + "-";
}
catch (InvalidOperationException)
{
Console.WriteLine(" :: SUCCESS:
InvalidOperationException is thrown because the min-heap is
empty");
result = result + "D";
}
catch (Exception)
{
Console.WriteLine(" :: FAIL: min-heap's state " +
minHeap.ToString());
Console.WriteLine("Last operation is invalid and
must throw InvalidOperationException. Your solution does not
match specification.");
result = result + "-";
}
87. // test 5
try
{
Console.WriteLine("nnTest E: Run a sequence of
operations: ");
Console.WriteLine("nInsert a node with name {0}
(data) and ID {1} (key).", names[0], IDs[0]);
IHeapifyable<int, string> node =
minHeap.Insert(IDs[0], names[0]);
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nBuild the min-heap for the
pair of key-value arrays with n[{0}] as keys and n[{1}] as data
elements", String.Join(", ", IDs), String.Join(", ", names));
nodes = minHeap.BuildHeap(IDs, names);
Console.WriteLine("Last operation is invalid and
must throw InvalidOperationException. Your solution does not
match specification.");
result = result + "-";
}
catch (InvalidOperationException)
88. {
Console.WriteLine(" :: SUCCESS:
InvalidOperationException is thrown because the min-heap is
not empty");
result = result + "E";
}
catch (Exception)
{
Console.WriteLine(" :: FAIL: min-heap's state " +
minHeap.ToString());
Console.WriteLine("Last operation is invalid and
must throw InvalidOperationException. Your solution does not
match specification.");
result = result + "-";
}
// test 6
try
{
Console.WriteLine("nnTest F: Run a sequence of
operations: ");
89. Console.WriteLine("nClear the min-heap.");
minHeap.Clear();
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nBuild the min-heap for the
pair of key-value arrays with n[{0}] as keys and n[{1}] as data
elements", String.Join(", ", IDs), String.Join(", ", names));
nodes = minHeap.BuildHeap(IDs, names);
if (minHeap.Count !=
certificateMinHeapBuild.Length) throw new Exception("The
resulting min-heap has a wrong number of elements.");
if (nodes.Length != certificateMinHeapBuild.Length)
throw new Exception("The size of the resulting array returned
by BuildHeap() is incorrect.");
for (int i = 0; i < nodes.Length; i++)
{
if (!(nodes[i].Position ==
certificateMinHeapBuild[i])) throw new Exception("The min-
heap has a wrong structure");
}
result = result + "F";
Console.WriteLine(" :: SUCCESS: min-heap's state "
90. + minHeap.ToString());
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 7
try
{
Console.WriteLine("nnTest G: Run a sequence of
operations: ");
IHeapifyable<int, string> node = nodes[nodes.Length
- 1];
91. Console.WriteLine("nDelete the minimum element
from the min-heap.");
minHeap.Delete();
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nDelete the minimum element
from the min-heap.");
minHeap.Delete();
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
Console.WriteLine("nRun DecreaseKey(node,0) for
node {0} by setting the new value of its key to 0", node);
minHeap.DecreaseKey(node, 0);
if (minHeap.Count !=
certificateMinHeapBuild.Length - 2) throw new Exception("The
resulting min-heap has a wrong number of elements");
if (!((node.Position == 1) && (minHeap.Min().Key
== node.Key))) throw new Exception("The min-heap has a
wrong structure");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
92. result = result + "G";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 8
try
{
Console.WriteLine("nnTest H: Run a sequence of
operations: ");
Console.WriteLine("nCreate a max-heap by calling
'maxHeap = new Heap<int, string>(new
IntDescendingComparer());'");
maxHeap = new Heap<int, string>(new
93. IntDescendingComparer());
Console.WriteLine(" :: SUCCESS: max-heap's state "
+ maxHeap.ToString());
Console.WriteLine("nBuild the max-heap for the
pair of key-value arrays with n[{0}] as keys and n[{1}] as data
elements", String.Join(", ", IDs), String.Join(", ", names));
nodes = maxHeap.BuildHeap(IDs, names);
if (maxHeap.Count !=
certificateMaxHeapBuild.Length) throw new Exception("The
resulting max-heap has a wrong number of elements");
if (nodes.Length != certificateMaxHeapBuild.Length)
throw new Exception("The size of the resulting array returned
by BuildHeap() is incorrect.");
for (int i = 0; i < nodes.Length; i++)
{
if (!(nodes[i].Position ==
certificateMaxHeapBuild[i])) throw new Exception("The max-
heap has a wrong structure");
}
result = result + "H";
Console.WriteLine(" :: SUCCESS: max-heap's state "
+ maxHeap.ToString());
}
94. catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: max-heap's state
" + maxHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
// test 9
try
{
Console.WriteLine("nnTest I: Run a sequence of
operations: ");
IHeapifyable<int, string> node = nodes[4];
Console.WriteLine("nDelete the Richard element
from the min-heap.");
IHeapifyable<int, string> r =
minHeap.DeleteElement(node);
95. if (!r.Data.Equals(node.Data)) throw new
Exception("The deleted node is the incorrect node.");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
if (minHeap.Count !=
certificateMinHeapBuild.Length - 3) throw new Exception("The
resulting min-heap has a wrong number of elements");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
result = result + "I";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
96. // test 10
try
{
Console.WriteLine("nnTest J: Run a sequence of
operations: ");
Console.WriteLine("min-heap's state " +
minHeap.ToString());
IHeapifyable<int, string> node =
minHeap.KthMinElement(4);
if (!node.Data.Equals("John")) throw new
Exception("The 4th deleted node" + node.ToString() + " is the
incorrect node.");
Console.WriteLine(" :: SUCCESS: 4th Node is " +
node.ToString());
if (minHeap.Count !=
certificateMinHeapBuild.Length - 3) throw new Exception("The
resulting min-heap has a wrong number of elements");
Console.WriteLine(" :: SUCCESS: min-heap's state "
+ minHeap.ToString());
97. result = result + "J";
}
catch (Exception exception)
{
try { Console.WriteLine(" :: FAIL: min-heap's state "
+ minHeap.ToString()); } catch { };
Console.WriteLine(exception.ToString());
result = result + "-";
}
Console.WriteLine("nn ------------------- SUMMARY -
------------------ ");
Console.WriteLine("Tests passed: " + result);
Console.ReadKey();
}
}
98. }
18 BioPharm International www.biopharminternational.com
September 2010
Perspectives on Outsourcing
D
o
n
F
a
rr
a
ll
/G
e
tt
y
I
m
a
g
e
s
99. A
fter your R&D team has had a “Eureka!”
moment, the first order of business is
to engage in process development and
production of the product for clinical supply.
Perhaps that moment came a few years ago and
now you need to ensure that you can supply
enough product to meet commercial demand.
Do you choose to build or retrofit your own
manufacturing plant or do you buy via out-
sourcing to a contract manufacturing organiza-
tion (CMO)? This complex decision shouldn’t
be made lightly because it could affect nearly
everything about your business, including your
company’s financial situation, intellectual prop-
erty position, and business and product goals.
THE CURRENT MARKET
In 2009, many small- to medium-sized bio-
pharmaceutical companies struggled to raise
100. funds for their product development and man-
ufacturing projects, while large, financially
stable companies reigned in spending and
reassessed their pipelines. The building of new
manufacturing facilities decreased, possibly
reflecting changes in business philosophies as
well as a reduced ability by the pharmaceutical
and biotech companies to prog-
ress with construction.1,2 At the
same time, the global CMO market
declined to approximately $2.6 bil-
lion, a reduction from years past.3
In general, CMOs saw a drop in
requests for proposal, more sensi-
tivity to pricing from potential cli-
ents, and there was (and continues
to be) increased level of competi-
tiveness amongst CMOs. At least
101. one CMO closed its doors (QSV
Biolog ics). Mergers and acquisi-
tions also changed the landscape
of the CMO business, as CMOs of
all sizes and capabilities were integrated into
larger pharmaceutical or biotech companies
( Watson Pha r maceut ica ls/E den Biodesig n;
Merck/Avecia; Recipharm/Cobra).
Today, the business environment seems to
be on the rebound: interest in pipelines includ-
ing biologics remains strong, and for compa-
nies considering outsourcing, CMO capacity
is broadly available (though, perhaps because
of the acquisitions of 2009, capacity may not
remain readily available). Process economics
continue to improve through leaps in produc-
tivity and the acceptance of new production
technologies. There is a wider array of product
102. types requiring cGMP manufacture, includ-
ing the emergence of biosimilars as originator
product patents expire. But the industry has
learned some valuable lessons as a result of the
tumult of 2009. Companies remain cautious
when evaluating requirements for risk shar-
ing, product quality compliance, and business
partner compatibility. Cost-containment is still
paramount and everyone is looking to manage
their project budgets efficiently.
HOW TO DECIDE
When deciding whether to build your own
capacity or buy it from a CMO, prioritization
of what is most important to you as a com-
pany should be key. Although your available
budget and the return on investment must be
considered, your choice shouldn’t be made on
potential costs alone. Several factors should be
103. weighed before you make your choice:
• Risk tolerance: Are you willing to put some
(or all) of the responsibilit y for product
development and manufacturing into the
hands of a trusted partner?
• People/exper tise/core competencies: Can
you assemble a team to execute various proj-
ect tasks, or do you require support from an
Build Versus Buy in the Current
Biotech Market Environment
Factors such as production scale and intellectual property must
be considered
when deciding whether to build your own capacity or buy it
from a CMO
Maria Lusk is a director of client
management at Eden Biodesign, a part
of the Watson Group, Liverpool, UK,
919.806.4234,
[email protected]
20 BioPharm International www.biopharminternational.com
September 2010
104. Perspectives on Outsourcing
external source for things like
basic process development and
manufacturing, or for specialized
activities like fill-and-finish?
• Manufacturing scale and pro-
duction forecast: How much of
your product will you need to
complete your clinical trials or
to support commercial demand?
Will your company have avail-
able capacity at the proper pro-
duction scale to meet your needs?
• Technology: What technologies
will be required to manufacture,
test, and finish your product?
Do you already have the appro-
priate science and equipment in
105. place? Do you have the budget
and time to obtain the required
technology, or is partnering with
a CMO the best option?
• Ti mel i ne s: Is t here pressu re
from investors or the market to
achieve a clinical or commercial
milestone by a particular date?
How will the required project
tasks fit with the expected time-
line? Will building or retrofitting
a facility fit with the timeline, or
do you need to use a CMO to
achieve your milestones?
• Geography/cultures/currencies/
com mu n icat ion: Does closer
necessar ily mean better? A re
currency exchange rates critical
106. to your project budget? Are you
prepared to communicate across
various time zones and possibly
cultural influences?
• Regulatory affairs (RA)/clinical
sites: What is your target market
and will you need to include
severa l locat ions a rou nd t he
globe in your plan to submit a
regulatory filing? Do you need
to have your own facility and
R A staff in the same location
as the clinical sites? Is there a
CMO out there that can fully
support your regulatory plans?
• Intellectual proper ty/control:
Does you r compa ny w ish to
control its IP completely, or are
107. you willing to share your know-
how with a trusted CMO part-
ner? Will you grant a license to
a business partner who will take
your product through to com-
mercialization, or do you prefer
to maintain control, including
manufacturing, throughout the
product’s lifecycle?
• Number of products and their
development/clinical phase: You
should plan for success, but the
“what ifs” of failure also need
to be considered. Do you have
one or two products in the early
phase of development, or is your
por t folio well balanced w it h
products in all stages of clinical
108. development and clinical trials?
It does not make sense to build
a new facility if your pipeline
cannot support it.
GREENFIELD OR RETROFIT?
If you have the option to build a
facility from scratch (“greenfield”)
or to retrofit an existing space, you
must carefully scrutinize what is
available to support the production
of your product. A greenfield facil-
ity will be fit for purpose from the
beginning, but various challenges
may arise for a company that cho-
ses to build, including keeping to
the construction budget and time-
line; employing people with the
proper background to ensure that
109. the facility is fit for purpose; and
training staff to install, validate,
and operate equipment. On the
other hand, it may be more dif-
ficult to retrofit an existing space
because the existing space must
be able to accommodate the new
equipment while perhaps main-
taining (and re-validating) some
of the legacy infrastructure (e.g.,
clean-in-place and steam-in-place
skids, utilities, tanks, water supply).
Any compromises in facility design
will need to be weighed against
planned production and regulatory
requirements.
If you do decide to build, consider
that there are several manufacturing
110. technologies to choose from:
• Disposable, single-use, or limited-
use manufacturing equipment:
Some of the benefits of these
components and systems include
a low initial capital outlay, fast
installation, and reduced routine
operating costs, because these can
reduce or eliminate the require-
ment for cleaning or cleaning
validation. Although the use of a
completely disposable production
train is not common, biotechnol-
ogy companies are beginning to
investigate this as an option.4 For
particular types of products such
as viral vaccines, disposables are
indispensable.
111. • St a i n le ss - steel systems on ly:
Stainless-steel systems are proven
for manufacturing products reli-
ably and reproducibly; the tech-
nology is common, so process
transfer between manufactur-
ing sites (internal and external)
is relat ively st ra ight for wa rd,
and these systems can support
various types of products. But
consideration should be given
to budget and timeline require-
ments for installation because
they tend to be expensive and
time-consuming to order, install,
and validate. Cleaning will be
a continuous challenge for the
lifetime of the system.
112. Before making the decision to buy, get to
know your potential CMO partner. Ask questions
and be prepared to answer some, too.
September 2010 www.biopharminternational.com
BioPharm International 21
Perspectives on Outsourcing
• Hybrid systems consisting of dis-
posable and stainless-steel com-
ponents: This option seems to be
the most popular for manufac-
turing biopharmaceutical prod-
ucts.4 Systems can be designed
to meet your facility and prod-
uct requirements, using a “best
of both worlds” approach.
Before mak ing your decision
to build or retrofit, consider that
regardless of the equipment you
113. choose to install, maintenance
and mater ials supply w ill be a
continuous endeavor. Planning
for time and costs to operate and
maintain these systems should be
included in your overall product
lifecycle design.
ARE CMOS THE ANSWER?
An alternative to building or ret-
rofitting a facilit y is to partner
with a CMO. Indeed, innovator
companies have started looking
at the strategic benefits of engag-
ing CMOs to support their prod-
ucts throughout their lifecycle:
in general, it is likely t hat t he
CMO’s facilit y and qualit y sys-
te m s a l r e ad y me e t r eg u l ator y
114. requirements, including interna-
tional regulations; an innovator
company can choose a CMO in a
particular location (or locations)
as there continues to be signifi-
c a nt C M O b u s i n e s s d e v e l o p -
ment in Singapore, Israel, Japan,
and the BR IC countries (Brazil,
Russia, India, and China); CMOs
are differentiating themselves by
increasingly offering specialized
technolog ies a nd ser v ices, a nd
several major CMOs are engag-
ing the innovator companies by
e x plor i ng a lte r nat ive bu si ne ss
models. In addition, companies
have access to C MO s t hat a re
already prepared to not only man-
115. ufac t ure a my r iad of produc ts,
but also provide you with tech-
nologies and personnel already in
place to “hit the ground running”
in support of your project needs.
Expression Systems
O ne of t he b e ne f it s of work-
i n g w i t h a C M O i s t h a t i n
s ome i n st a nc e s t he I P hold e r
f o r a p a r t i c u l a r e x p r e s -
s i o n s y s t e m i s t h e C M O
(for e x a mple, G - Pe x /C at a le nt;
G S/ L on z a; BI - H E X / B ohe r i nge r
I n g e l h i e m ; C H E F - 1 / C M C
Biologics), or a technolog y may
be available to the CMO (SUR E
( S e l e x i s), U C O E ( M i l l i p o r e)/
E den Biodesig n) a nd accessi ng
116. it through the CMO may allow
your company to obtain prefer-
ential business terms. Discussion
of available options that may be
most appropriate for the produc-
tion of your product should be
based on your company’s supply
requirements (current and future);
your available budget; any target
product delivery date(s); and your
c omp a ny ’s r i sk tole r a nc e a nd
regulatory strategy.
NICHE TECHNOLOGIES
There are a few areas of special-
ization that commonly are out-
sourced by innovator companies,
including those who have their
own internal manufacturing capa-
bility. These include:
117. • Product characterization: This usu-
ally includes highly specialized
analytical techniques such as
mass spectrometry, amino acid
analysis and post-translational
modification analysis. Because
these analytical methods usually
require expensive equipment and
highly skilled technicians, many
companies choose to engage the
services of an external contract
testing house.
• Drug product fill-and-finish: This
can include vial fill and lyophi-
lization, combination products,
and transdermal patches.
• V i r a l p r o d u c t p r o d u c t i o n :
There are several product types
118. in development requiring spe-
cialized knowledge and exper-
t i se. E x a mple s i nc lude v i ra l
vaccines, gene therapies, and
cell culture products compris-
i ng or made usi ng bac u lov i-
ruses, adenoviruses, or a wide
variety of other viruses. Some
i n novator compa n ies choose
to outsource the production of
these types of product because
of constraints in their existing
facility (e.g., segregation of pro-
duction suites and air handling
units), technical expertise, or
regulatory requirements.
FINAL THOUGHTS
B efore ma k i ng t he dec ision to
119. b uy, get to k now you r p ote n-
tial CMO partner. Ask questions
and be prepared to answer some
too. You should understand and
t hen sha re what you r expec ta-
tions are for working with your
c hose n C MO, a nd you shou ld
have an understanding of how its
capabilities stack up against your
internal capabilities and project
requirements.
In general, those who choose to
build tend to be the large pharma-
ceutical and biotech companies that
have sturdy pipelines and plenty of
cash on hand. Smaller companies
with fewer products and less cash
often outsource production of their
120. products. But regardless of who you
are, the choice to build or buy is one
that could have a significant impact
on your present and future busi-
ness success, and therefore should
be made very carefully. ◆
REFERENCES
1. Langer E. Build or Buy? Strategic
Choices in Biomanufacturing.
2010 BIO International Convention.
Chicago, IL. 2010 May 3–7.
2. Bush L. Build or Buy? Strategic
Choices in Biomanufacturing.
2010 BIO International Convention.
Chicago, IL. 2010 May 3–7.
3. Liu C, William D. State of the bio-
CMO market. Contract Pharma.
2010;12(3).
4. Hoffman M. Trends in bioprocessing.
121. Bioprocessing and sterile
manufacturing 2010 survey. Pharm
Tech suppl. 2010;34(3):s4–s7.
Reproduced with permission of the copyright owner. Further
reproduction prohibited without permission.
Discussion: Ideal Alliance Partners
In thinking about ideal alliance partners, Microsoft and Apple
may not immediately spring to mind. But in fact, these often
fierce competitors have a surprising history of collaboration;
take for example, Office for Mac 2011. Working with, rather
than against Apple, “Microsoft has once again made the Mac OS
X version of its world-dominant productivity suite jive a lot
more closely with the latest Windows version” (Hiner, 2010).
In “Finding the Ideal Partner,” Kwicien (2012) asserts that
many organizations can grow only by forming business
alliances. HR executives are increasingly being called upon to
find suitable alliance partners. When considering potential
alliance candidates, Kwicien emphasizes the need to think
originally, or “outside the box.” He provides seven
characteristics of the ideal alliance partner. One way for HR to
encourage original thinking would be to ask the C-suite to
consider new factors not previously considered when evaluating
potential alliance partners. Drawing on the Required Resources
and your own additional research, suggest three other plausible
ways for HR to facilitate new ways of thinking about potential
alliance partners.
Do you see any risk for the HR department in leading the charge
of thinking outside the box in this regard? From a risk versus
122. reward perspective, how might the HR department fail the
organization by selecting non-traditional candidates?
To prepare for this Discussion,
Review this week’s Learning Resources, especially:
· https://www.amanet.org/articles/the-right-way-to-make-
alliances-work/
· Finding the ideal partner:– See pdf
· Build Versus Buy in the Current– See pdf
· Managing business processes – See pdf
Assignment:
Post a cohesive and scholarly response based on your readings
and research this week that addresses the following:
· As an HR executive charged with finding ways to expand an
organization, conduct additional research on characteristics of
ideal alliance candidates.
· Describe a successful partnership that you found in your
research. Would you characterize it as ideal relative to
Kwicien’s seven characteristics?
· Cite an example of a partnership that initially appeared to be
ideal, but failed to come together as hoped.
· Describe how it has progressed thus far.
· If less-than-ideal partnerships can succeed, what is the lesson
in that for HR professionals?
· Accepting Kwicien’s premise about “thinking outside the
box,” suggest at least three ways for HR to facilitate original
thinking in searching for alliance partners.
· Justify the use of a limited HR budget in pursuing “outside the
box” alliance partners.
· What are possible negative consequences for HR in
encouraging original thinking in the search for ideal alliance
partners?