Modified depth first search to find total sum - c#

Disclaimer: This is not a class project, more of work related. I tried finding example online but generally its just for transversing through the tree. I am coding it in C#
Hi all,
I am trying to use DFS to calculate the biggest possible number sum combination which will be equal to the number given with some other conditions.
Total sum of weight needs to be below 150 in a class.
Total height in the class cannot be more than 600.
Max number of student if possible in Class A
If same height and weight, the person with the smaller ID will be considered first.
ID - Weight - Height
1 - 80 - 150
2 - 30 - 100
3 - 30 - 150
4 - 50 - 100
5 - 60 - 150
6 - 40 - 100
Class 1: 1, 2, 6
Class 2: 3, 4, 5
Class 3:
Anyone can point me in the right direction or DFS shouldn't be used in this case?

DFS and BFS works with trees, which you currently do not have. IMO, creating a tree with all possible combinations is not the right way in this case (but of course you can do it). If your set is small you can try to enumerate all solutions without creating a tree and using DFS or BFS (as #Dennis.Verweij is proposing).
I think that your problem is a variation of the Knapsack problem, which is unfortunately NP-Complete
Otherwise take a look at Integer Programming. This is a hard problem to solve, but you can find some relevant algorithms (which might actually use internally DFS) to help you with the solution.

Related

C# : is there an appropriate collection for fast range-related search?

I have data like that:
Time(seconds from start)
Value
15
2
16
4
19
2
25
9
There are a lot of entries (10000+), and I need a way to find fast enough sum of any time range, like sum of range 16-25 seconds (which would be 4+2+9=15). This data will be dynamically changed many times (always adding new entries at the bottom of list).
I am thinking about using sorted list + binary search to determinate positions and just make sum of values, but is can took too much time to calculate it. Is there are any more appropriate way to do so? Nuget packets or algorithm references would be appreciated.
Just calculate cumulative sum:
Time Value CumulativeSum
15 2 2
16 4 6
19 2 8
25 9 17
Then for range [16,25] it will be task to binary search left border of 16 and 25 exact, which turns into 17 - 2 = 15
Complexity: O(log(n)), where n - size of the list.
Binary search implementation for lower/upper bound can be found in my repo - https://github.com/eocron/Algorithm/blob/master/Algorithm/Sorted/BinarySearchExtensions.cs

How to identify 5 numbers within 5% of each other out of 6 consecutive numbers

Using C# I have to:
Take an user entered number and decide if 5 out of 6 of these numbers are within 5% of each other. Also identify when it's impossible reach success before going to all 6 numbers. An example of this would be in the first 3 numbers... if 2 were not within 5% of each other, no use continuing.
I've tried taking in the first 2 numbers, into an array, and setting a Min and Max assuming they are within 5%. By the time I get to the 3rd and 4th numbers, which also can reset my Min and Max, it's turned into a bowl of spaghetti :)
Please help!

Weighted random number generation C#

I have been trying to search answer for this, but all discussions that I have found are either in language that I don't understand or relies on having a collection where each element has its own weight.
I want to basically just get a random number between 0 and 10, which is "middle-weighted" as in 5 comes more often than 0 and 10. Basically I have been trying to figure out an algorithm where I can give any number to be the "weighted number" between min and max values that I have defined and all the numbers generated would be weighted appropiately. I know that this may sound like "I dont want to think about this, I'll just sit back and wait someone else to do this", but I have been thinking and searching about this for like an hour and I'm really lost :|
So in the end, I want that I could call ( via extension method )
random.NextWeighted(MIN, MAX, WEIGHT);
You have an inverse normal distribution method available.
Scale your random number so that it's a double between zero and one.
Pass it to InverseNormalDistribution.
Scale the returned value based on the weight. (For example, divide by weight over 100.)
Calculate [ (MIN + MAX) / 2 ] + [ (ScaledValue) X (MAX - MIN) ]
If that's less than MIN, return MIN. If it's more than MAX, return MAX. Otherwise, return this value.
I don't know how much more often you want 5 to appear than the other numbers between 0-10 but you could create an array with the distribution you want.
Something like
var dist = new []{0,1,2,3,4,5,6,7,8,9,10,5,5,5};
Then you get a random positions of 0 and 13 you will get numbers between 0-10 but a 5 four times more often than the others. Pretty fast but not very practical if you want numbers between 0 and billion though.

