How to optimise my solution? - algorithm

I recently encountered a problem which goes
like this :
A student is given N number of
questions and T time in total. Each question
requires different time to complete and carries
different marks. The problem asks to find the
maximum marks the student can get by
attempting some of the N questions within T
time (Assuming if a question is attempted, it
must be fully completed,no partial attempt of a
question is allowed).
I tried to solve the problem by computing all
possible combinations of questions which takes
<= T seconds to complete but soon found out
its ineffective for large datasets.
How can I optimise my solution? Is there any
alternative solution available?

It looks like a variant of the well known Knapsack Problem

Related

Algorithm to Calculate "Best" Option Based on Score

I have an essentially infinite set of "challenges", and each one can be solved (or not) using a formula that has a finite set of inputs, each with a finite set of possible values (so that a possible solution to one challenge might be X=10, Y=22, Z=6, and another might be X=3, Y=14, Z=5). Whether or not a challenge is solved by a particular solution is not known until after the formula is applied to the given challenge. At that point, I will know if the challenge was solved or not.
There are some extra factors to consider:
1) Each iteration of the formula takes time and costs money, so I can't use "brute force" and just try every combination.
2) Over time, a solution that used to work may stop working, and vice versa.
3) There is usually more than one solution to a given challenge.
4) Different solutions have varying time and cost factors, so in the absence of any prior attempts at solving a particular challenge, there is a "known order" of solutions, sorted by these factors.
Each time a challenge is presented, I have access to a history of the prior attempts at solving prior challenges with identical attributes. So after I see a particular challenge a few times, I know what solution has and hasn't worked in the past.
The objective is to take the results of the past challenges (with identical attributes) and prioritize the available solutions in the order that they are most likely to succeed. In a highly simplified version of this: If solution 10/22/6 worked 3 of the last 5 times (and no other previously-attempted solutions worked more than 2 times), then solution 10/22/6 is probably the best one to try first; etc.
PS - I'm not expecting anyone to "write this" for me; just hoping for some ideas as to what to explore and experiment with. I can't imagine something like this hasn't been done before.

Algorithm: Some sort of version of producer/consumer? Scheduling

I'm not sure if this is a producer/consumer problem but I couldn't find a better way to phrase my question.
I'm wondering if this problem (or a similar one) has already been solved. If it hasn't, is it an NP problem? Here is the description of the problem and the question I'm trying to answer
Assume you have 4 producers and 2 consumers.
Assume you already know everything the producers are going to produce (as a list of items, each items being of a different size)
Assume each consumer can consume any data at different speeds (e.g consumer1 will consume any item twice as fast as consumer2)
QUESTION: If I control the scheduler (meaning which consumer gets what item), How do I find out what assignment of the items will make the consumers finish the fastest (consuming all the items).
I hope that makes sense. I spent a couple of hours thinking about this and then a couple of more hours looking for possible solutions but still no luck. Hoping I can get some brainstorming/solutions from everyone. Thanks in advance!
I believe that this is a variant on the bin-packing problem, where instead of one bin you have two different-sized bins; you want to minimize the total number of bins used, and you want to use approximately the same quantity of each bin type. This is an NP-Hard problem.
Note that I don't think that the number of producers used is relevant here.

Algorithm to assign Exams to Rooms?

I have a problem that I have no idea what it is or how to solve it. I know there is a name for the problem (after it is known, the title could be changed to reflect it).
Its somewhat of getting a perfect fit for a particular list based on a passed formula. For eg.
I have 2 lists of objects. One list of rooms and one list of exams. For each exam, I loop through all available rooms, execute a formula (which returns a value from 0-1), 1 meaning its a good fit, and assign the highest one to the exam. I continue the loop over and over to find the best fit (which may lead to infinite loop).
I am trying to avoid using a genetic algorithm to solve this. Anyone got any idea what the name of the problem is and also a possible solution?
ps. Can an admin rename the title if I do not get the chance to?
This is the Assignment problem. Wikipedia will tell you more about how to solve it.

Designing a twenty questions algorithm

