C# recursively calculate value
I have following table
I need to work out the values in columns X, Y and Z.
Rule 1: code only has children as X, Y, or Z.
Let's start from a simple one, row 12, code 'E2' has a child called 'Z' and value is 3.30, so cell [F12] (column Z) should have 3.30. We can denote as f(12)= 3.30Z, Similarly, cell [E11] should be 2.10, or f(11)=2.10Y. For row 6, cell[D6] should be 1.14, denote as f(6)=1.14X.
note, code X,Y,Z do not have children themselves. However, other children can have grand children, recursively.
Rule 2: If a code has a child, then the value will be its own value times whatever the child code value.
e.g. row 10, it has a child 'E2', so the value will be its value 3.10 times whatever the children (E2) value, i.e. f(10)=3.10*f(12)=3.10*3.30Z=10.23Z, cell[F10] should be 10.23
Rule 3, if a code has multiple children, then the value will be sum for all the children group by type, following Rule 2
e.g. row 5 C1 has a child D, and D has three children (X, E1, E2), the 3 children values needs to add together. f(5)=1.70*(f(8)+f(9)+f(10)). Of course, some children has X values, some has Y values, some has Z values, so when adding them up, they need to be grouped by value type, and then fill in the corresponding columns Cell[D5], Cell[E5], cell[F5]
Hope that makes sense.
This is a simplified version of the original more complicated question which has thousands of rows, and some other calculations. But not a huge table, so performance or speed is not priority consideration.
It is more of an algorithm issue, but I prefer to implement in C#
c# algorithm recursion
|
show 4 more comments
I have following table
I need to work out the values in columns X, Y and Z.
Rule 1: code only has children as X, Y, or Z.
Let's start from a simple one, row 12, code 'E2' has a child called 'Z' and value is 3.30, so cell [F12] (column Z) should have 3.30. We can denote as f(12)= 3.30Z, Similarly, cell [E11] should be 2.10, or f(11)=2.10Y. For row 6, cell[D6] should be 1.14, denote as f(6)=1.14X.
note, code X,Y,Z do not have children themselves. However, other children can have grand children, recursively.
Rule 2: If a code has a child, then the value will be its own value times whatever the child code value.
e.g. row 10, it has a child 'E2', so the value will be its value 3.10 times whatever the children (E2) value, i.e. f(10)=3.10*f(12)=3.10*3.30Z=10.23Z, cell[F10] should be 10.23
Rule 3, if a code has multiple children, then the value will be sum for all the children group by type, following Rule 2
e.g. row 5 C1 has a child D, and D has three children (X, E1, E2), the 3 children values needs to add together. f(5)=1.70*(f(8)+f(9)+f(10)). Of course, some children has X values, some has Y values, some has Z values, so when adding them up, they need to be grouped by value type, and then fill in the corresponding columns Cell[D5], Cell[E5], cell[F5]
Hope that makes sense.
This is a simplified version of the original more complicated question which has thousands of rows, and some other calculations. But not a huge table, so performance or speed is not priority consideration.
It is more of an algorithm issue, but I prefer to implement in C#
c# algorithm recursion
2
This is a very broad question, which makes it hard for us to answer. If you've tried something, and have a specific issue, maybe we can help with that instead?
– Richard Everett
Nov 27 '18 at 2:14
3
Please provide a Minimal, Complete, and Verifiable example
– Jeremy Thompson
Nov 27 '18 at 2:22
It's not clear at all which part you're stuck on. Please show the code that's not working as you expect it to (SO is not a code-writing service).
– Rufus L
Nov 27 '18 at 2:49
Peeyush. the data is correct. The code represents chemical components. For example row 6 means there is 1.14 % of component X within component C1. The original chemical code are very complicated, I replaced them with pseudo code here to simply the problem.
– ppau2004
Nov 27 '18 at 2:50
Rufus, I am not sure where to start this code. this is definitely not a for each loop and has to be some sort of recursion, but I am not sure how to do. I will continue to work on it, hopefully, get a solution and post it here. In the meantime, anyone gives me some suggestions will be highly appreciated.
– ppau2004
Nov 27 '18 at 2:54
|
show 4 more comments
I have following table
I need to work out the values in columns X, Y and Z.
Rule 1: code only has children as X, Y, or Z.
Let's start from a simple one, row 12, code 'E2' has a child called 'Z' and value is 3.30, so cell [F12] (column Z) should have 3.30. We can denote as f(12)= 3.30Z, Similarly, cell [E11] should be 2.10, or f(11)=2.10Y. For row 6, cell[D6] should be 1.14, denote as f(6)=1.14X.
note, code X,Y,Z do not have children themselves. However, other children can have grand children, recursively.
Rule 2: If a code has a child, then the value will be its own value times whatever the child code value.
e.g. row 10, it has a child 'E2', so the value will be its value 3.10 times whatever the children (E2) value, i.e. f(10)=3.10*f(12)=3.10*3.30Z=10.23Z, cell[F10] should be 10.23
Rule 3, if a code has multiple children, then the value will be sum for all the children group by type, following Rule 2
e.g. row 5 C1 has a child D, and D has three children (X, E1, E2), the 3 children values needs to add together. f(5)=1.70*(f(8)+f(9)+f(10)). Of course, some children has X values, some has Y values, some has Z values, so when adding them up, they need to be grouped by value type, and then fill in the corresponding columns Cell[D5], Cell[E5], cell[F5]
Hope that makes sense.
This is a simplified version of the original more complicated question which has thousands of rows, and some other calculations. But not a huge table, so performance or speed is not priority consideration.
It is more of an algorithm issue, but I prefer to implement in C#
c# algorithm recursion
I have following table
I need to work out the values in columns X, Y and Z.
Rule 1: code only has children as X, Y, or Z.
Let's start from a simple one, row 12, code 'E2' has a child called 'Z' and value is 3.30, so cell [F12] (column Z) should have 3.30. We can denote as f(12)= 3.30Z, Similarly, cell [E11] should be 2.10, or f(11)=2.10Y. For row 6, cell[D6] should be 1.14, denote as f(6)=1.14X.
note, code X,Y,Z do not have children themselves. However, other children can have grand children, recursively.
Rule 2: If a code has a child, then the value will be its own value times whatever the child code value.
e.g. row 10, it has a child 'E2', so the value will be its value 3.10 times whatever the children (E2) value, i.e. f(10)=3.10*f(12)=3.10*3.30Z=10.23Z, cell[F10] should be 10.23
Rule 3, if a code has multiple children, then the value will be sum for all the children group by type, following Rule 2
e.g. row 5 C1 has a child D, and D has three children (X, E1, E2), the 3 children values needs to add together. f(5)=1.70*(f(8)+f(9)+f(10)). Of course, some children has X values, some has Y values, some has Z values, so when adding them up, they need to be grouped by value type, and then fill in the corresponding columns Cell[D5], Cell[E5], cell[F5]
Hope that makes sense.
This is a simplified version of the original more complicated question which has thousands of rows, and some other calculations. But not a huge table, so performance or speed is not priority consideration.
It is more of an algorithm issue, but I prefer to implement in C#
c# algorithm recursion
c# algorithm recursion
asked Nov 27 '18 at 2:11
ppau2004ppau2004
6410
6410
2
This is a very broad question, which makes it hard for us to answer. If you've tried something, and have a specific issue, maybe we can help with that instead?
– Richard Everett
Nov 27 '18 at 2:14
3
Please provide a Minimal, Complete, and Verifiable example
– Jeremy Thompson
Nov 27 '18 at 2:22
It's not clear at all which part you're stuck on. Please show the code that's not working as you expect it to (SO is not a code-writing service).
– Rufus L
Nov 27 '18 at 2:49
Peeyush. the data is correct. The code represents chemical components. For example row 6 means there is 1.14 % of component X within component C1. The original chemical code are very complicated, I replaced them with pseudo code here to simply the problem.
– ppau2004
Nov 27 '18 at 2:50
Rufus, I am not sure where to start this code. this is definitely not a for each loop and has to be some sort of recursion, but I am not sure how to do. I will continue to work on it, hopefully, get a solution and post it here. In the meantime, anyone gives me some suggestions will be highly appreciated.
– ppau2004
Nov 27 '18 at 2:54
|
show 4 more comments
2
This is a very broad question, which makes it hard for us to answer. If you've tried something, and have a specific issue, maybe we can help with that instead?
– Richard Everett
Nov 27 '18 at 2:14
3
Please provide a Minimal, Complete, and Verifiable example
– Jeremy Thompson
Nov 27 '18 at 2:22
It's not clear at all which part you're stuck on. Please show the code that's not working as you expect it to (SO is not a code-writing service).
– Rufus L
Nov 27 '18 at 2:49
Peeyush. the data is correct. The code represents chemical components. For example row 6 means there is 1.14 % of component X within component C1. The original chemical code are very complicated, I replaced them with pseudo code here to simply the problem.
– ppau2004
Nov 27 '18 at 2:50
Rufus, I am not sure where to start this code. this is definitely not a for each loop and has to be some sort of recursion, but I am not sure how to do. I will continue to work on it, hopefully, get a solution and post it here. In the meantime, anyone gives me some suggestions will be highly appreciated.
– ppau2004
Nov 27 '18 at 2:54
2
2
This is a very broad question, which makes it hard for us to answer. If you've tried something, and have a specific issue, maybe we can help with that instead?
– Richard Everett
Nov 27 '18 at 2:14
This is a very broad question, which makes it hard for us to answer. If you've tried something, and have a specific issue, maybe we can help with that instead?
– Richard Everett
Nov 27 '18 at 2:14
3
3
Please provide a Minimal, Complete, and Verifiable example
– Jeremy Thompson
Nov 27 '18 at 2:22
Please provide a Minimal, Complete, and Verifiable example
– Jeremy Thompson
Nov 27 '18 at 2:22
It's not clear at all which part you're stuck on. Please show the code that's not working as you expect it to (SO is not a code-writing service).
– Rufus L
Nov 27 '18 at 2:49
It's not clear at all which part you're stuck on. Please show the code that's not working as you expect it to (SO is not a code-writing service).
– Rufus L
Nov 27 '18 at 2:49
Peeyush. the data is correct. The code represents chemical components. For example row 6 means there is 1.14 % of component X within component C1. The original chemical code are very complicated, I replaced them with pseudo code here to simply the problem.
– ppau2004
Nov 27 '18 at 2:50
Peeyush. the data is correct. The code represents chemical components. For example row 6 means there is 1.14 % of component X within component C1. The original chemical code are very complicated, I replaced them with pseudo code here to simply the problem.
– ppau2004
Nov 27 '18 at 2:50
Rufus, I am not sure where to start this code. this is definitely not a for each loop and has to be some sort of recursion, but I am not sure how to do. I will continue to work on it, hopefully, get a solution and post it here. In the meantime, anyone gives me some suggestions will be highly appreciated.
– ppau2004
Nov 27 '18 at 2:54
Rufus, I am not sure where to start this code. this is definitely not a for each loop and has to be some sort of recursion, but I am not sure how to do. I will continue to work on it, hopefully, get a solution and post it here. In the meantime, anyone gives me some suggestions will be highly appreciated.
– ppau2004
Nov 27 '18 at 2:54
|
show 4 more comments
2 Answers
2
active
oldest
votes
What you've described is a tree structure, which you can build easily enough, and then traverse recursively. You already know the parent/child relationships; you just have to create a model to represent them in code.
Start with an Element
class that looks like this:
class Element
{
string Code;
Element Parent; // null if no parent
double Value;
double CalculatedValue;
List<string> Children;
}
And create a dictionary of these, keyed by code:
Dictionary<string, Element> Elements;
Go through the list, adding creating an Element
for each unique element, and adding it to the dictionary:
(Note: code examples are in pseudo-C#. I don't want to get bogged down in syntax here.)
for each row
{
Element e;
// if the element doesn't exist in the dictionary, create and add it
if (!Elements.TryGetValue(code, out e))
{
e = new Element(code, value);
Elements.Add(code, e);
}
if (child != null)
{
e.Children.Add(child);
}
}
You now have a dictionary of elements, with the child relationships. You need to create the parent relationships. Easiest way is with a scan of the dictionary:
for each e in Elements
for each child in e.Children
if (child != "X" or "Y" or "Z")
Elements[child].Parent = e;
Now what you have is a forest: one or more unrooted trees. You can scan it recursively to compute your value:
double totalValue = 0;
for each e in Elements
if (e.Parent == null)
{
totalValue += calculateElementValue(e);
}
}
// at this point, totalValue should contain the total value
If I understood your rules correctly, this method should compute an individual element's value. I assumed that an element has only one of X, Y, or Z. This is a simple depth-first traversal of an element tree.
double CalculateElementValue(Element e)
{
double eValue = 0;
double childrenValue = 0;
for each child in e.Children
{
switch (child)
{
case "X": eValue = e.Value * xValue; break;
case "Y": eValue = e.Value * yValue; break;
case "Z": eValue = e.Value * zValue; break;
else
{
childrenValue += CalculateElementValue(Elements[child]);
}
}
}
return eValue * childrenValue;
}
You could include the parent assignment in the initial loop that builds the elements, but it complicates things a little bit. But unless the table has lots of rows, you probably won't notice a difference in speed.
add a comment |
Here are some example data structures you can use to represent your data, and recursively calculate values.
Note that this example uses indirect recursion. I.e. Node.Evaluate()
does not call itself directly, but instead calls WeightedChild.Evaluate()
which in turn calls back to Node.Evaluate()
.
public class Node
{
public Node(params WeightedChild weightedChildren)
{
this.WeightedChildren = weightedChildren ?? Enumerable.Empty<WeightedChild>();
}
IEnumerable<WeightedChild> WeightedChildren { get; }
public double Evaluate()
{
return this.WeightedChildren.Any()
? this.WeightedChildren.Select(child => child.Evaluate()).Sum()
: 1;
}
}
public class WeightedChild
{
public WeightedChild(double weight, Node child)
{
this.Weight = weight;
this.Child = child;
}
public double Weight { get; }
Node Child { get; }
public double Evaluate()
{
return this.Child.Evaluate() * this.Weight;
}
}
You can then use these classes to build your data set:
var X = new Node();
var Y = new Node();
var Z = new Node();
var E2 = new Node(new WeightedChild(3.3, Z));
var E1 = new Node(new WeightedChild(2.1, Y));
var D = new Node(
new WeightedChild(0.7, X),
new WeightedChild(1.8, E1),
new WeightedChild(3.1, E2));
var C2 = new Node(new WeightedChild(0.9, X));
var C1 = new Node(
new WeightedChild(1.14, X),
new WeightedChild(1.7, D));
var B = new Node(
new WeightedChild(1.3, C1),
new WeightedChild(1.5, C2));
var A = new Node(new WeightedChild(1.1, C1));
You can then evaluate each node:
Console.WriteLine($"f(E2) = {E2.Evaluate()}");
Console.WriteLine($"f(D) = {D.Evaluate()}");
Console.WriteLine($"f(C1) = {C1.Evaluate()}");
Note however, that while in your example for rule 2, you are evaulating a single "D" from row 10, the set defined in this answer captures the fact that D has multiple children and therefore will give a different answer. You could address this by redefining the Ds as D1
, D2
and D3
, and then add them all as children of C1 etc.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53491779%2fc-sharp-recursively-calculate-value%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
What you've described is a tree structure, which you can build easily enough, and then traverse recursively. You already know the parent/child relationships; you just have to create a model to represent them in code.
Start with an Element
class that looks like this:
class Element
{
string Code;
Element Parent; // null if no parent
double Value;
double CalculatedValue;
List<string> Children;
}
And create a dictionary of these, keyed by code:
Dictionary<string, Element> Elements;
Go through the list, adding creating an Element
for each unique element, and adding it to the dictionary:
(Note: code examples are in pseudo-C#. I don't want to get bogged down in syntax here.)
for each row
{
Element e;
// if the element doesn't exist in the dictionary, create and add it
if (!Elements.TryGetValue(code, out e))
{
e = new Element(code, value);
Elements.Add(code, e);
}
if (child != null)
{
e.Children.Add(child);
}
}
You now have a dictionary of elements, with the child relationships. You need to create the parent relationships. Easiest way is with a scan of the dictionary:
for each e in Elements
for each child in e.Children
if (child != "X" or "Y" or "Z")
Elements[child].Parent = e;
Now what you have is a forest: one or more unrooted trees. You can scan it recursively to compute your value:
double totalValue = 0;
for each e in Elements
if (e.Parent == null)
{
totalValue += calculateElementValue(e);
}
}
// at this point, totalValue should contain the total value
If I understood your rules correctly, this method should compute an individual element's value. I assumed that an element has only one of X, Y, or Z. This is a simple depth-first traversal of an element tree.
double CalculateElementValue(Element e)
{
double eValue = 0;
double childrenValue = 0;
for each child in e.Children
{
switch (child)
{
case "X": eValue = e.Value * xValue; break;
case "Y": eValue = e.Value * yValue; break;
case "Z": eValue = e.Value * zValue; break;
else
{
childrenValue += CalculateElementValue(Elements[child]);
}
}
}
return eValue * childrenValue;
}
You could include the parent assignment in the initial loop that builds the elements, but it complicates things a little bit. But unless the table has lots of rows, you probably won't notice a difference in speed.
add a comment |
What you've described is a tree structure, which you can build easily enough, and then traverse recursively. You already know the parent/child relationships; you just have to create a model to represent them in code.
Start with an Element
class that looks like this:
class Element
{
string Code;
Element Parent; // null if no parent
double Value;
double CalculatedValue;
List<string> Children;
}
And create a dictionary of these, keyed by code:
Dictionary<string, Element> Elements;
Go through the list, adding creating an Element
for each unique element, and adding it to the dictionary:
(Note: code examples are in pseudo-C#. I don't want to get bogged down in syntax here.)
for each row
{
Element e;
// if the element doesn't exist in the dictionary, create and add it
if (!Elements.TryGetValue(code, out e))
{
e = new Element(code, value);
Elements.Add(code, e);
}
if (child != null)
{
e.Children.Add(child);
}
}
You now have a dictionary of elements, with the child relationships. You need to create the parent relationships. Easiest way is with a scan of the dictionary:
for each e in Elements
for each child in e.Children
if (child != "X" or "Y" or "Z")
Elements[child].Parent = e;
Now what you have is a forest: one or more unrooted trees. You can scan it recursively to compute your value:
double totalValue = 0;
for each e in Elements
if (e.Parent == null)
{
totalValue += calculateElementValue(e);
}
}
// at this point, totalValue should contain the total value
If I understood your rules correctly, this method should compute an individual element's value. I assumed that an element has only one of X, Y, or Z. This is a simple depth-first traversal of an element tree.
double CalculateElementValue(Element e)
{
double eValue = 0;
double childrenValue = 0;
for each child in e.Children
{
switch (child)
{
case "X": eValue = e.Value * xValue; break;
case "Y": eValue = e.Value * yValue; break;
case "Z": eValue = e.Value * zValue; break;
else
{
childrenValue += CalculateElementValue(Elements[child]);
}
}
}
return eValue * childrenValue;
}
You could include the parent assignment in the initial loop that builds the elements, but it complicates things a little bit. But unless the table has lots of rows, you probably won't notice a difference in speed.
add a comment |
What you've described is a tree structure, which you can build easily enough, and then traverse recursively. You already know the parent/child relationships; you just have to create a model to represent them in code.
Start with an Element
class that looks like this:
class Element
{
string Code;
Element Parent; // null if no parent
double Value;
double CalculatedValue;
List<string> Children;
}
And create a dictionary of these, keyed by code:
Dictionary<string, Element> Elements;
Go through the list, adding creating an Element
for each unique element, and adding it to the dictionary:
(Note: code examples are in pseudo-C#. I don't want to get bogged down in syntax here.)
for each row
{
Element e;
// if the element doesn't exist in the dictionary, create and add it
if (!Elements.TryGetValue(code, out e))
{
e = new Element(code, value);
Elements.Add(code, e);
}
if (child != null)
{
e.Children.Add(child);
}
}
You now have a dictionary of elements, with the child relationships. You need to create the parent relationships. Easiest way is with a scan of the dictionary:
for each e in Elements
for each child in e.Children
if (child != "X" or "Y" or "Z")
Elements[child].Parent = e;
Now what you have is a forest: one or more unrooted trees. You can scan it recursively to compute your value:
double totalValue = 0;
for each e in Elements
if (e.Parent == null)
{
totalValue += calculateElementValue(e);
}
}
// at this point, totalValue should contain the total value
If I understood your rules correctly, this method should compute an individual element's value. I assumed that an element has only one of X, Y, or Z. This is a simple depth-first traversal of an element tree.
double CalculateElementValue(Element e)
{
double eValue = 0;
double childrenValue = 0;
for each child in e.Children
{
switch (child)
{
case "X": eValue = e.Value * xValue; break;
case "Y": eValue = e.Value * yValue; break;
case "Z": eValue = e.Value * zValue; break;
else
{
childrenValue += CalculateElementValue(Elements[child]);
}
}
}
return eValue * childrenValue;
}
You could include the parent assignment in the initial loop that builds the elements, but it complicates things a little bit. But unless the table has lots of rows, you probably won't notice a difference in speed.
What you've described is a tree structure, which you can build easily enough, and then traverse recursively. You already know the parent/child relationships; you just have to create a model to represent them in code.
Start with an Element
class that looks like this:
class Element
{
string Code;
Element Parent; // null if no parent
double Value;
double CalculatedValue;
List<string> Children;
}
And create a dictionary of these, keyed by code:
Dictionary<string, Element> Elements;
Go through the list, adding creating an Element
for each unique element, and adding it to the dictionary:
(Note: code examples are in pseudo-C#. I don't want to get bogged down in syntax here.)
for each row
{
Element e;
// if the element doesn't exist in the dictionary, create and add it
if (!Elements.TryGetValue(code, out e))
{
e = new Element(code, value);
Elements.Add(code, e);
}
if (child != null)
{
e.Children.Add(child);
}
}
You now have a dictionary of elements, with the child relationships. You need to create the parent relationships. Easiest way is with a scan of the dictionary:
for each e in Elements
for each child in e.Children
if (child != "X" or "Y" or "Z")
Elements[child].Parent = e;
Now what you have is a forest: one or more unrooted trees. You can scan it recursively to compute your value:
double totalValue = 0;
for each e in Elements
if (e.Parent == null)
{
totalValue += calculateElementValue(e);
}
}
// at this point, totalValue should contain the total value
If I understood your rules correctly, this method should compute an individual element's value. I assumed that an element has only one of X, Y, or Z. This is a simple depth-first traversal of an element tree.
double CalculateElementValue(Element e)
{
double eValue = 0;
double childrenValue = 0;
for each child in e.Children
{
switch (child)
{
case "X": eValue = e.Value * xValue; break;
case "Y": eValue = e.Value * yValue; break;
case "Z": eValue = e.Value * zValue; break;
else
{
childrenValue += CalculateElementValue(Elements[child]);
}
}
}
return eValue * childrenValue;
}
You could include the parent assignment in the initial loop that builds the elements, but it complicates things a little bit. But unless the table has lots of rows, you probably won't notice a difference in speed.
answered Nov 27 '18 at 6:26
Jim MischelJim Mischel
107k12130250
107k12130250
add a comment |
add a comment |
Here are some example data structures you can use to represent your data, and recursively calculate values.
Note that this example uses indirect recursion. I.e. Node.Evaluate()
does not call itself directly, but instead calls WeightedChild.Evaluate()
which in turn calls back to Node.Evaluate()
.
public class Node
{
public Node(params WeightedChild weightedChildren)
{
this.WeightedChildren = weightedChildren ?? Enumerable.Empty<WeightedChild>();
}
IEnumerable<WeightedChild> WeightedChildren { get; }
public double Evaluate()
{
return this.WeightedChildren.Any()
? this.WeightedChildren.Select(child => child.Evaluate()).Sum()
: 1;
}
}
public class WeightedChild
{
public WeightedChild(double weight, Node child)
{
this.Weight = weight;
this.Child = child;
}
public double Weight { get; }
Node Child { get; }
public double Evaluate()
{
return this.Child.Evaluate() * this.Weight;
}
}
You can then use these classes to build your data set:
var X = new Node();
var Y = new Node();
var Z = new Node();
var E2 = new Node(new WeightedChild(3.3, Z));
var E1 = new Node(new WeightedChild(2.1, Y));
var D = new Node(
new WeightedChild(0.7, X),
new WeightedChild(1.8, E1),
new WeightedChild(3.1, E2));
var C2 = new Node(new WeightedChild(0.9, X));
var C1 = new Node(
new WeightedChild(1.14, X),
new WeightedChild(1.7, D));
var B = new Node(
new WeightedChild(1.3, C1),
new WeightedChild(1.5, C2));
var A = new Node(new WeightedChild(1.1, C1));
You can then evaluate each node:
Console.WriteLine($"f(E2) = {E2.Evaluate()}");
Console.WriteLine($"f(D) = {D.Evaluate()}");
Console.WriteLine($"f(C1) = {C1.Evaluate()}");
Note however, that while in your example for rule 2, you are evaulating a single "D" from row 10, the set defined in this answer captures the fact that D has multiple children and therefore will give a different answer. You could address this by redefining the Ds as D1
, D2
and D3
, and then add them all as children of C1 etc.
add a comment |
Here are some example data structures you can use to represent your data, and recursively calculate values.
Note that this example uses indirect recursion. I.e. Node.Evaluate()
does not call itself directly, but instead calls WeightedChild.Evaluate()
which in turn calls back to Node.Evaluate()
.
public class Node
{
public Node(params WeightedChild weightedChildren)
{
this.WeightedChildren = weightedChildren ?? Enumerable.Empty<WeightedChild>();
}
IEnumerable<WeightedChild> WeightedChildren { get; }
public double Evaluate()
{
return this.WeightedChildren.Any()
? this.WeightedChildren.Select(child => child.Evaluate()).Sum()
: 1;
}
}
public class WeightedChild
{
public WeightedChild(double weight, Node child)
{
this.Weight = weight;
this.Child = child;
}
public double Weight { get; }
Node Child { get; }
public double Evaluate()
{
return this.Child.Evaluate() * this.Weight;
}
}
You can then use these classes to build your data set:
var X = new Node();
var Y = new Node();
var Z = new Node();
var E2 = new Node(new WeightedChild(3.3, Z));
var E1 = new Node(new WeightedChild(2.1, Y));
var D = new Node(
new WeightedChild(0.7, X),
new WeightedChild(1.8, E1),
new WeightedChild(3.1, E2));
var C2 = new Node(new WeightedChild(0.9, X));
var C1 = new Node(
new WeightedChild(1.14, X),
new WeightedChild(1.7, D));
var B = new Node(
new WeightedChild(1.3, C1),
new WeightedChild(1.5, C2));
var A = new Node(new WeightedChild(1.1, C1));
You can then evaluate each node:
Console.WriteLine($"f(E2) = {E2.Evaluate()}");
Console.WriteLine($"f(D) = {D.Evaluate()}");
Console.WriteLine($"f(C1) = {C1.Evaluate()}");
Note however, that while in your example for rule 2, you are evaulating a single "D" from row 10, the set defined in this answer captures the fact that D has multiple children and therefore will give a different answer. You could address this by redefining the Ds as D1
, D2
and D3
, and then add them all as children of C1 etc.
add a comment |
Here are some example data structures you can use to represent your data, and recursively calculate values.
Note that this example uses indirect recursion. I.e. Node.Evaluate()
does not call itself directly, but instead calls WeightedChild.Evaluate()
which in turn calls back to Node.Evaluate()
.
public class Node
{
public Node(params WeightedChild weightedChildren)
{
this.WeightedChildren = weightedChildren ?? Enumerable.Empty<WeightedChild>();
}
IEnumerable<WeightedChild> WeightedChildren { get; }
public double Evaluate()
{
return this.WeightedChildren.Any()
? this.WeightedChildren.Select(child => child.Evaluate()).Sum()
: 1;
}
}
public class WeightedChild
{
public WeightedChild(double weight, Node child)
{
this.Weight = weight;
this.Child = child;
}
public double Weight { get; }
Node Child { get; }
public double Evaluate()
{
return this.Child.Evaluate() * this.Weight;
}
}
You can then use these classes to build your data set:
var X = new Node();
var Y = new Node();
var Z = new Node();
var E2 = new Node(new WeightedChild(3.3, Z));
var E1 = new Node(new WeightedChild(2.1, Y));
var D = new Node(
new WeightedChild(0.7, X),
new WeightedChild(1.8, E1),
new WeightedChild(3.1, E2));
var C2 = new Node(new WeightedChild(0.9, X));
var C1 = new Node(
new WeightedChild(1.14, X),
new WeightedChild(1.7, D));
var B = new Node(
new WeightedChild(1.3, C1),
new WeightedChild(1.5, C2));
var A = new Node(new WeightedChild(1.1, C1));
You can then evaluate each node:
Console.WriteLine($"f(E2) = {E2.Evaluate()}");
Console.WriteLine($"f(D) = {D.Evaluate()}");
Console.WriteLine($"f(C1) = {C1.Evaluate()}");
Note however, that while in your example for rule 2, you are evaulating a single "D" from row 10, the set defined in this answer captures the fact that D has multiple children and therefore will give a different answer. You could address this by redefining the Ds as D1
, D2
and D3
, and then add them all as children of C1 etc.
Here are some example data structures you can use to represent your data, and recursively calculate values.
Note that this example uses indirect recursion. I.e. Node.Evaluate()
does not call itself directly, but instead calls WeightedChild.Evaluate()
which in turn calls back to Node.Evaluate()
.
public class Node
{
public Node(params WeightedChild weightedChildren)
{
this.WeightedChildren = weightedChildren ?? Enumerable.Empty<WeightedChild>();
}
IEnumerable<WeightedChild> WeightedChildren { get; }
public double Evaluate()
{
return this.WeightedChildren.Any()
? this.WeightedChildren.Select(child => child.Evaluate()).Sum()
: 1;
}
}
public class WeightedChild
{
public WeightedChild(double weight, Node child)
{
this.Weight = weight;
this.Child = child;
}
public double Weight { get; }
Node Child { get; }
public double Evaluate()
{
return this.Child.Evaluate() * this.Weight;
}
}
You can then use these classes to build your data set:
var X = new Node();
var Y = new Node();
var Z = new Node();
var E2 = new Node(new WeightedChild(3.3, Z));
var E1 = new Node(new WeightedChild(2.1, Y));
var D = new Node(
new WeightedChild(0.7, X),
new WeightedChild(1.8, E1),
new WeightedChild(3.1, E2));
var C2 = new Node(new WeightedChild(0.9, X));
var C1 = new Node(
new WeightedChild(1.14, X),
new WeightedChild(1.7, D));
var B = new Node(
new WeightedChild(1.3, C1),
new WeightedChild(1.5, C2));
var A = new Node(new WeightedChild(1.1, C1));
You can then evaluate each node:
Console.WriteLine($"f(E2) = {E2.Evaluate()}");
Console.WriteLine($"f(D) = {D.Evaluate()}");
Console.WriteLine($"f(C1) = {C1.Evaluate()}");
Note however, that while in your example for rule 2, you are evaulating a single "D" from row 10, the set defined in this answer captures the fact that D has multiple children and therefore will give a different answer. You could address this by redefining the Ds as D1
, D2
and D3
, and then add them all as children of C1 etc.
edited Nov 27 '18 at 3:17
answered Nov 27 '18 at 3:01
ErgwunErgwun
8,84444370
8,84444370
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53491779%2fc-sharp-recursively-calculate-value%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
This is a very broad question, which makes it hard for us to answer. If you've tried something, and have a specific issue, maybe we can help with that instead?
– Richard Everett
Nov 27 '18 at 2:14
3
Please provide a Minimal, Complete, and Verifiable example
– Jeremy Thompson
Nov 27 '18 at 2:22
It's not clear at all which part you're stuck on. Please show the code that's not working as you expect it to (SO is not a code-writing service).
– Rufus L
Nov 27 '18 at 2:49
Peeyush. the data is correct. The code represents chemical components. For example row 6 means there is 1.14 % of component X within component C1. The original chemical code are very complicated, I replaced them with pseudo code here to simply the problem.
– ppau2004
Nov 27 '18 at 2:50
Rufus, I am not sure where to start this code. this is definitely not a for each loop and has to be some sort of recursion, but I am not sure how to do. I will continue to work on it, hopefully, get a solution and post it here. In the meantime, anyone gives me some suggestions will be highly appreciated.
– ppau2004
Nov 27 '18 at 2:54