Skip to content

Commit 3d40102

Browse files
committed
2 parents 9941175 + 84b56ed commit 3d40102

12 files changed

Lines changed: 1893 additions & 7 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@
2525
/Test_Numerics/.vs
2626
/Test_Numerics/bin
2727
/Test_Numerics/obj
28+
/Numerics/.vs/Numerics
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/**
2+
* NOTICE:
3+
* The U.S. Army Corps of Engineers, Risk Management Center (USACE-RMC) makes no guarantees about
4+
* the results, or appropriateness of outputs, obtained from Numerics.
5+
*
6+
* LIST OF CONDITIONS:
7+
* Redistribution and use in source and binary forms, with or without modification, are permitted
8+
* provided that the following conditions are met:
9+
* ● Redistributions of source code must retain the above notice, this list of conditions, and the
10+
* following disclaimer.
11+
* ● Redistributions in binary form must reproduce the above notice, this list of conditions, and
12+
* the following disclaimer in the documentation and/or other materials provided with the distribution.
13+
* ● The names of the U.S. Government, the U.S. Army Corps of Engineers, the Institute for Water
14+
* Resources, or the Risk Management Center may not be used to endorse or promote products derived
15+
* from this software without specific prior written permission. Nor may the names of its contributors
16+
* be used to endorse or promote products derived from this software without specific prior
17+
* written permission.
18+
*
19+
* DISCLAIMER:
20+
* THIS SOFTWARE IS PROVIDED BY THE U.S. ARMY CORPS OF ENGINEERS RISK MANAGEMENT CENTER
21+
* (USACE-RMC) "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
* DISCLAIMED. IN NO EVENT SHALL USACE-RMC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
* **/
30+
31+
using System;
32+
using System.Collections.Generic;
33+
using System.Linq;
34+
using System.Text;
35+
using System.Threading.Tasks;
36+
37+
namespace Numerics.Mathematics.Optimization
38+
{
39+
40+
/// <summary>
41+
/// This is an implementation of the binary heap data structure. The binary heap is especially convenient for shortest path algorithms
42+
/// such as Djikstra's shortest path.
43+
/// source of inspiration: http://opendatastructures.org/versions/edition-0.1e/ods-java/10_1_BinaryHeap_Implicit_Bi.html
44+
/// </summary>
45+
/// <typeparam name="T">Generic variable to store with each node. Typically used to store important data associated with the network that isn't required for the binary heap.</typeparam>
46+
public class BinaryHeap<T>
47+
{
48+
public struct Node
49+
{
50+
public float Weight;
51+
public int Index;
52+
public T Value;
53+
54+
public Node(float nodeWeight, int nodeIndex, T nodeValue)
55+
{
56+
Weight = nodeWeight;
57+
Index = nodeIndex;
58+
Value = nodeValue;
59+
}
60+
}
61+
62+
private readonly Node[] _heap;
63+
private int _n = 0; // Number of nodes.
64+
private int _p = 0; // Parent Index
65+
66+
public int Count => _n;
67+
68+
public BinaryHeap(int heapSize)
69+
{
70+
_heap = new Node[heapSize];
71+
}
72+
73+
/// <summary>
74+
/// Add a node to the heap.
75+
/// </summary>
76+
/// <param name="value">Node to add.</param>
77+
public void Add(Node value)
78+
{
79+
_heap[_n] = value;
80+
_n += 1;
81+
82+
//Push the node up the tree.
83+
if (_n <= 1) return;
84+
int i = _n - 1;
85+
_p = (i - 1) / 2; // parent index (use integer division).
86+
Node parentNode = _heap[_p];
87+
Node currentNode = value;
88+
89+
while (i > 0 && currentNode.Weight < parentNode.Weight)
90+
{
91+
_heap[i] = parentNode;
92+
_heap[_p] = currentNode;
93+
i = _p;
94+
_p = (i - 1) / 2; // parent index (use integer division).
95+
parentNode = _heap[_p];
96+
currentNode = _heap[i];
97+
}
98+
}
99+
100+
/// <summary>
101+
/// Remove the minimum (top) node from the heap.
102+
/// </summary>
103+
/// <returns></returns>
104+
public Node RemoveMin()
105+
{
106+
Node result = _heap[0];
107+
108+
//Push the empty node down the tree then replace with last node in array
109+
int r;
110+
int l;
111+
int i = 0;
112+
int pIndex = 0;
113+
Node lNode;
114+
Node rNode;
115+
do
116+
{
117+
r = 2 * i + 2; //right child index
118+
l = r - 1; //left child index
119+
if (r < _n)
120+
{
121+
lNode = _heap[l];
122+
rNode = _heap[r];
123+
if (lNode.Weight < rNode.Weight)
124+
{
125+
_heap[i] = lNode;
126+
pIndex = i;
127+
i = l;
128+
}
129+
else
130+
{
131+
_heap[i] = rNode;
132+
pIndex = i;
133+
i = r;
134+
}
135+
}
136+
else
137+
{
138+
if (l < _n)
139+
{
140+
_heap[i] = _heap[l];
141+
pIndex = i;
142+
i = l;
143+
}
144+
else
145+
{
146+
break;
147+
}
148+
}
149+
} while (i >= 0);
150+
//
151+
_n -= 1;
152+
//Replace with last node in array and push up.
153+
if (i != _n)
154+
{
155+
_heap[i] = _heap[_n];
156+
if (_heap[pIndex].Weight > _heap[i].Weight)
157+
{
158+
//Push the node up.
159+
if (i <= 0) return result;
160+
_p = pIndex;
161+
Node parentNode = _heap[_p];
162+
Node currentNode = _heap[i];
163+
while (i > 0 && currentNode.Weight < parentNode.Weight)
164+
{
165+
_heap[i] = parentNode;
166+
_heap[_p] = currentNode;
167+
i = _p;
168+
_p = (i - 1) / 2; // parent index (use integer division).
169+
parentNode = _heap[_p];
170+
currentNode = _heap[i];
171+
}
172+
}
173+
}
174+
//
175+
return result;
176+
}
177+
178+
/// <summary>
179+
/// Replace a node that has the same index value as the new node.
180+
/// </summary>
181+
/// <param name="newNode"></param>
182+
public void Replace(Node newNode)
183+
{
184+
for (int i = 0; i < _n; i++)
185+
{
186+
if (_heap[i].Index == newNode.Index)
187+
{
188+
_heap[i] = newNode;
189+
//Push the node up the tree
190+
if (i <= 0) return;
191+
_p = (i - 1) / 2; // parent index (use integer division).
192+
Node parentNode = _heap[_p];
193+
Node currentNode = newNode;
194+
while (i > 0 && currentNode.Weight < parentNode.Weight)
195+
{
196+
_heap[i] = parentNode;
197+
_heap[_p] = currentNode;
198+
i = _p;
199+
_p = (i - 1) / 2;
200+
parentNode = _heap[_p];
201+
currentNode = _heap[i];
202+
}
203+
break;
204+
}
205+
}
206+
}
207+
208+
209+
}
210+
}

0 commit comments

Comments
 (0)