I am interested in writing a twenty questions algorithm similar to what akinator and, to a lesser extent, 20q.net uses. The latter seems to focus more on objects, explicitly telling you not to think of persons or places. One could say that akinator is more general, allowing you to think of literally anything, including abstractions such as "my brother".
The problem with this is that I don't know what algorithm these sites use, but from what I read they seem to be using a probabilistic approach in which questions are given a certain fitness based on how many times they have lead to correct guesses. This SO question presents several techniques, but rather vaguely, and I would be interested in more details.
So, what could be an accurate and efficient algorithm for playing twenty questions?
I am interested in details regarding:
What question to ask next.
How to make the best guess at the end of the 20 questions.
How to insert a new object and a new question into the database.
How to query (1, 2) and update (3) the database efficiently.
I realize this may not be easy and I'm not asking for code or a 2000 words presentation. Just a few sentences about each operation and the underlying data structures should be enough to get me started.
Update, 10+ years later
I'm now hosting a (WIP, but functional) implementation here: https://twentyq.evobyte.org/ with the code here: https://github.com/evobyte-apps/open-20-questions. It's based on the same rough idea listed below.
Well, over three years later, I did it (although I didn't work full time on it). I hosted a crude implementation at http://twentyquestions.azurewebsites.net/ if anyone is interested (please don't teach it too much wrong stuff yet!).
It wasn't that hard, but I would say it's the non-intuitive kind of not hard that you don't immediately think of. My methods include some trivial fitness-based ranking, ideas from reinforcement learning and a round-robin method of scheduling new questions to be asked. All of this is implemented on a normalized relational database.
My basic ideas follow. If anyone is interested, I will share code as well, just contact me. I plan on making it open source eventually, but once I have done a bit more testing and reworking. So, my ideas:
an Entities table that holds the characters and objects played;
a Questions table that holds the questions, which are also submitted by users;
an EntityQuestions table holds entity-question relations. This holds the number of times each answer was given for each question in relation to each entity (well, those for which the question was asked for anyway). It also has a Fitness field, used for ranking questions from "more general" down to "more specific";
a GameEntities table is used for ranking the entities according to the answers given so far for each on-going game. An answer of A to a question Q pushes up all the entities for which the majority answer to question Q is A;
The first question asked is picked from those with the highest sum of fitnesses across the EntityQuestions table;
Each next question is picked from those with the highest fitness associated with the currently top entries in the GameEntities table. Questions for which the expected answer is Yes are favored even before the fitness, because these have more chances of consolidating the current top ranked entity;
If the system is quite sure of the answer even before all 20 questions have been asked, it will start asking questions not associated with its answer, so as to learn more about that entity. This is done in a round-robin fashion from the global questions pool right now. Discussion: is round-robin fine, or should it be fully random?
Premature answers are also given under certain conditions and probabilities;
Guesses are given based on the rankings in GameEntities. This allows the system to account for lies as well, because it never eliminates any possibility, just decreases its likeliness of being the answer;
After each game, the fitness and answers statistics are updated accordingly: fitness values for entity-question associations decrease if the game was lost, and increase otherwise.
I can provide more details if anyone is interested. I am also open to collaborating on improving the algorithms and implementation.
This is a very interesting question. Unfortunately I don't have a full answer, let me just write down the ideas I could come up with in 10 minutes:
If you are able to halve the set of available answers on each question, you can distinguish between 2^20 ~ 1 million "objects". Your set is probably going to be larger, so it's right to assume that sometimes you have to make a guess.
You want to maximize utility. Some objects are chosen more often than others. If you want to make good guesses you have to take into consideration the weight of each object (= the probability of that object being picked) when creating the tree.
If you trust a little bit of your users you can gain knowledge based on their answers. This also means that you cannot use a static tree to ask questions because then you'll get the answers for the same questions.. and you'll learn nothing new if you encounter with the same object.
If a simple question is not able to divide the set to two halves, you could combine them to get better results: eg: "is the object green or blue?". "green or has a round shape?"
I am trying try to write a python implementation using a naïve Bayesian network for learning and minimizing the expected entropy after the question has been answered as criterium for selecting a question (with an epsilon chance of selecting a random question in order to learn more about that question), following the ideas in http://lists.canonical.org/pipermail/kragen-tol/2010-March/000912.html. I have put what I got so far on github.
Preferably choose questions with low remaining entropy expectation. (For putting together something quickly, I stole from ε-greedy multi-armed bandit learning and use: With probability 1–ε: Ask the question with the lowest remaining entropy expectation. With probability ε: Ask any random question. However, this approach seems far from optimal.)
Since my approach is a Bayesian network, I obtain the probabilities of the objects and can ask for the most probable object.
A new object is added as new column to the probabilities matrix, with low a priori probability and the answers to the questions as given if given or as guessed by the Bayes network if not given. (I expect that this second part would work much better if I would add Bayes network structure learning instead of just using naive Bayes.)
Similarly, a new question is a new row in the matrix. If it comes from user input, probably only very few answer probabilities are known, the rest needs to be guessed. (In general, if you can get objects by asking for properties, you can obtain properties by asking if given objects have them or not, and the transformation between these is essentially Bayes' theorem and breaks down to transposition in the easiest case. The guessing quality should improve again once the network has an appropriate structure.)
(This is a problem, since I calculate lots of probabilities. My goal is to do it using database-oriented sparse tensor calculations optimized for working with weighted directed acyclic graphs.)
It would be interesting to see how good a decision tree based algorithm would serve you. The trick here is purely in the learning/sorting of the tree. I'd like to note that this is stuff I remember from AI class and student work in the AI working group and should be taken with a semi-large grain (or nugget) of salt.
To answer the questions:
You just walk the tree :)
This is a big downside of decision trees. You'd only have one guess that can be attached to the end nodes of the tree at depth 20 (or earlier, if the tree is still sparse).
There are whole books dedicated to this topic. As far as I remember from AI class you try minimize entropy at all times, so you want to ask questions that ideally divide the set of remaining objects into two sets of equal size. I'm afraid you'd have to look this up in AI books.
Decision trees are highly efficient during the query phase, as you literally walk the tree and follow the 'yes' or 'no' branch at each node. Update efficiency depends on the learning algorithm applied. You might be able to do this offline as in a nightly batched update or something like that.

