I need either mathematical solution or programming solution in PHP - php

I am thinking to arrange office room.
Office room is always noisy, and you are thinking to separate each room users as possible as you
can so that they don’t feel uncomfortable.
If they are facing each other, we will add unhappy point as 1.
INPUT
What we can do here is based on given rooms and users, arrange room separately so people don’t
feel uncomfortable.
[row, column, users] -> unhappy points
Example 1: [2, 3, 6]
*2 Rows, 3 Columns, 6 people
Example 2: [3, 3, 8]
*3 Rows, 3 Columns, 8 people
Sample Output
]
Following are some Test Cases :
[5,2,8]-> 7
[3,5,14]-> 18
[1,16,1]-> 0
[3,5,1]-> 0
[8,2,12]-> 10
[16,1,1]-> 0
[3,3,6]-> 3
[2,6,12]-> 16
[15,1,0]-> 0
[5,3,7]-> 0
[4,3,5]-> 0
I need either mathematical solution or programming solution in PHP.

This is not a complete question because how will you determine that two rooms are facing each other and one more thing is that how are you counting 7 unhappy points for first example.
I've observes that if you are taking a matrix lets say 4 by 5 than you can put 4*5=20 peoples there.So how will you count more than 20 points while we have only 20 people?

Related

Mysql return only items that have n number of property matches

I have a database of items and each item has various number of properties. Is it possible for MySql only to return items that have a certain number of matches (not properties) when a search is run?
Example: I am searching for any item with a wheel that is red and has a tire.
This would return all items with these three matches even if they have more properties and would automatically exclude anything that has less than 3 matches.
I have tried playing with the COUNT + GROUP BY + HAVING but I was unable to put together a meaningful working code. Before I spend more time on this I would like to know if it is possible at all.
TABLE DESIGN
ID ITEM PROPERTY
1 1 red
2 1 wheel
3 1 tire
4 2 red
5 2 wheel
6 2 tire
7 2 lamp
8 3 red
9 3 wheel
10 4 red
I would like it to return ITEM 1 and 2
You would do this with a group by and having. You really provide no information about your data structure, but the basic idea is:
select ip.item
from design ip
where ip.property in ('wheel', 'red', 'tire')
group by ip.item
having count(distinct ip.property) = 3;

how do i determine which questions to ask a user in a quiz based on previous answers