Algorithm to determine best combinations - Bin Packing

Given a set of items, each with a value, determine the number of each item to include in a collection so that the total value is less than or equal to given limit and the total value is as large as possible.
Example:
Product A = 4
Product B = 3
Product C = 2
Product D = 5
If Total Capacity = 10.5 , then the combination of B,C,D will be selected.
If Total Capacity = 12.5 , then the combination of A,B,D will be selected.
If Total Capacity = 17 , then the combination of A,B,C,D will be selected.
I am looking for an algorithm (like knapsack or bin packing) to determine the combination. Any help appreciated.
You say that this is "like knapsack". As far as I can see it is a special case of bounded knapsack problem called the 0-1 knapsack problem.
It is NP-complete.
There are lots of ways you could attempt to solve it. See this related question for one approach:
Writing Simulated Annealing algorithm for 0-1 knapsack in C#
If you only have four items then just testing all possibilities should be fast enough for most purposes.

How to manage AI actions based on percentages

I am looking now for some time about how can a programmer simulate a AI decision based on percentages of actions for the final fantasy tactic-like games (strategy game).
Say for example that the AI character has the following actions:
Attack 1: 10%
Attack 2: 9%
Magic : 4%
Move : 1%
All of this is far from equaling 100%
Now at first I though about having an array with 100 empty slots, attack would have 10 slots, attack 2 9 slots on the array. Combining random I could get the action to do then. My problem here is it is not really efficient, or doesn't seem to be. Also important thing, what do I do if I get on an empty slot. Do I have to calculate for each character all actions based on 100% or define maybe a "default" action for everyone ?
Or maybe there is a more efficient way to see all of this ? I think that percentage is the easiest way to implement an AI.
The best answer I can come up with is to make a list of all the possible moves you want the character to have, give each a relative value, then scale all of them to total 100%.
EDIT:
For example, here are three moves I have. I want attack and magic to be equally likely, and fleeing to be half as likely as attacking or using magic:
attack = 20
magic = 20
flee = 10
This adds up to 50, so dividing each by this total gives me a fractional value (multiply by 100 for percentage):
attack = 0.4
magic = 0.4
flee = 0.2
Then, I would make from this a list of cumulative values (i.e. each entry is a sum of that entry and all that came before it):
attack = 0.4
magic = 0.8
flee = 1
Now, generate a random number between 0 and 1 and find the first entry in the list that is greater than or equal to that number. That is the move you make.
No, you just create threshholds. One simple way is:
0 - 9 -> Attack1
10 - 18 -> Attack 2
19 - 22 -> Magic
23 -> Move
Something else -> 24-99 (you need to add up to 100)
Now create a random number and mod it by 100 (so num = randomNumber % 100) to define your action. The better the random number to close to a proper distribution you will get. So you take the result and see which category it falls into. You can actually make this even more efficient but it is a good start.
Well if they don't all add up to 100 they aren't really percentages. This doesnt matter though. you just need to figure out the relative probability of each action. To do this use the following formula...
prob = value_of_action / total_value_of_all_actions
This gives you a number between 0 and 1. if you really want a percentage rather than a fraction, multiply it by 100.
here is an example:
prob_attack = 10 / (10 + 9 + 4 + 1)
= 10 / 24
= 0.4167
This equates to attack being chosen 41.67% of the time.
you can then generate thresholds as is mentioned in other answers. And use a random number between 0 and 1 to choose your action.

Categories