|
I am designing a conference management system in C#. Part of the functionality involves automatic assignment of papers to conference reviewers. Now the authors of the papers specify keywords while they upload their papers to a database. The reviewers specify areas of interest while the register. I am trying to find ideas for an algorithm that can perform automatic assignment of the papers in a database table to reviewers in another table. The criteria for selection is comparison of the keywords to interests and deciding which reviewer (based on his interests) is most suitable for a paper or set of papers.
Thanks
|
|
|
|
|
for each paper you could consider each reviewer, calculate the number of matching keywords, then pick the one with the highest match.
potential problem: a reviewer with more keywords is likely to get (much) more papers assigned.
refinement 1:
calculate the the full matrix of paper-reviewer affinity as above, then pick the one article and reviewer that have the largest drop in affinity from the top to the second; that is the one where a specific reviewer is much more preferred than anywhere else. Now discard the article, and repeat this step again. and again. when a reviewer is getting too much work, discard him from the matrix and continue.
refinement 2:
take the order of the keywords into account: rather than just counting the matches, give them a weight that corresponds to their position in the list for article and reviewer respectively (say article keywords A,B,C,D and reviewer keyword A,E,F,B then A yields much more than B.
|
|
|
|
|
Is there any way you can translate this into C# code? That is the part I am confused about.....
|
|
|
|
|
I use a PC with a keyboard; and Visual Studio most often. Do you have a specific question?
|
|
|
|
|
alkowarizmi wrote: Is there any way you can translate this into C# code?
Yes he can. Is he going to do it for you? I don't think so.
|
|
|
|
|
you can get a bit idea with this code. Sorry I have not commented the code. was a quick example for you to get started if required.
<br />
public class Paper<br />
{<br />
private string _name;<br />
<br />
public string Name<br />
{<br />
get { return _name; }<br />
set { _name = value; }<br />
}<br />
private List<string> keywords;<br />
<br />
public List<string> Keywords<br />
{<br />
get { return keywords; }<br />
set { keywords = value; }<br />
}<br />
<br />
private Reviewer _paperreviewer;<br />
<br />
public Reviewer PaperReviewer<br />
{<br />
get { return _paperreviewer; }<br />
set { _paperreviewer = value; }<br />
}<br />
}<br />
<br />
public class Reviewer<br />
{<br />
private string _name;<br />
<br />
public string Name<br />
{<br />
get { return _name; }<br />
set { _name = value; }<br />
}<br />
private List<string> keywords;<br />
<br />
public List<string> Keywords<br />
{<br />
get { return keywords; }<br />
set { keywords = value; }<br />
}<br />
<br />
private int reviewCount;<br />
<br />
public int ReviewCount<br />
{<br />
get { return reviewCount; }<br />
set { reviewCount = value; }<br />
}<br />
}<br />
<br />
<br />
class PaperList<br />
<br />
{<br />
private List<Reviewer> _reviewers = new List<Reviewer>();<br />
private List<Paper> _papers = new List<Paper>();<br />
private IReviewStrategy _reviewstrategy;<br />
<br />
public PaperList(List<Paper> papers, List<Reviewer> reviewers)<br />
{<br />
_papers = papers;<br />
_reviewers = reviewers;<br />
}<br />
<br />
public void SetReviewStrategy(IReviewStrategy reviewstrategy)<br />
{<br />
this._reviewstrategy = reviewstrategy;<br />
}<br />
<br />
public void Review()<br />
{<br />
_papers=_reviewstrategy.FindReviewer(_papers, _reviewers);<br />
foreach (Paper p in _papers)<br />
{<br />
string reviewername=string.Empty;<br />
if (p.PaperReviewer != null)<br />
reviewername = p.PaperReviewer.Name;<br />
else<br />
reviewername = "None";<br />
Console.WriteLine(p.Name + " is reviewed by " + reviewername);<br />
}<br />
}<br />
<br />
}<br />
<br />
public interface IReviewStrategy<br />
{<br />
List<Paper> FindReviewer(List<Paper> papers, List<Reviewer> reviewers); <br />
}<br />
<br />
public class SimpleReviewStrategy:IReviewStrategy<br />
{<br />
public List<Paper> FindReviewer(List<Paper> papers, List<Reviewer> reviewers)<br />
{<br />
int KeyWordMatch=0;<br />
Reviewer bestReviewer = null;<br />
int bestKeyWordCount=0;<br />
foreach (Paper p in papers)<br />
{<br />
bestReviewer = null;<br />
bestKeyWordCount=0;<br />
foreach (Reviewer r in reviewers)<br />
{<br />
KeyWordMatch = CountKeyWordOccurences(p.Keywords, r.Keywords);<br />
if (KeyWordMatch > 0 && KeyWordMatch >= bestKeyWordCount)<br />
{<br />
if (KeyWordMatch > bestKeyWordCount)<br />
{<br />
bestKeyWordCount = KeyWordMatch;<br />
bestReviewer = r;<br />
}<br />
else<br />
{<br />
if (r.ReviewCount < bestReviewer.ReviewCount)<br />
{<br />
bestKeyWordCount = KeyWordMatch;<br />
bestReviewer = r;<br />
}<br />
}<br />
}<br />
<br />
}<br />
if (bestReviewer != null)<br />
p.PaperReviewer = bestReviewer;<br />
}<br />
return papers;<br />
}<br />
private int CountKeyWordOccurences(List<string> list1, List<string> list2)<br />
{<br />
int counter = 0;<br />
foreach (string l1 in list1)<br />
{<br />
if (list2.Contains(l1))<br />
counter++;<br />
}<br />
return counter;<br />
}<br />
}<br />
<br />
private void button1_Click(object sender, EventArgs e)<br />
{<br />
<br />
List<string> keywordset1=new List<string>();<br />
keywordset1.Add("music");<br />
List<string> keywordset2=new List<string>();<br />
keywordset2.Add("music");<br />
keywordset2.Add("science");<br />
List<string> keywordset3=new List<string>();<br />
keywordset3.Add("animal");<br />
keywordset3.Add("bird");<br />
keywordset3.Add("trees");<br />
List<string> keywordset4=new List<string>();<br />
keywordset4.Add("men");<br />
keywordset4.Add("women");<br />
<br />
List<string> keywordset5=new List<string>();<br />
keywordset5.Add("men");<br />
keywordset5.Add("animal");<br />
keywordset5.Add("music");<br />
keywordset5.Add("women");<br />
<br />
List<string> keywordset6=new List<string>();<br />
keywordset6.Add("love");<br />
keywordset6.Add("music");<br />
<br />
List<string> keywordset7 = new List<string>();<br />
keywordset7.Add("sex");<br />
<br />
<br />
List<Reviewer> reviewers = new List<Reviewer>();<br />
reviewers.Add(new Reviewer { Name = "Roshan", Keywords = keywordset2, ReviewCount = 0 });<br />
reviewers.Add(new Reviewer { Name = "Alice", Keywords = keywordset4, ReviewCount = 0 });<br />
<br />
List<Paper> papers = new List<Paper>();<br />
papers.Add(new Paper { Name = "P1", Keywords = keywordset5, PaperReviewer = null });<br />
papers.Add(new Paper { Name = "P2", Keywords = keywordset6, PaperReviewer = null });<br />
papers.Add(new Paper { Name = "P21", Keywords = keywordset7, PaperReviewer = null });<br />
<br />
PaperList simple = new PaperList(papers, reviewers);<br />
simple.SetReviewStrategy(new SimpleReviewStrategy());<br />
simple.Review();<br />
<br />
<br />
}<br />
|
|
|
|
|
I apologize in advance if this is the wrong forum for this post. It is definitely algorithm-related, though it may classify just as much as a personal RFP:
I am looking for a programmer who is looking for an algorithmic challenge. While I am a business applications developer by day, my hobby/pet-project has been the development of a railroad simulator/"video game". (Check out this series of screen shots.) Most of my endeavor has been very successful. However, where I feel totally defeated is in programming of the brake systems, which deal with the flow of compressed air.
I do not believe you need to be an expert in either brake systems or fluid dynamics. You just have to be good at solving algorithms. I can give you enough of a crash course to know what you need regarding trains. Regarding fluid dynamics, one has to remember this is a real-time video game. I don't want to waste lots of CPU power performing excessively accurate calculations. In fact, as long as the desired behavior is achieved, I don't really care how realistic the underlying algorithm is.
"What is the 'desired behavior'," you ask? Take a look at this article, which describes in detail what I'm trying to simulate. If you have general questions about what I am asking, please post those publicly on this thread so others can read the responses. However, I have also enabled private responses to this message for those who would like to proceed with this and therefore need to take the discussion outside of this thread.
As I said before, this is a pet project. It is not commercially funded. Therefore I do not have resources to pay -- at least not a lot. I might be able to contribute a little something for your time if you come up with the winning algorithm. But primarily you should only take this on if you're in it for the interesting challenge. Based on my experience, it's guaranteed to give you hours of hair-pulling frustration and nightmares in between.
Thanks for reading.
|
|
|
|
|
|
Doesn't look much like a game to me. But Choo-Choo!, what are you using to develop the GUI? I'm in to massivly parallel SIMD, OpenCL development, and a but of Directcompute, but there is not much info on the topic yet. Let me look at the parper describing the problem and consult my prinston math book. ~brb
|
|
|
|
|
I have a hard time picking a term to define what this program is. It's not really a "simulation" because it isn't scientifically accurate or complex enough. It's not a "game" because there's no end objective.
What probably isn't clear from the screen shots is that you start with a "Tron"-like grid. You model all the landscape yourself. You add the engines and train cars yourself. It's basically a model train layout without space limitations. You're only limited by your computer's specs. But I also come from a disciplined C++ training from before you could get gigs of RAM for pennies. My data structures squeeze the most out of every byte so you don't have to have the worlds greatest gaming computer to get a lot of capacity out of the software.
It's very similar to "Trainz" by Auran Games. There are reasons that I went through the trouble to write my own program instead of just using my copy of "Trainz", but I'm not going to bore everyone with that explanation here.
|
|
|
|
|
It's really not an algorithm. It's linear algebra. You need to know the state of the charge in the brake in terms of PSI for n cars. Each car dissipates the correct amount of release to slow down the car, and then starts to recharge the reservoir. This can be event driven to start charging, you have to know the rate at which it recharges. The rest is a set of linear equations to find what the correct amount of release is for the set of cars in the system. There are some good videos at MIT for solving linear equations for computer programs, if you google lineal algebra and click on videos. I think it's a long set, but you should get the core fundamentals in the forest 3 lecture.
~PB
|
|
|
|
|
You make some good points. I do know the rates of release and recharge and have been able to successfully develop computations when the locomotive is the only control point. However, I run into problems adding to the process the conditions where by air can be released from or added to the main pipe at each individual car valve.
There's also the issue of rapid set/release action. From the railroading standpoint it would not be correct to jostle the brake lever rapidly. However, good practice as a programmer is of course to try to anticipate all possible user input. I haven't been able to successfully track the creation and dissipation of pressure waves that would result from a rapid jostling of the brake lever.
I'll look up the videos you mentioned. Having fought with this as much as I have, you may well be right that the source of my issues is lack of knowledge in the appropriate mathematics (and/or physics) rather than any inability to develop code.
|
|
|
|
|
You could implement the jostling of the break valve as an event driven interface on a linked list and use a generic func type to adjust the values in the list, the list would contain the ascending and descending pressure values.
Once you find the right math....
|
|
|
|
|
Easier said than done. That's pretty close to the concept I have been working with -- keeping a list of "pressure zones" (sub-divisions of the brake pipe according to how far air can travel in one computation cycle) and trying to do relative comparisons of pressure from zone to zone. But there are a lot of complications that present themselves once you really dig into it.
|
|
|
|
|
FWIW: I did not read the article, but from your description it sounds like an "RC ladder network" (example[^] with each Y a capacitor (holding air), and each Z a resistor (preventing "air" to flow from one capacitor to the next). Such networks are pretty simple to simulate in the time-domain. I haven't done it recently, I did hundreds of those some decades ago.
ADDED
the ref to the book was mainly to the diagram; I am not suggesting one starts calculating transfer functions or Laplace transforms, a simple delta-V over delta-T simulation should do.
/ADDED
|
|
|
|
|
I read the article, very interesting. I think I'll stick to my Allen 10 Wheeler.
Dave.
|
|
|
|
|
I have a square that is created in 2D points that can be dragged about and it rotates depending on where the mouse drags ect.
The problem I am facing is getting the angle in radians as there is a texture that I would like to apply over the wireframe.
I have this so far to get the angle:
void GetAngle()
{
float dx = Points[0].Position.X - Points[1].Position.X;
float dy = Points[0].Position.Y - Points[1].Position.Y;
float angle = (float)Math.Atan2(dy, dx);
_angle = angle;
}
This works fine apart from that when the square is rotate (points) the texture rotates accordingly but its position changes, here is a screen shot of the issue.
http://img339.imageshack.us/img339/7786/captureas.png[^]
The texture should be inside the wire-frame.
If i rotate it to the left instead to the right the texture is below the wireframe!
This is a link to the project :
http://www.mediafire.com/?2i62poeedyw192n[^]
It is in C# and uses the XNA game programming engine.
Thanks for your help!
|
|
|
|
|
You need to rotate around the CENTER of your object.
Find the coordinates of the center (xCenter, yCenter), then subtract this point from all the points in your object, do the rotation, and finally add (xCenter, yCenter) back to each rotated point.
|
|
|
|
|
I figured out a better way! (although when you here it you may laugh...)
In the rendering of the spritebatch the "position" argument is Point[0].Position and the origin is Vector2.Zero xD
Simple yet for some reason I didn't get it straight away
Thank you though, that way would had worked well !
|
|
|
|
|
I have a program where a (indirect) recursive call to a certain function is forbidden.
It could easily introduce bugs that are hard to find.
(This function is the "core" of a finite state machine)
For now I throw an exception if someone still makes a recursive call to this function.
But if a certain condition never happens during debugging,
the recursive call might stay in the program.
It made me wonder if there is a feature in some compilers
(doesn't matter what language, any language. this is a very general question)
that detects recursion of a function and gives a warning/error
during compilation?
|
|
|
|
|
Define a static variable for the function you're trying to protect from recursion, and give it an initial value.
Then at the beginning of the function, test this variable and throw an exception if it DOESN'T have this initial value. If it does, set the variable to a different value, then reset it to the initial value just before you leave the function.
This detects recursion at run time. A few languages (like PL/I) require you to declare recursive functions as "recursive", but as far as I know, most languages won't allow you to detect and prevent recursion at compile time.
|
|
|
|
|
It's not a compiler function, but I believe there are code analysers out there that can build a (static) call graph. Loop in graph <=> recursive calls. Of course if you're using dynamic calling mechanisms (C: function pointers, Java, etc: reflection) you can hide recursion from static analysers, but that might be within the scope of manual checking. Of course, FSMs generally use such mechanisms, so you might wind up back where you started... Such is life. [Famous last words of one Ned Kelly, Australian Bushranger.]
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
|
OpenCL uses a subset of C-99 that explicitly does not allow recursion. to answer one of your questions.
|
|
|
|
|
I'm laying out various objects (FrameworkElements) on a surface (Canvas) and I've implemented all the usual algorithms for aligning them vertically (top, bottom and middle) and horizontally (left, right and center). Now I want to implement a distribute function that will evenly distribute selected objects. Now this would be easy if the all the objects are the same size (find the left most and right most objects, divide the space between them by the number of objects and then set the positions of the objects), but it's a bit more complicated when objects potentially have different sizes.
My brain feels a little backed up right now, is there a well-known and easy algorithm for doing this?
|
|
|
|