I have a list of questions in a category, and want to choose a subset of them to ask the user based on which ones they answered right/wrong previously.
I want to make it random, but in a way that the ones they have more trouble with are asked more frequently.
EDIT: I'm trying to figure out how to calculate the weight/bias/score for each question based on the number of times they've answered it right/wrong.
I came up with the following, but it seems odd to me:
I assign a score to each question based on how many times they answered it right/wrong
Obviously, if they've never been asked that question I need to assign an arbitrary score (I chose 5)
For all other question, I use the formula
score = wrong*2-right
so if I had the following 10 questions, the "score" would be calculated for each of them (R=# of times they got it right, W=# of times they got it wrong and S=score). From there, I take the lowest score and assign that a probability of 1 (in this case it was id=5 with a score of -7). I then take the difference between the lowest score and the second lowest score (id=1 with -5, a difference of 2) and assign it a probability of 1 + the difference = 3.
I continue this for every question, and then at the end I can just choose a random number between Min(1) and Max(82) and select the question that has the highest P where random < P. So if my random # was 79 I would choose id=2.
But this seems long and convoluted. Is there an easier way to do this (I'm using PHP and mysql, But I plan to do this within an app with a local datastore as well)
id R W S P
1 5 0 -5 3
2 3 5 7 82
3 6 2 -2 8
4 2 2 2 23
5 9 1 -7 1
6 3 1 -1 14
7 0 0 5 68
8 7 5 3 33
9 6 5 4 44
10 3 4 5 56
EDIT: to clarify, I'm stuck on the issue of "weight" (P value in my example)...I'm trying to find a good (and fast) way of calculating the "weight" for each problem, given the number of right and wrong answers they've given for the question
I am not sure if I understand your answer correctly but it seems you are looking for a sort of "weighted" random number generator. In essense what you want to do is give the problems they are having issues with more weight. Perhaps create a class called questions with a property of weight in it. That property can hold how much weight you put in it. Then when you select a random number generator use something like this.
http://codetheory.in/weighted-biased-random-number-generation-with-javascript-based-on-probability/
After doing some research, I realize that my initial method of calculating a weight is bit slow. After using the formula, I end up with some -ve weights. I then have to go through each one and add ABS(MIN(S)) to each weight, which is unnecessary.
My new formula would be S = CEILING(Wrong * 5 / Right)
Obviously I'd need to account for 0 values, so the code would be:
if (R == 0 AND W == 0) S = 10
else if (R == 0) S = W*5
else if (W == 0) S = CEILING(5/R)
else S = CEILING(W * 5 / R)
I've worked out the numbers for a few sample sets and this gives me fairly good results. It also allows me to keep the SCORE value updated in the database, so it doesn't need to be recalculated every time (just updated whenever that question is answered)
Once I have a set of 60 or so questions and I want to choose 5 or 10 of them, I can just create a random # between 1-SUM(SCORE) and then use a binary search to figure out which question that represents.
If anyone has a better suggestion for calculating the score/weight/bias or whatever it's called, I'd appreciate it.

Detecting columns in a document (table) via php - Algorithm

Given a table like the one below, what would be the best way to detect the two columns separately?
So what I would need the total colspans for the first column.
What is important to remember is that the nr of columns can change.
In the case of this example, the second column starts at "10 euro" (second row). The first section is equal to 2 colspans. The other section is 5 colspans.
Any (abstract) ideas on how to do this?
You must consider the gaps in between the table cells and mark their positions, like this::
0 1 2 3 4 7
0 2 3 4 5 6 7
0 1 2 4 5 7
...
0 2 7
Once you have built an array with above information, you iterate over them and mark the common gap locations:
0 2 7
Since 0 and 7 are both at the edges of your table, you can strip those off. Then you're left with position 2 as the common gap between your rows.
Done :)

Algorithm that creates "teams" based on a numeric skill value

I am building an application that helps manage frisbee "hat tournaments". The idea is people sign up for this "hat tournament". When they sign up, the provide us with a numeric value between 1 and 6 which represents their skill level.
Currently, we are taking this huge list of people who signed up, and manually trying to create teams out of this based on the skill levels of each player. I figured, I could automate this by creating an algorithm that splits up the teams as evenly as possible.
The only data feeding into this is the array of "players" and a desired "number of teams". Generally speaking we are looking at 120 players and 8 teams.
My current thought process is to basically have a running "score" for each team. This running score is the total of all assigned players skill levels. I loop through each skill level. I go through rounds of picks once inside skill level loop. The order of the picks is recalculated each round based on the running score of a team.
This actually works fairly well, but its not perfect. For example, I had a range of 5 pts in my sample data array. I could very easily, manually swap players around and make the discrepancy no more then 1 pt between teams.. the problem is getting that done programatically.
Here is my code thus far: http://pastebin.com/LAi42Brq
Snippet of what data looks like:
[2] => Array
(
[user__id] => 181
[user__first_name] => Stephen
[user__skill_level] => 5
)
[3] => Array
(
[user__id] => 182
[user__first_name] => Phil
[user__skill_level] => 6
)
Can anyone think of a better, easier, more efficient way to do this? Many thanks in advance!!
I think you're making things too complicated. If you have T teams, sort your players according to their skill level. Choose the top T players to be captains of the teams. Then, starting with captain 1, each captain in turn chooses the player (s)he wants on the team. This will probably be the person at the top of the list of unchosen players.
This algorithm has worked in playgrounds (and, I dare say on the frisbee fields of California) for aeons and will produce results as 'fair' as any more complicated pseudo-statistical method.
A simple solution could be to first generating a team selection order, then each team would "select" one of the highest skilled player available. For the next round the order is reversed, the last team to select a player gets first pick and the first team gets the last pick. For each round you reverse the picking order.
First round picking order could be:
A - B - C - D - E
second round would then be:
E - D - C - B - A
and then
A - B - C - D - E etc.
It looks like this problem really is NP-hard, being a variant of the Multiprocessor scheduling problem.
"h00ligan"s suggestions is equivalent to the LPT algorithm.
Another heuristic strategy would be a variation of this algorithm:
First round: pick the best, second round: pair the teams with the worst (add from the end), etc.
With the example "6,5,5,3,3,1" and 2 teams this would give the teams "6,1,5" (=12) and "5,3,3" (=11). The strategy of "h00ligan" would give the teams "6,3,3" (=12) and "5,5,1" (=11).
This problem is unfortunately NP-Hard. Have a look at bin packing which is probably a good place to start and includes an algorithm you can hopefully tweak, this may or may not be useful depending on how "fair" two teams with the same score need to be.

(poor man's )product recommendation implementation

I am trying to build a poor man's recommendation system for a online store.
I want to realize that kind of Amazon "Customers Who Bought This Item Also Bought" feature and I read a lot about it.
I know there is that Apache Mahout thing, but I am unable to tweak the server that way. Then there would be the google prediction API, but it cost money so I start experimenting myself.
I got an orderhistory with 250.000+ items and I wrote a nested MySQL Query to find orders which contain the current article, rank the other order items and sort that table for ranking, so I got a set of products which other people ordered along with the current article.
The problem is, the query could take up to 10sec - so this can't be used directly.
I thought about a caching table, but this query stops after 20 minutes (there are 60.000 products and 250.000 ordered items) So I am unable to fill that table.
My current workaround is the following:
The recommendation HTML is loaded via AJAX ondocumentready, so the site loads, while the recommendation loads in the background. The recommendation data is processed once and stored in a filecache (PEAR simple cache) so it loads faster the next time. So the cache is made on demand if someone visits the site and stored for a day or maybe a week.
I ask myself and you, would that be an acceptable approach or is it stupid and unperformant?
Would it be better to store the cached data in a db or in file (I think about performance and parallel hits). I mean, in the worst case I would endup with 60.000 cachefiles.
I would prefer a pre-computed table with all the data, but as I said it takes to long and I don't know how to optimize it. (Waiting till the SQL Dude come back from holidays ^^)
Thanks for any hint, opinion.
btw. this is the query:
SELECT c.ArtNr as artnr , count(c.ArtNr) as rank, s.ArtNr as parent_artnr
FROM (
SELECT a.ID_order, a.ArtNr
FROM net_orderposition a
WHERE a.ArtNr = 'TT-PV0005'
) s
JOIN net_orderposition c
WHERE s.ID_order = c.ID_order AND s.ArtNr != c.ArtNr
GROUP BY c.ArtNr
ORDER BY rank DESC,c.Stamp DESC
LIMIT 10;
EDIT:
I thought about the given answers and I think they are similar to my initial idea.
The above code result in the following table:
ID,ParentID , ChildID , Rank
1, TT-PV0005, TT-PV0040, 220
2, TT-PV0005, TT-PV0355, 135
3, TT-PV0005, TT-PV0450, 134
4, TT-PV0005, TT-PV0451, 89
5, TT-PV0005, RH-01V2 , 83
6, TT-PV0005, TT-PV0041, 83
7, TT-PV0005, TT-PV0353, 82
8, TT-PV0005, TT-PV0037, 80
The ParentID is the current item, ChildID the items that ordered in the past along with ParentID, Rank is the precomputed count of how often the child is ordered with current item.
Now I can UPDATE or INSERT related items on every new order and count up Rank if it's already present in DB.
The only thing I fear, I will endup in a really really big table.
Maybe it shouldn't be a problem, if I precalculate it offline once a week?
But then I have to optimize the query so it doesn't take 10 sec per item.
What do you think?
check out easyrec it has the features you need and is free. no tweaking needed and you can use the Demo instance like google analytics. I think it will be much easier to just use this free to use web service then code the whole logic on your own.
In a tweet today they mentioned that they support full mahout support to easyrec so you have the whole thing with easyrec.You can either use easyrec's free webservice or deploy the free WAR file on your webserver.
To add to #GalacticCowboy's answer and fill in where you're comment was, #Marcus...
One schema to accomplish this would be to create a table like:
RelatedItems
RelatedItemsId
purchasedItemId
relatedItemId
Then when an order is completed (or viewed depending on your requirements) you'd write records to the RelatedItems table, where each item purchased gets a record where that id is the purchasedItemId. Then all the other items would be written as the relatedItemId.
For example, if I made a purchase of Items 5, 9, 12, and 19, I would have 12 records that were written to my table that look like:
RelatedItemId, PurchasedItemId, RelatedItemId
1, 5, 9
2, 5, 12
3, 5, 19
4, 9, 5
5, 9, 12
6, 9, 19
7, 12, 5
8, 12, 9
9, 12, 19
10, 19, 5
11, 19, 9
12, 19, 12
Then you could usage a query similar to GalacticCowboy to get the top 10 items that were normally purchased alongside any of those items.
Please note, this is not the most efficient schema for a task like this, it could be tweaked quite a bit to reduce redundant data, but given that we don't know an awful lot about your system and overall schema design (and what seems a shaky understanding of some SQL concepts) I'm not going to go deep into that.
Every time there's an order, store a relationship record between the different items in the order. Then do something like:
SELECT ItemID, COUNT(RelatedItemID) AS RelatedItemCount
FROM RelatedItems
WHERE RelatedItemID = #viewingItemID
GROUP BY ItemID
ORDER BY RelatedItemCount DESC
LIMIT 10
You could also presummarize this using an overnight process or something and have a table that only contains the top n related items for each item ID.

Categories