Effective Timetabling Algorithm

I've got a job that I've been asked to do which involves writing a program to determine where various people are to work on a given day.
For example the input may be:
4-6pm, Site A
1-2pm, Site B
9-11am & 2-4pm Site A
Essentially there can be many sites and people can work during multiple blocks. I get the feeling that this kind of problem has been solved long ago so rather than reinventing the wheel I was hoping somebody could point me in the direction of an elegant solution.
Edit: Reading similar questions I get the feeling that the problem may be NP complete. I don't need the most efficient solution only something that works and is reasonably ok.
Edit 2: To clarify, the output should be a timetable with people allocated such that gaps (instances where nobody is working) is as small as possible.
Looks like you are trying to solve a problem for which there are quite specialized software applications. If your problem is small enough, you could try to do a brute force approach like this:
Determine the granularity of your problem. E.g. if this is for a school time table, your granularity can be 1 hour.
Make instances for every time slot divided by the granularity. So for Site B there will be one instance (1-2pm), for size A there will be many instances (4-5pm, 5-6pm, 9-10am, 10-11am, ...).
Make instances for all the persons you want to assign
Then iteratively assign a person to a free time slot taking all of your constraints into account (like holiday, lunch break, only being able to do one thing at a time, maximum number of people per site, ...) until:
you have a valid solution (fine, print it out and exit the application)
you enter a situation where you still need to place persons but there is no valid time slot anymore. Then backtrack (undo the last action and try to find an alternative for it).
If your problem is not too big you could find a solution in reasonable time.
However, if the problem starts to get big, look for more specialized software. Things to look for are "constraint based optimization" and "constraint programming".
E.g. the ECLIPSe tool is an open-source constraint programming environment. You can find some examples on http://eclipseclp.org/examples/index.html. One nice example you can find there is the SEND+MORE=MONEY problem. In this problem you have the following equation:
S E N D
+ M O R E
-----------
= M O N E Y
Replace every letter by a digit so that the sum is correct.
This also illustrates that although you can solve this brute-force, there are more intelligent ways to solve this (see http://eclipseclp.org/examples/sendmore.pl.txt).

Resources