Choose 1 from each of 11 ArrayLists is too slow - java

This is basically what my program is doing:
if you have 5 different shirts and 4 different pants to choose from, there are 20 different combinations of shirts and pants you can wear, and my program would iterate through all 20 combinations to determine which is the "best" to wear.
Except, in my situation, there are 11 different types of clothing (such as headgear, gloves, pants, earrings, shoes, cloak, etc) and as many as 10 items in each category. So, there could be as many as 11^10 combinations, and when I tried running my program with only 4 in each category, or 11^4, it took about 5 seconds to complete. 11^10 will take DAYS.
Currently, what I have going on is 11 for loops nested inside each other to go through every combination. This obviously isn't the best way to do this because it is so slow. How can I make this faster? For context, I have 1 "outer" ArrayList containing 11 ArrayLists, and each of those 11 ArrayLists is a list of objects (the clothing).

There really is no way of doing it without using a brute-force search, however you can chop down the choice area by generating a range of possible matches, and only iterating through the items in the list that are in that range.

Edit
Since your score is additive, the best item of clothing from each category is the one that gives the best sum of dex+str+int. This means that you don't need to consider combinations, just pick the best shirt, then the best pants, etc. So 11 loops, not 11 nested loops.
Old answer
In the general case, there brute force (what you're doing right now) is the only way to guarantee a correct answer.
Under some conditions, however, you can do better: For example if I know that if the one shirt-pants combination is "better" than another shirt-pants combination no matter what other items of clothing I choose, I can find the best shirt-pants combination first, and then consider what item of clothing is best to add to it. It's essentially a greedy search.

Related

Java - statistics automation using arrays, (Creating a table of classes)

I know this is kind of hard to understand but bear with me here, I'm taking a statistics class and I wanted to automate the process, so what we do is take some data, take the minimum number and maximum, get the range, all easy and already done.
But here is the trick, we need to split the data between classes, for example user entered 10 data points ranging between the numbers 10 and 40, what you wanna do is create classes to fit each number, class one is the numbers between 10 and 15, class 2 is 15 and 20 and so on (this was just an example).. thinking about it first you can just make a shit ton of if conditions, but that doesn't seem intuitive and second all data and class width and number of classes are the user's choice, so how do you suggest I approach this problem?
To help you understand here is a better example:
STATS

Solution for selecting an appropriate category for something based off of the words within its description (java)

Im trying to better organise the types of tasks regularly sent to my team based off of the titles and short comment people enter.
Our team only handles a handful of issues (maybe 10 or so) different types of tasks, so I've put together a list of common words used within the description of a particular type of task and i've been using this to categorise the issues. for example.... an issue might come through like "User x doesn't have access to office after hours, please update their swipecard access level". what i've got so far is if the comments contain 'swipecard' or 'access', its a building access type request.
I've quickly found myself with code that's LOTS of ... if contains, and if !contains...
Is there a neater way of doing what im after?
If you want to make it complex, it sounds like you have a classification problem.
If you want to keep it simple, you're probably on the right track with your if statements and contains(). To get to a cleaner solution, I would approach it as follows:
Create a class to modify your categories - give it two attributes: String categoryName, List<String> commonlyUsedWords;
Populate a list with instances of that class - one per type.
For each issue, loop through the list of categories and check how many words match, and store that as a percentage (e.g. 8 out of 10 words match, therefore 80% match).
Return the category with the highest match rate.

Calculating winning odds - Poker bot

I am trying to build a poker bot in java. I have written the hand evaluation class and I am about to start feeding a neural network but I face a problem. I need the winning odds of every hand for every step: preflop, flop, turn, river.
My problem is that, there are 52 cards and the combinations of 5 cards are 2,598,960. So I need to store 2,598,960 odds for each possible hand. The number is huge and these are only the odds I need for the river.
So I have two options:
Find the odds for every possible hand and every possible deck and every time I start my application load them and kill my memory.
Calculate the odds on the fly and lack processing power.
Is there a 3rd better option to deal with this problem?
3rd option is use the disk... but my first choice would be to calculate odds as you need them.
Why do you need to calculate all combinations of 5 cards, a lot of these hands are worth the same, as there are 4 suits there is repetition between hands.
Personally I would rank your hand based on how many hands beat your hand and how many hands your hand beats. From this you can compute your probability of winning the table by multiplying by number of active hands.
What about ignoring the colors? From 52 possible values, you drop to 13. You only have 6175 options remaining. Of course, colors are important for a flush - but here, it is pretty much binary - are all the colors the same or not? So we are at 12350 (including some impossible combinations, in fact it is 7462 as in the others, a number is contained more than once, so the color must differ).
If the order is important (e.g. starting hand, flip, flop, river or how is it called), it will be a lot more, but it is still less than your two millions. Try simplifying your problems and you'll realize they can be solved.

Finding as many pairs as possible

I'm trying to solve a problem but unfortunately my solution is not really the best for this task.
Task:
At a party there are N guests ( 0 < N < 30000 ). All guests tell when they get to the party and when they leave (for example [10;12]). The task is to take photos of as many people as possible at the party. On a photo there can only be 2 people (a pair) and each person can only be on exactly one photo. Of course, a photo can only be taken when the two persons are at the party at the same time. This is the case when their attendance intervals overlap.
My idea: I wrote a program which from the intervals creates a graph of connections. From the graph I search for the person who has the least number of connections. From the connected persons I also select the person who has the least connections. Then these two are chosen as a pair on a photo. Both are removed from the graph. The algorithm runs until no connections are left.
This approach works however there is a 10 secs limit for the program to calculate. With 1000 entries it runs in 2 secs, but even with 4000 it takes a lot of time. Furthermore, when I tried it with 25000 data, the program stops with an out of memory error, so I cannot even store the connections properly.
I think a new approach is needed here, but I couldn't find an other way to make this work.
Can anyone help me to figure out the proper algorithm for this task?
Thank you very much!
Sample Data:
10
1 100
2 92
3 83
4 74
5 65
6 55
7 44
8 33
9 22
10 11
The first line is the number of guests the further data is the intervals of people at the party.
No need to create graph here, this problem can be solved well on intervals structure. Sort people by ascending order of their leaving time(ending point of interval). Then iterate over them in that sorted order: if current person is not intersecting with anyone, then he should be removed. If he is intersecting with more than one person, take as a pair one of them who has earliest leaving time. During iteration you should compare each person only with next ones.
Proving this approach is not so difficult, so I hope you can prove it yourself.
Regarding running time, simple solution will be O(N^2), however I think that it can be reduced to O(N * logN). Anyway, O(N^2) will fit in 10 seconds on a normal PC.
Seems like a classical maximum matching problem to me.
You build a graph, where people who can possibly be pictured together (their time intervals intersect) are connected with an edge, and then find maximum matching, for example, with Edmond's Blossom algorithm.
I wouldn't say, that it's quite easy to implement. However, you can get quite a good approximation of this with Kuhn's algorithm for maximum matching in bipartite graphs. This one is really easy to implement, but won't give you the exact solution.
I have some really simple idea:
Assume, party will take Xh, make X sets for each hour, add to them appropriate people. Of course, people who will be there longer than hour will be in few sets. Now if there are 2 sets "together" with even number of ppl, you just could take n/2 photos for each sets. If there are 2 sets of odd number of people you are looking for someone who will be on each of that 2 sets, and move him to one of them (so you got 2 even number sets of people who will be on the same time on the party).
Remember to remove all used ppl (consider some class - Man with lists of all his/her hours).
My idea probably should be expand to more advanced "moving people" algorithm, through more than one neighboring set.
I think the following can do:
First, read all the guests' data and sort them into an array by leaving time ascending. Then, take first element of the array and iterate through next elements until the very first time-match found (next guest's entry time is less than this guest's leave time), if found, remove both from array as a pair, and report it elsewhere. If not, remove the guest as it can't be paired at all. Repeat until the array is empty.
The worst case of this is also N^2, as a party can be like [1,2],[3,4],... where no guests could be paired with each other, and the algorithm will search through all 30000 guests in vain all the time. So I don't think this is the optimal algorithm, but it should give an exact answer.
You say you already have a graph structure representation. I assume your vertices represent the guest and the interval of their staying at the party and the edges represent overlap of the respective intervals. What you then have to solve is the graph theoretical maximum matching problem, which has been solved before.
However, as indicated in my comments above, I think you can exploit the properties of the problem, especially the transitivity-like "if A leaves before B leaves and B leaves before C arrives, then A and C will not meet, either" like this:
Wait until the next yet unphotographed guest is about to leave, then take a photo of this one with the one who leaves next among those present.
You might succeed in thinking about the earliest time a photo can be taken: It is the time when the second person arrives at the party.
So as a photographer, goto the party being the first person and wait. Whenever a person arrives, take a photo with him/her and all other persons at the party. As a person appears only once, you will not have any duplicates.
While taking a photo (i.e. iterating over the list of guests), remove those guests who actually left the party.

What kind of algorithm is this? Box packing/Knapsack?

I was working on an application last night and came across a particular problem which I'm sure probably has an efficient algorithm to solve it. Could anyone suggest?
Problem:
TL;DR: Maybe a picture will help: http://www.custom-foam-inserts.com/ . I have lots of items which fit in a range of compartments: and I want to minimise the number of cases I need to take.
.
I have a set of N items of expensive electronic equipment which I want to pack into specially designed protective boxes. These boxes each have many compartments which can each fit a single item: some of which are designed specially to fit a particular item (ie, a camera shaped hole) and some of which are generic (a rectangular hole). I know in advance that there are C different sizes of compartment and what sizes these are.
These boxes come in L different layouts, each with at least one compartment. A layout might be ‘two large rectangular compartments and 4 small circular compartments’.
Each compartment size is present on at least one layout, but I have items which don’t suit any compartment size. Each item fits at least one compartment and may fit into multiple different compartments: for example, my DSLR camera might be a tight fit in a ‘medium rectangle’ compartment, a loose fit in a ‘large rectangle’ and a perfect fit in a ‘DSLR camera compartment’, but won’t fit in a ‘small circle’. To this end I’ve made a list of which compartments are suitable for each item.
The items are moderately heterogeneous – for example there may be 50 items of one size and 20 items of another size.
Each box has two costs Volume and Dollars (however D ~proportional to V). I need to minimise one or both of these costs whilst fitting ALL of my items into the boxes. Due to the layouts of the boxes, the optimal solution may contain unused compartments. If two solutions have equal volume, select the one with the most unused compartments. Because each compartment is present on at least one layout and each item fits in at least one compartment, there is always a solution which fits all items.
Number of items: <=2000, average case 150.
Number of compartments: <= 1000.
Number of layouts: <= 1000.
Any ideas on this one? I've looked a bit at Knapsack and Bin Packing algorithms and I'm not sure they're the way to go. Help much appreciated.
From the problem description this does indeed seem to be knapsack problem since you have to maximise your space available while keeping in mind the weight of your options.
Depending on what you are after, you could also consider using a Genetic Algorithm. Since this problem is NP Complete the running time will eventually explode should you need to add more items, so I would go with this primarily if I need the best solution available irrelevant of the time it takes.
On the other hand, the Genetic Algorithm should be able to provide with some solution in a relatively small period of time, however, the solution it provides might not be as good as the one provided by the Knapsack algorithm, so I would choose a GA if I have restrictions on the time I need to provide some solution and I do not care if it is the not absolute best.

Categories