I have a layer structure that is something like this:
1.1
1.2
2.1
3.1
3.2
4.1
5.1
I want to output all possible combinations for every item but not including items with higher order than themselves, the order is the first number, so for example:
5.1 will have the following combinations:
(4.1, 3.1, 2.1, 1.1)
(4.1, 3.1, 2.1, 1.2)
(4.1, 3.2, 2.1, 1.1)
(4.1, 3.2, 2.1, 1.2)
And 4.1 will have:
(3.1, 2.1, 1.1)
(3.1, 2.1, 1.2)
(3.2, 2.1, 1.1)
(3.2, 2.1, 1.2)
I want to do it with recursive function, I have tried something but it does not work like it should, here it is in pseudo code.
I start with the layer order and go down till it gets to the layers with order of 1.
function recursion (layer)
if layer.order > 1 do
for iterationLayer in allLayers do
if iterationLayer.order == (layer.order - 1) do
print iterationLayer.name
recursion iterationLayer
else
end of combination
This code gives me something like this for 4.1 case
(3.1, 2.1, 1.1)
(1.2)
(3.2, 2.1, 1.1)
(1.2)
Its like this because when the recursion reach the last for loop it tracks back from the bottom to the top, does anyone have solution for this?
Pseudo code:
function recursionMain(level)
for iterationLayer in allLayers where (layer.level == level)
recursion (iterationLayer, new list)
function recursion(currentLayer, currentLayerList)
remainingLevelsList = get the distinct list of levels left to visit
if remainingLevelsList not empty
lowestRemamingLevel = get the lowest number from remainigLevelsList
for iterationLayer in allLayers where (layer.level == lowestRemainingLevel)
recursion (iterationLayer, currentLayerList + currentLayer)
else
print the list(combination) / end of combination
This is working sample in C#:
static void GetCombinationsR(int level)
{
foreach (Layer layer in layers.Where(l => l.Level == level))
{
GetCombinationsR(layer, new List<Layer>());
}
}
static void GetCombinationsR(Layer layer, List<Layer> currentLayers)
{
// Declaring new list so we don't loose the list of previous layers in currentLayers
List<Layer> currentLayers2 = new List<Layer>();
currentLayers2 = currentLayers2.Union(currentLayers).ToList();
currentLayers2.Add(layer);
// Getting the list of remaining levels because we are not certain
// if level 1 is the lowest or if some levels are skipped
List<int> remainingLevels = layers.Select(l => l.Level).Where(l => l < layer.Level).ToList();
if (remainingLevels.Count() > 0)
{
int firstLowerLevel = remainingLevels.OrderByDescending(l => l).First();
foreach (Layer layerByValue in layers.Where(l => l.Level == firstLowerLevel).ToArray())
{
GetCombinationsR(layerByValue, currentLayers2);
}
}
else
{
PrintResultList(currentLayers2);
}
}
static void PrintResultList(List<Layer> resultList)
{
StringBuilder sb = new StringBuilder();
foreach (Layer layer in resultList)
{
sb.Append(layer.Level).Append(": ").Append(layer.Value).Append(" -> ");
}
sb = sb.Remove(sb.Length - 4, 4);
Console.WriteLine(sb.ToString());
}
Perhaps you need something like this:
function recursion (layer, combination)
if layer = 0
print combination
else
for (i = 0; i < layer.itemcount; i++)
recursion(layer - 1, combination + layer.item[i])
recursion(layer-1, empty[])
Delphi example (not optimal, we can search faster and break loop early)
var
A: TArray<string>;
procedure recursion (layer: Integer; combination: string);
var
i: integer;
begin
if layer = 0 then
Memo1.Lines.Add(combination)
else
for i := 0 to High(A) do
if A[i][1] = IntToStr(layer) then //primitive check of layer
recursion(layer - 1, combination + A[i] + ', ')
end;
begin
A := ['1.1','1.2','2.1','3.1','3.2','4.1','5.1'];
recursion(4, '');
generates
4.1, 3.1, 2.1, 1.1,
4.1, 3.1, 2.1, 1.2,
4.1, 3.2, 2.1, 1.1,
4.1, 3.2, 2.1, 1.2,
Related
I have been asked to implement a function "fold" for an assessment, which takes a double table, its int size, a double initial value and a double function as arguments. It should return a double by cumulatively applying the function to the elements of the table, starting with the initial value.
For example, with the table {1.0, 2.0, 3.0, 4.0, 5.0}, the initial value 10.0 and the adding function, it should return :
((((((((((10.0 + 1.0) + 1.0) + 2.0) + 2.0) + 3.0) + 3.0) + 4.0) + 4.0) + 5.0) + 5.0) = 40.0
I know I could have done iteratively but for some reasons I decided to be an elegant programmer and use recursion. Here is my program :
double fold(double* tab, int size, double init, double func(double, double)){
double result = func(func(init, *tab), *tab);
if (size > 0){
return fold(tab + 1, size - 1, result, func);
}
return result;
}
And here is my test :
int main(){
double init = 10.0;
double table[5] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
double result = fold(table, 5, init, &add);
printf("Expected: %f, Result: %f", 40.0, result);
}
When run once, it gives me the correct result, but when I re-run it it explodes to huge values. Does anyone know where the problem is ?
When size == 0, you reference table[5], which is random memory just off then of table[]. Change if (size > 0) { to if (size > 1) {.
Me and my friend are trying to implement a paper and the last step requires solving a linear programming problem to get the final result. We are not so familiar with LP so i'd like to ask for your help.
Here's the function which is based on the PROFSET model
and here's the proposed constraints
(1)
(2)
where:
Pa and Qi are the binary decision variables
J are all the available categories
F are sets of frequent categories
Φ is the total number of selected categories
Constraint (1) actually says that Qi is 1 if category i is included in some itemset A where Pa = 1
Basically, we are trying to use some common open source lp solvers (like joptimizer) but we dont know
how to define those constraints, especially those that define set inclusion rules. Most of those solvers
seem to accept just inequalities.
So, do you have any idea about how to define those constraints? Maybe transform them to inequalities or
something? Any help would be appreciated.
Thank you
A constraint that is written as an equality can be also written as two inequalities.
e.g.
A*x=b is the same as
A*x<=b and A*x>=b
In order to write such a LP there are two ways.
To hardcode it, meaning writing everything in code for example in Java.
Write it the mathematical way in a "language" called AMPL: https://ampl.com/resources/the-ampl-book/ For the second way you don't really need to know a programming language. AMPL transforms magically your LP into code and feeds it to a solver e.g. commercial: CPLEX, Gurobi (academic license available) or open source: GLPK. AMPL provides also an online platform that you can provide your model as .mod file and data as .dat files.
If you still want to hardcode your LP GLPK has nice examples e.g. in JAVA:
public class Lp {
// Minimize z = -.5 * x1 + .5 * x2 - x3 + 1
//
// subject to
// 0.0 <= x1 - .5 * x2 <= 0.2
// -x2 + x3 <= 0.4
// where,
// 0.0 <= x1 <= 0.5
// 0.0 <= x2 <= 0.5
// 0.0 <= x3 <= 0.5
public static void main(String[] arg) {
glp_prob lp;
glp_smcp parm;
SWIGTYPE_p_int ind;
SWIGTYPE_p_double val;
int ret;
try {
// Create problem
lp = GLPK.glp_create_prob();
System.out.println("Problem created");
GLPK.glp_set_prob_name(lp, "myProblem");
// Define columns
GLPK.glp_add_cols(lp, 3);
GLPK.glp_set_col_name(lp, 1, "x1");
GLPK.glp_set_col_kind(lp, 1, GLPKConstants.GLP_CV);
GLPK.glp_set_col_bnds(lp, 1, GLPKConstants.GLP_DB, 0, .5);
GLPK.glp_set_col_name(lp, 2, "x2");
GLPK.glp_set_col_kind(lp, 2, GLPKConstants.GLP_CV);
GLPK.glp_set_col_bnds(lp, 2, GLPKConstants.GLP_DB, 0, .5);
GLPK.glp_set_col_name(lp, 3, "x3");
GLPK.glp_set_col_kind(lp, 3, GLPKConstants.GLP_CV);
GLPK.glp_set_col_bnds(lp, 3, GLPKConstants.GLP_DB, 0, .5);
// Create constraints
// Allocate memory
ind = GLPK.new_intArray(3);
val = GLPK.new_doubleArray(3);
// Create rows
GLPK.glp_add_rows(lp, 2);
// Set row details
GLPK.glp_set_row_name(lp, 1, "c1");
GLPK.glp_set_row_bnds(lp, 1, GLPKConstants.GLP_DB, 0, 0.2);
GLPK.intArray_setitem(ind, 1, 1);
GLPK.intArray_setitem(ind, 2, 2);
GLPK.doubleArray_setitem(val, 1, 1.);
GLPK.doubleArray_setitem(val, 2, -.5);
GLPK.glp_set_mat_row(lp, 1, 2, ind, val);
GLPK.glp_set_row_name(lp, 2, "c2");
GLPK.glp_set_row_bnds(lp, 2, GLPKConstants.GLP_UP, 0, 0.4);
GLPK.intArray_setitem(ind, 1, 2);
GLPK.intArray_setitem(ind, 2, 3);
GLPK.doubleArray_setitem(val, 1, -1.);
GLPK.doubleArray_setitem(val, 2, 1.);
GLPK.glp_set_mat_row(lp, 2, 2, ind, val);
// Free memory
GLPK.delete_intArray(ind);
GLPK.delete_doubleArray(val);
// Define objective
GLPK.glp_set_obj_name(lp, "z");
GLPK.glp_set_obj_dir(lp, GLPKConstants.GLP_MIN);
GLPK.glp_set_obj_coef(lp, 0, 1.);
GLPK.glp_set_obj_coef(lp, 1, -.5);
GLPK.glp_set_obj_coef(lp, 2, .5);
GLPK.glp_set_obj_coef(lp, 3, -1);
// Write model to file
// GLPK.glp_write_lp(lp, null, "lp.lp");
// Solve model
parm = new glp_smcp();
GLPK.glp_init_smcp(parm);
ret = GLPK.glp_simplex(lp, parm);
// Retrieve solution
if (ret == 0) {
write_lp_solution(lp);
} else {
System.out.println("The problem could not be solved");
}
// Free memory
GLPK.glp_delete_prob(lp);
} catch (GlpkException ex) {
ex.printStackTrace();
ret = 1;
}
System.exit(ret);
}
/**
* write simplex solution
* #param lp problem
*/
static void write_lp_solution(glp_prob lp) {
int i;
int n;
String name;
double val;
name = GLPK.glp_get_obj_name(lp);
val = GLPK.glp_get_obj_val(lp);
System.out.print(name);
System.out.print(" = ");
System.out.println(val);
n = GLPK.glp_get_num_cols(lp);
for (i = 1; i <= n; i++) {
name = GLPK.glp_get_col_name(lp, i);
val = GLPK.glp_get_col_prim(lp, i);
System.out.print(name);
System.out.print(" = ");
System.out.println(val);
}
}}
Kotlin provides some usingful extension functions allow stream-like programming.
For example, if I look for an element in a list I can use find:
return list.find { n -> n>4 && n<6 }
But when I have a have nested lists this seems not practical for me. I have tu use forEach then -- luckyly I can return from an inner Lambda with Kotlin:
private fun findUsingForEach(data: List<List<Int>>, pred : (Int) -> Boolean) : Optional<Int> {
data.forEach { list ->
list.forEach { n ->
if( pred(n) ) return Optional.of(n)
}
}
return Optional.empty()
}
It seems fo me that forEach is not the right tool for that. Is there a more functional way to du this? filter comes to mind, but the nesting causes problems.
That follwing is the test I use for the function abouve:
#Test
open fun findTest() {
val data = listOf( listOf(1,2,3), listOf(3,4,5,6), listOf(), listOf(6,7,8) )
val e = findUsingForEach( data, { n -> n>4 && n < 6 } )
assertEquals(5, e.get())
}
You could flatten the list:
fun <T> Iterable<Iterable<T>>.flatten(): List<T> (source)
Returns a single list of all elements from all collections in the given collection.
val data = listOf(listOf(1, 2, 3), listOf(3, 4, 5, 6), listOf(), listOf(6, 7, 8))
data.flatten().find { n -> n > 4 && n < 6 }
This will return a single list with the elements of the sublists in order. Then you can use find as usual.
In your example,
{{1, 2, 3}, {3, 4, 5, 6}, {}, {6, 7, 8}}
becomes
{1, 2, 3, 3, 4, 5, 6, 6, 7, 8}
and the result of find on this list is 5.
However, this will create a new list. Take a look at the source of flatten:
/**
* Returns a single list of all elements from all collections in the given collection.
*/
public fun <T> Iterable<Iterable<T>>.flatten(): List<T> {
val result = ArrayList<T>()
for (element in this) {
result.addAll(element)
}
return result
}
If you want to save memory, create a Sequence from your list first:
data.asSequence()
and then perform your operations on this sequence:
data.asSequence().flatten().find { n -> n > 4 && n < 6 }
Side note: your predicate, n > 4 && n < 6, is simply equivalent to n == 5.
If you just want to reduce codes and you don't care much about efficiency, try this.
list.flatten().find { your pred here }
Or
list.flatMap { it }.find { your pred }
Or create a useful utility which doesn't create new lists (faster/lower memory taken):
inline fun <T> Iterable<Iterable<T>>.forEachEach(f: (T) -> Unit) =
forEach { it.forEach(f) }
I create an interactive map as follows:
library(leafletR)
data(quakes)
# store data in GeoJSON file (just a subset here)
q.dat <- toGeoJSON(data=quakes[1:99,], dest=tempdir(), name="quakes")
# make style based on quake magnitude
q.style <- styleGrad(prop="mag", breaks=seq(4, 6.5, by=0.5), style.val=rev(heat.colors(5)), leg="Richter Magnitude", fill.alpha=0.7, rad=8)
# create map
q.map <- leaflet(data=q.dat, dest=tempdir(), title="Fiji Earthquakes", base.map="osm", style=q.style, popup="mag")
# view map in browser
rstudio::viewer(q.map)
Now, I want to make the size of the circle dependent on another variable. Let's say the variable 'stations'. How can I do this? If it is not possible with this package, I am open to use another package ... as long as I can put a legend, the map is interactive, a pop-up appear when clicked on and the color can depend on the value of a continuous variable.
I read through the documentation for the leafletR package, and it seems to me (and I could be wrong) that the current version doesn't support multiple styles for the same dataset. They give a few examples where they combine 2 styleSingles by listing them (e.g. style=list(sty.1, sty.2)), but that only works in conjunction with listing 2 different datasets (see P.8 in the document for more details). I tried various tricks, but none of them worked for me.
However, I came up with a hacky solution that you might want to try. After the html page is created using the leaflet() function, you can edit the Javascript code that handles the styling to make the radius property dynamic (this could also work for the other styling properties, such as fill, alpha, etc.).
What you need to know:
In the HTML document that leaflet creates, search for the definition of the style1(feature) function. You should find the following segment of code:
function style1(feature) {
return {"color": getValue(feature.properties.mag),
"fillOpacity": 0.7,
"radius": 8};
}
This function basically returns the style for each record in your dataset. As you can see, the function in its current form returns a static value for fillOpacity and radius. However, when it comes to color, it calls another function called getValue and passes it the mag (magnitude) property. If we take a look at the definition of the getValue function, we'll see that it simply defines the magnitude ranges for each color:
function getValue(x) {
return x >= 6.5 ? "#808080" :
x >= 6 ? "#FF0000" :
x >= 5.5 ? "#FF5500" :
x >= 5 ? "#FFAA00" :
x >= 4.5 ? "#FFFF00" :
x >= 4 ? "#FFFF80" :
"#808080";
}
The function definition is really simple. If x (the magnitude in this case) is greater or equal to 6.5, then the color of that data point will be "#808080". If it's between 6 and 6.5, then the color will be #FF0000". And so on and so forth.
What you can do:
Now that we see how the Javascript code handles how the colors are assigned to each data point, we can do something similar for all the other styling properties with very minimal effort. The following code segment, for instance, shows how you can make the radius dynamic based on the count of stations in the area:
/* The getValue function controls the color of the data points */
function getValue(x) {
return x >= 6.5 ? "#808080" :
x >= 6 ? "#FF0000" :
x >= 5.5 ? "#FF5500" :
x >= 5 ? "#FFAA00" :
x >= 4.5 ? "#FFFF00" :
x >= 4 ? "#FFFF80" :
"#808080";
}
/* The getRadValue function controls the radius of the data points */
function getRadValue(x) {
return x >= 100 ? 24 :
x >= 80 ? 20 :
x >= 60 ? 16 :
x >= 40 ? 12 :
8;
}
/* The updated definition of the style1 function */
function style1(feature) {
return {"color": getValue(feature.properties.mag),
"fillOpacity": 0.7,
"radius": getRadValue(feature.properties.stations)
};
}
So, with the new definition of style1(feature), now we can control both the color as well as the radius of the data points. The result of the code modification looks like this:
The good thing about this approach is that it gives you more fine-grained control over the styling properties and the range of values that they can have. The major draw-back is going to be that if you want to add a legend for those properties, then you'll have to do that manually. The logic for adding/editing the legend should be at the very bottom of the HTML document, and if you know Javascript/HTML/CSS, editing that code segment shouldn't be too difficult.
Update:
To add a legend for the new dynamic variable (in our case, the radius), you need to edit the .onAdd handler that's attached to the legend object. As I said before, the definition for this handler is usually at the bottom of the html page, and if we run the bit of code that you provided in your question, then the handler should look like this:
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'legend');
var labels = [];
var grades = [4, 4.5, 5, 5.5, 6, 6.5];
div.innerHTML += 'Richter Magnitude<br>';
for (var i = 0; i < grades.length - 1; i++) {
div.innerHTML += '<i style="background:' + getValue(grades[i]) + '"></i> ' + grades[i] + '–' + grades[i + 1] + '<br>';
}
return div;
};
The above code simply loops through the range of values for the magnitude, and creates a box (with the appropriate color, referencing the getValue function that we looked at before) and a label. If you want to create something similar for the stations variable, let's say, we can use the same logic above. Though in this case instead of varying the color, we'll be varying the size of the circle. The following segment of code shows how to achieve that:
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'legend');
var labels = [];
var grades = [4, 4.5, 5, 5.5, 6, 6.5];
div.innerHTML += 'Richter Magnitude<br>';
for (var i = 0; i < grades.length - 1; i++) {
div.innerHTML += '<i style="background:' + getValue(grades[i]) + '"></i> ' + grades[i] + '–' + grades[i + 1] + '<br>';
}
// Adding the range of possible of values that the variable might take
// This should be in sync with the range of values you considered in
// the getRadValue function.
var rad_grades = [40, 60, 80, 100];
// The title for this section of the legend
div.innerHTML += 'Number of stations<br>'
for (var i = 0; i < rad_grades.length - 1; i++) {
div.innerHTML += '<table style="border: none;"><tr><td class="circle" style="width: ' +
(getRadValue(rad_grades[rad_grades.length - 2]) * 2 + 6) + 'px;"><svg style="width: ' +
(getRadValue(rad_grades[i]) * 2 + 6) + 'px; height: ' + (getRadValue(rad_grades[i]) * 2 + 6) +
'px;" xmlns="http://www.w3.org/2000/svg" version="1.1"><circle cx="' + (getRadValue(rad_grades[i]) + 3) + '" cy="' +
(getRadValue(rad_grades[i]) + 3) + '" r="' + getRadValue(rad_grades[i]) + '" /></svg></td><td class="value">' +
rad_grades[i] + '–' + rad_grades[i + 1] + '</td></tr></table>';
}
return div;
};
As you can see, the type of styling property we're controlling will determine how we're specifying it in the legend. If you want to add a legend for the alpha property, for instance, then you might want to try some other approach other than using circles and controlling their width and height. The end result of the code modifications above looks like this:
Also, if you want to include the number of stations in the popup, then you'll have to edit the onEachFeature function. It's going to be the same approach we took with all the other modifications, and it's a really simple change.
The onEachFeature function looks like this in the original HTML:
function onEachFeature(feature, layer) {
if (feature.properties && feature.properties.mag) {
layer.bindPopup("mag: " + feature.properties.mag);
}
}
If you want to include the number of stations in the popup too, then you need to include it in the argument to the bindPopup method, as follows:
function onEachFeature(feature, layer) {
if (feature.properties && feature.properties.mag && feature.properties.stations) {
layer.bindPopup("mag: " + feature.properties.mag + "<br> # Stations: " + feature.properties.stations);
}
}
The end result of this change is the following:
Hope this helps.
This is what I currently have:
What I need, is to have the following uneven intervals (vertical lines & x-axis labels):
1) 1 (i.e. must not cross at 0)
2) 1.5
3) 2.5
4) 3.5
5) 4
Is there any way to do this? Even if it's a kludge with an extra series or something - although I'm hoping it's something to do with IntervalOffset, but I can't get it to do what I want.
Currently, I just have:
chartarea.AxisX.Maximum = 4;
chartarea.AxisX.Minimum = 1;
chartarea.AxisX.Interval = 1;
This is what was required:
// set the max & min, with an interval of 1 which is offset by 0.5
// this gives the correct start (1), and three .5 intervals
// however, it doesn't give the closing vertical line at 4
chartarea.AxisX.Maximum = 4;
chartarea.AxisX.Minimum = 1;
chartarea.AxisX.Interval = 1;
chartarea.AxisX.IntervalOffset = 0.5;
// enable a secondary y axis for the line at 4
chartarea.AxisY2.Enabled = AxisEnabled.True;
// switch of all tickmarks & gridlines
chartarea.AxisY2.MajorTickMark.Enabled = false;
chartarea.AxisY2.MinorTickMark.Enabled = false;
chartarea.AxisY2.MajorGrid.Enabled = false;
chartarea.AxisY2.MinorGrid.Enabled = false;
chartarea.AxisY2.LabelStyle.Enabled = false;
// set the correct colour & line style
chartarea.AxisY2.LineColor = Color.FromArgb(160, 160, 160);
chartarea.AxisY2.LineDashStyle = ChartDashStyle.Dash;
// add custom labels for the 5 points/lines
chartarea.AxisX.CustomLabels.Add(0.9, 1.1, "1");
chartarea.AxisX.CustomLabels.Add(1.4, 1.6, "1.5");
chartarea.AxisX.CustomLabels.Add(2.4, 2.6, "2.5");
chartarea.AxisX.CustomLabels.Add(3.4, 3.6, "3.5");
chartarea.AxisX.CustomLabels.Add(3.9, 4.1, "4");
And voila:
(although my data has changed)