I'm putting together a simple chess position evaluation function. This being the first time for me building a chess engine, I am feeling very tentative with putting in just any evaluation function. The one shown on this Chess Programming Wiki page looks like a good candidate. However this has an ellipsis at the end which makes me unsure of whether it will be a good one to use?
Once the whole engine is in place and functional, I intend to come back to the evaluation function and make a real attempt to sorting it out properly. But for now I need some sort of function which is good enough to play against an average amateur.
The most basic component of an evaluation function is material, obviously. This should be perfectly straightforward, but on its own does not lead to interesting play. The engine has no sense of position at all, and simply reacts to tactical lines. But we will start here:
value = white_material - black_material // calculate delta material
Next we introduce some positional awareness through piece-square tables. For example, this is a such a predefined table for pawns:
pawn_table = {
0, 0, 0, 0, 0, 0, 0, 0,
75, 75, 75, 75, 75, 75, 75, 75,
25, 25, 29, 29, 29, 29, 25, 25,
4, 8, 12, 21, 21, 12, 8, 4,
0, 4, 8, 17, 17, 8, 4, 0,
4, -4, -8, 4, 4, -8, -4, 4,
4, 8, 8,-17,-17, 8, 8, 4,
0, 0, 0, 0, 0, 0, 0, 0
}
Note that this assumes the common centipawn (value of pawn is ~100) value system. For each white pawn we encounter, we index into the table with the pawn's square and add the corresponding value.
for each p in white pawns
value += pawn_table[square(p)]
Note that we can use use a simple calculation to reflect the table when indexing for black pieces. Alternatively you can define separate tables.
For simple evaluation this will work very well and your engine will probably already be playing common openings. However, it's not too hard to make some simple improvements. For example, you can create tables for the opening and the endgame, and interpolate between them using some sort of phase calculation. This is especially effective for kings, where their place shifts from the corners to the middle of the board as the game progresses.
Thus our evaluation function may look something like:
evaluate(position, colour) {
phase = total_pieces / 32 // this is just an example
opening_value += ... // sum of evaluation terms
endgame_value += ...
final_value = phase * opening_value + (1 - phase) * endgame_value
return final_value * sign(colour) // adjust for caller's perspective
}
This type of evaluation, along with quiescence search, should be enough to annihilate most amateurs.
Related
I've read the document here, and from previous question, I can see
The setIndex function is used to specify triangle indices that
reference the vertex attribute buffers on the BufferGeometry.
I think I understand 50% of these concepts, but in this interleaved example, (code is here) What is the purpose of setting index (I know it is specifying triangle indices)? but why?
var indices = new Uint16Array( [
0, 1, 2,
2, 1, 3,
4, 5, 6,
6, 5, 7,
8, 9, 10,
10, 9, 11,
12, 13, 14,
14, 13, 15,
16, 17, 18,
18, 17, 19,
20, 21, 22,
22, 21, 23
] );
geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
My understanding is there are 24 vertexes, and the set index tells the renderer to use vertex at a specific index (not natural order) to arrange a triangle. But why is a new arrangement needed? Do I have to do setIndex every time in my own code?
Using an indexed geometry is not required. If you are not using indices, the triangles are defined by the order of vertices in the buffer. In this case, you talk about non-indexed geometries. Indices are especially useful if many vertices are shared between triangles/faces. Using an index buffer allows you to save some memory then.
The official documentation page about BufferGeometry provides more information about both geometry types.
First thing first, I am new to the world of statistics.
Problem statement:
I have three predicted time series. These time series represent three independent scores, the sum of which is desired to be minimized over timeslot while selecting it. Length of the timeslot is already provided. I have read that there is confidence based selection of predicted interval for such problems, but I have used LSTM to predict the time series which may restrict me to use that approach, perhaps I think calculating the predicted interval is related to single time series.
e.g: Consider below arrays represent the three predicted time series.
arr1 = [23, 34, 16, 5, 45, 10, 2, 34, 56, 11]
arr2 = [123, 100, 124, 245, 125, 120, 298, 124, 175, 200]
arr3 = [1, 3, 10, 7, 2, 2, 10, 7, 8, 12]
time slot length = 3
As you could see, optimal timeslot for arr1 is [5, 7], for arr2 is [0, 2], and arr3 for is [3, 5], but I need only one timeslot for all three time series.
Questions:
Which error paradigm I should employ to select the optimal time slot?
I also have given weights(positive real number in [0, 1]) which represents the importance of particular time series in deciding timeslot. How do I employ it in error paradigm?
This is a follow up question to Can you use clpfd to implement a coverage algorithm?
I have put the code here: http://swish.swi-prolog.org/p/Coverage%20using%20Constraints%20%20.pl
There are two search procedures.
start_exhaustive_search(Positives,Negatives,r(Features, Value,cm(TP,FP)))
And a heuristic search :
start_search(Ps,Ns,Result).
The heuristic search will refine a rule until it does not cover any negatives. cm is for confusion matrix.
There are three ways to test the predicates, one with a small database accessible with pos(Ps) and negs(Ns). Then a larger database accessible with approved(Ps) and notapproved(Ns). This also has some predicates to turn the binary representation of used features into a list of named features.binary_to_features(Binary,Features).
You can also generate a random matrix of examples using random_binary_matrix_x_y(X,Y,R) (With X as 9 the result will be compatible with the larger approved/notapproved example.).
Example exhaustive query:
?-approved(Ps),notapproved(Ns),start_exhaustive_search(Ps,Ns,Result).
Result = r([0, 0, 0, 0, 0, 0, 0, 1, 0, 0], 21, cm(6, 1)).
Example heuristic query:
?-approved(Ps),notapproved(Ns),start_search(Ps,Ns,Result).
Result = [r([0, 0, 0, 0, 0, 0, 0, 1, 0, 0], 21, cm(6, 1)), r([0, 0, 0, 0, 0, 0, 0, 1, 0, 1], 20, cm(4, 0))]
So both methods do not seem to be as fast as I would imagine is possible using the constraints. Is there a way to improve the speed?
Also I am curious why I cant use dif/2 but have to use \== on line 98?
I am using card/2 to count the number of examples covered, I cant see another way to use this?
My question:
I have searched through available Ruby gems to find one that performs k-means clustering. I've found quite a few: kmeans, kmeans-clustering, reddavis-k_means and k_means_pp. My problem is that none of the gems deals with one-dimensional k-means clustering. They all expect input like this:
[[1, 2], [3, 4], [5, 6]]
My input looks like this:
[1, 2, 3, 4, 5, 6]
Hence my question: How do I perform a one-dimensional k-means clustering using Ruby?
The context (my task):
I have 100 input values:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 8, 8, 10, 16, 18, 22, 22, 35, 50, 50
Each value represents a response time, i.e. the number of minutes it took for some customer service agent to respond to an email from a customer. So the first value 0 indicates that the customer only waited 0 minutes for a response.
I need to find out how many fast, medium-fast and slow response time instances there is. In other words, I want to cut my input values up in 3 pools, and then count how many there are in each pool.
The complicating factor is that I based on the overall slope steepness have to figure out where to make the cuts. There is no fixed definition of fast, medium-fast and slow. The first cut (between fast and medium-fast) should occur where the steepness of the slope starts to increase more drastically than before. The second cut (between medium-fast and slow) should occur when an even more dramatic steepness increase occur.
Here is a graphical representation of the input values.
In the above example, common sense would probably define fast as 0-3, because there are many instances of 0, 1, 2, and 3. 4-8 or 4-10 looks like common sense choices for medium-fast. But how to determine something like this mathematically? If the response times were generally faster, then the customers would be expecting this, so an even smaller increase towards the end should trigger the cut.
Finishing notes:
I did find the gem davidrichards-kmeans that deals with one-dimensional k-means clustering, but it don't seem to work properly (the example code raises a syntax error).
k-means is the wrong tool for this job anyway.
It's not designed for fitting an exponential curve.
Here is a much more sound proposal for you:
Look at the plot, mark the three points, and then you have your three groups.
Or look at quantiles... Report the median response time, the 90% quantile, and the 99% quantile...
Clustering is about structure discovery in multivariate data. It's probably not what you want it to be, sorry.
If you insist on trying k-means, try encoding the data as
[[1], [2], [3], [4], [5]]
and check if the results are at least a little bit what you want them to be (also remember that k-means is randomized. Running it multiple times may yield very different results).
Is there something like an anti-filter in image processing?
Say for instance, I am filtering an image using the following 13 tap symmetric filter:
{0, 0, 5, -6, -10, 37, 76, 37, -10, -6, 5, 0, 0} / 128
Each pixel is changed by this filtering process. My question is can we get back the original image by doing some mathematical operation on the filtered image.
Obviously such mathematical operations exists for trivial filters, like:
{1, 1} / 2
Can we generalize this to complex filters like the one I mentioned at the beginning?
Here is a pointer to one method of deconvolution - taking account of noise which in your case I guess you have due to rounding error - http://en.wikipedia.org/wiki/Wiener_deconvolution