microsoft solver foundation constraint logical erro - c#

This is the formula that I want to add as a constraint to the Microsoft solver foundation.
I am using the SumTermBuilder class in this code but solver gives me the wrong result and there is no compilation error for this code. Why am I getting the wrong result?
Code:
var N_Available_Total = new SumTermBuilder(decisions.Count());
var OM_Available_Total = new SumTermBuilder(decisions.Count());
var Hourly = new SumTermBuilder(96);
for (int i = 1; i < 97; i++)
{
foreach (var item in newfeed)
{
float x = item.N_ED_Available_at_time_Total[i]/100;
float y = item.OM_ED_Available_at_time_Total[i]/100;
//get decision variables list
var feeddecision = model.Decisions.First(it => it.Name == item.feed);
//summation of all decision variables
N_Available_Total.Add(feeddecision * x); // For N
OM_Available_Total.Add(feeddecision * y); // for OM
}
Hourly.Add((Model.Sqrt(Model.Power((25 - ((N_Available_Total.ToTerm() / OM_Available_Total.ToTerm()))), 2)))/96);
}
var SIConstraint = (25 - ((Hourly.ToTerm())) / 25) >= 0.9;
model.AddConstraint("SI", SIConstraint);

Related

Rotate 2D points using System.Numerics.Vectors

I'm looking to optimize a program that is basing a lot of its calculations on the rotation of a lot of 2D Points. I've search around to see if it's possible to do these calculations using SIMD in C#.
I found a c++ answer here that seems to do what I want, but I can't seem to translate this into C# using the System.Numerics.Vectors package.
Optimising 2D rotation
Can anyone point me in the right direction for how this can be done?
The below code shows the regular method without SIMD. Where Point is a struct with doubles X and Y.
public static Point[] RotatePoints(Point[] points, double cosAngle, double sinAngle)
{
var pointsLength = points.Length;
var results = new Point[pointsLength];
for (var i = 0; i < pointsLength; i++)
{
results[i].X = (points[i].X * cosAngle) - (points[i].Y * sinAngle);
results[i].Y = (points[i].X * sinAngle) + (points[i].Y * cosAngle);
}
return results;
}
Edit:
I've managed to get an implementation working using two Vector< float> but from benchmarking this, this seems to be a lot slower than the previous implementation.
private static void RotatePoints(float[] x, float[] y, float cosAngle, float sinAngle)
{
var chunkSize = Vector<float>.Count;
var resultX = new float[x.Length];
var resultY = new float[x.Length];
Vector<float> vectorChunk1;
Vector<float> vectorChunk2;
for (var i = 0; i < x.Length; i += chunkSize)
{
vectorChunk1 = new Vector<float>(x, i);
vectorChunk2 = new Vector<float>(y, i);
Vector.Subtract(Vector.Multiply(vectorChunk1, cosAngle), Vector.Multiply(vectorChunk2, sinAngle)).CopyTo(resultX, i);
Vector.Add(Vector.Multiply(vectorChunk1, sinAngle), Vector.Multiply(vectorChunk2, cosAngle)).CopyTo(resultY, i);
}
}
The code added in the edit is a good start, however the codegen for Vector.Multiply(Vector<float>, float) is extremely bad so this function should be avoided. It's an easy change to avoid it though, just broadcast outside the loop and multiply by a vector. I also added a more proper loop bound and "scalar epilog" in case the vector size does not neatly divide the size of the input arrays.
private static void RotatePoints(float[] x, float[] y, float cosAngle, float sinAngle)
{
var chunkSize = Vector<float>.Count;
var resultX = new float[x.Length];
var resultY = new float[x.Length];
Vector<float> vectorChunk1;
Vector<float> vectorChunk2;
Vector<float> vcosAngle = new Vector<float>(cosAngle);
Vector<float> vsinAngle = new Vector<float>(sinAngle);
int i;
for (i = 0; i + chunkSize - 1 < x.Length; i += chunkSize)
{
vectorChunk1 = new Vector<float>(x, i);
vectorChunk2 = new Vector<float>(y, i);
Vector.Subtract(Vector.Multiply(vectorChunk1, vcosAngle), Vector.Multiply(vectorChunk2, vsinAngle)).CopyTo(resultX, i);
Vector.Add(Vector.Multiply(vectorChunk1, vsinAngle), Vector.Multiply(vectorChunk2, vcosAngle)).CopyTo(resultY, i);
}
for (; i < x.Length; i++)
{
resultX[i] = x[i] * cosAngle - y[i] * sinAngle;
resultY[i] = x[i] * sinAngle + y[i] * cosAngle;
}
}

How to distribute items evenly, without random numbers

I have a situation where I need to evenly distribute N items across M slots. Each item has its own distribution %. For discussion purposes say there are three items (a,b,c) with respective percentages of (50,25,25) to be distributed evenly across 20 slots. Hence 10 X a,5 X b & 5 X c need to be distributed. The outcome would be as follows:
1. a
2. a
3. c
4. b
5. a
6. a
7. c
8. b
9. a
10. a
11. c
12. b
13. a
14. a
15. c
16. b
17. a
18. a
19. c
20. b
The part that I am struggling with is that the number of slots, number of items and percentages can all vary, of course the percentage would always total up to 100%. The code that I wrote resulted in following output, which is always back weighted in favour of item with highest percentage. Any ideas would be great.
1. a
2. b
3. c
4. a
5. b
6. c
7. a
8. b
9. c
10. a
11. c
12. b
13. a
14. b
15. c
16. a
17. a
18. a
19. a
20. a
Edit
This is what my code currently looks like. Results in back weighted distribution as I mentioned earlier. For a little context, I am trying to evenly assign commercials across programs. Hence every run with same inputs has to result in exactly the same output. This is what rules out the use of random numbers.
foreach (ListRecord spl in lstRecords){
string key = spl.AdvertiserName + spl.ContractNumber + spl.AgencyAssignmentCode;
if (!dictCodesheets.ContainsKey(key)){
int maxAssignmentForCurrentContract = weeklyList.Count(c => (c.AdvertiserName == spl.AdvertiserName) && (c.AgencyAssignmentCode == spl.AgencyAssignmentCode)
&& (c.ContractNumber == spl.ContractNumber) && (c.WeekOf == spl.WeekOf));
int tmpAssignmentCount = 0;
for (int i = 0; i < tmpLstGridData.Count; i++)
{
GridData gData = tmpLstGridData[i];
RotationCalculation commIDRotationCalc = new RotationCalculation();
commIDRotationCalc.commercialID = gData.commercialID;
commIDRotationCalc.maxAllowed = (int)Math.Round(((double)(maxAssignmentForCurrentContract * gData.rotationPercentage) / 100), MidpointRounding.AwayFromZero);
tmpAssignmentCount += commIDRotationCalc.maxAllowed;
if (tmpAssignmentCount > maxAssignmentForCurrentContract)
{
commIDRotationCalc.maxAllowed -= 1;
}
if (i == 0)
{
commIDRotationCalc.maxAllowed -= 1;
gridData = gData;
}
commIDRotationCalc.frequency = (int)Math.Round((double)(100/gData.rotationPercentage));
if (i == 1)
{
commIDRotationCalc.isNextToBeAssigned = true;
}
lstCommIDRotCalc.Add(commIDRotationCalc);
}
dictCodesheets.Add(key, lstCommIDRotCalc);
}else{
List<RotationCalculation> lstRotCalc = dictCodesheets[key];
for (int i = 0; i < lstRotCalc.Count; i++)
{
if (lstRotCalc[i].isNextToBeAssigned)
{
gridData = tmpLstGridData.Where(c => c.commercialID == lstRotCalc[i].commercialID).FirstOrDefault();
lstRotCalc[i].maxAllowed -= 1;
if (lstRotCalc.Count != 1)
{
if (i == lstRotCalc.Count - 1 && lstRotCalc[0].maxAllowed > 0)
{
//Debug.Print("In IF");
lstRotCalc[0].isNextToBeAssigned = true;
lstRotCalc[i].isNextToBeAssigned = false;
if (lstRotCalc[i].maxAllowed == 0)
{
lstRotCalc.RemoveAt(i);
}
break;
}
else
{
if (lstRotCalc[i + 1].maxAllowed > 0)
{
//Debug.Print("In ELSE");
lstRotCalc[i + 1].isNextToBeAssigned = true;
lstRotCalc[i].isNextToBeAssigned = false;
if (lstRotCalc[i].maxAllowed == 0)
{
lstRotCalc.RemoveAt(i);
}
break;
}
}
}
}
}
}
}
Edit 2
Trying to clear up my requirement here. Currently, because item 'a' is to be assigned 10 times which is the highest among all three items, towards the end of distribution, items 16 - 20 all have been assigned only 'a'. As has been asked in comments, I am trying to achieve a distribution that "looks" more even.
One way to look at this problem is as a multi-dimensional line drawing problem. So I used Bresenham's line algorithm to create the distribution:
public static IEnumerable<T> GetDistribution<T>( IEnumerable<Tuple<T, int>> itemCounts )
{
var groupCounts = itemCounts.GroupBy( pair => pair.Item1 )
.Select( g => new { Item = g.Key, Count = g.Sum( pair => pair.Item2 ) } )
.OrderByDescending( g => g.Count )
.ToList();
int maxCount = groupCounts[0].Count;
var errorValues = new int[groupCounts.Count];
for( int i = 1; i < errorValues.Length; ++i )
{
var item = groupCounts[i];
errorValues[i] = 2 * groupCounts[i].Count - maxCount;
}
for( int i = 0; i < maxCount; ++i )
{
yield return groupCounts[0].Item;
for( int j = 1; j < errorValues.Length; ++j )
{
if( errorValues[j] > 0 )
{
yield return groupCounts[j].Item;
errorValues[j] -= 2 * maxCount;
}
errorValues[j] += 2 * groupCounts[j].Count;
}
}
}
The input is the actual number of each item you want. This has a couple advantages. First it can use integer arithmetic, which avoids any rounding issues. Also it gets rid of any ambiguity if you ask for 10 items and want 3 items evenly distributed (which is basically just the rounding issue again).
Here's one with no random number that gives the required output.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// name, percentage
Dictionary<string, double> distribution = new Dictionary<string,double>();
// name, amount if one more were to be distributed
Dictionary<string, int> dishedOut = new Dictionary<string, int>();
//Initialize
int numToGive = 20;
distribution.Add("a", 0.50);
distribution.Add("b", 0.25);
distribution.Add("c", 0.25);
foreach (string name in distribution.Keys)
dishedOut.Add(name, 1);
for (int i = 0; i < numToGive; i++)
{
//find the type with the lowest weighted distribution
string nextUp = null;
double lowestRatio = double.MaxValue;
foreach (string name in distribution.Keys)
if (dishedOut[name] / distribution[name] < lowestRatio)
{
lowestRatio = dishedOut[name] / distribution[name];
nextUp = name;
}
//distribute it
dishedOut[nextUp] += 1;
Console.WriteLine(nextUp);
}
Console.ReadLine();
}
}
Instead of a truly random number generator, use a fixed seed, so that the program has the same output every time you run it (for the same input). In the code below, the '0' is the seed, which means the 'random' numbers generated will always be the same each time the program is run.
Random r = new Random(0);
//AABC AABC…
int totalA = 10
int totalB = 5
int totalC = 5
int totalItems = 20 //A+B+C
double frequencyA = totalA / totalItems; //0.5
double frequencyB = totalB / totalItems; //0.25
double frequencyC = totalC / totalItems; //0.25
double filledA = frequencyA;
double filledB = frequencyB;
double filledC = frequencyC;
string output = String.Empty;
while(output.Length < totalItems)
{
filledA += frequencyA;
filledB += frequencyB;
filledC += frequencyC;
if(filledA >= 1)
{
filledA -= 1;
output += "A";
if(output.Length == totalItems){break;}
}
if(filledB >= 1)
{
filledB -= 1
output += "B";
if(output.Length == totalItems){break;}
}
if(filledC >= 1)
{
filledC -= 1
output += "C";
if(output.Length == totalItems){break;}
}
}
This answer was mostly stolen and lightly adapted for your use from here
My idea is that you distribute your items in the simplest way possible without care of order, then shuffle the list.
public static void ShuffleTheSameWay<T>(this IList<T> list)
{
Random rng = new Random(0);
int n = list.Count;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
Fiddle here

Replicate Excel Power Trendline values with c#

I need to replicate this Excel graph in code
Given a list of [x, y] values, how can I obtain a new list of values to graph the power trendline?
I've found people referring to this http://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html formula. But don't know how to generate a new list of values from this.
Follow the formula from the link:
function getFittedPoints(data) {
var log = Math.log,
pow = Math.pow,
sums = [
0, // sum of the logarithms of x ( sum(log(x)) )
0, // sum of the logarithms of y ( sum(log(y)) )
0, // sum of the logarithms of the products of x and y ( sum(log(x) * log(y)) )
0 // sum of the powers of the logarithms of x ( sum((log(x))^2 )
],
fittedPoints = [], // return fitted points
a, // a coefficient
b, // b coefficient
dataLen = data.length,
i,
logX,
logY;
for (i = 0; i < dataLen; i++) {
sums[0] += logX = log(data[i][0]);
sums[1] += logY = log(data[i][1]);
sums[2] += logX * logY;
sums[3] += pow(logX, 2);
}
b = (i * sums[2] - sums[0] * sums[1]) / (i * sums[3] - pow(sums[0], 2));
a = pow(Math.E, (sums[1] - b * sums[0]) / i);
for (i = 0; i < dataLen; i++) {
fittedPoints.push([
data[i][0],
a * pow(data[i][0], b)
]);
}
return fittedPoints;
}
And then apply the function to the data.
example: http://jsfiddle.net/fa3m4Lvf/
Of course if your data are not clean then you can improve the function with handling null values,etc.
And for those like me who are looking for the C# version of morganfree's answer above, here it is translated:
public static IEnumerable<double> GetPowerTrendline(IList<double> knownY, IList<double> knownX, IList<double> newX)
{
var sums = new double[4];
var trendlinePoints = new List<double>();
var dataLen = knownX.Count;
for (var i = 0; i < dataLen; i++)
{
var logX = Math.Log(knownX[i]);
var logY = Math.Log(knownY[i]);
sums[0] += logX;
sums[1] += logY;
sums[2] += logX * logY;
sums[3] += Math.Pow(logX, 2);
}
var b = (dataLen * sums[2] - sums[0] * sums[1]) / (dataLen * sums[3] - Math.Pow(sums[0], 2));
var a = Math.Pow(Math.E, (sums[1] - b * sums[0]) / dataLen);
foreach (var x in newX)
{
var pointY = a * Math.Pow(x, b);
trendlinePoints.Add(pointY);
}
return trendlinePoints;
}
Note that it is modified so that it takes a list of desired x points instead of using the provided ones.
I followed the example calculation based on this: http://www.statisticshowto.com/how-to-find-a-linear-regression-equation/
Modified Adams example based on this and came upp with this solution for C#. This is assumes you have all the existing scatter plots. The result is a number of arraylists with the all the x and y values for the trendline that you can directly insert into highcharts.
public static List<ArrayList> GetPowerTrendline(List<KeyValuePair<int,double>> xyValues)
{
var trendlinePoints = new List<ArrayList>();
var dataLen = xyValues.Count;
var xSum = xyValues.Sum(h => h.Key);
var ySum = xyValues.Sum(h => h.Value);
var XYSum = xyValues.Sum(h => h.Key * h.Value);
var xp2Sum = xyValues.Sum(x => Math.Pow(x.Key, 2));
var a = (ySum * xp2Sum - xSum * XYSum) / (dataLen * xp2Sum - Math.Pow(xSum, 2));
var b = ((dataLen * XYSum) - (xSum * ySum)) / (dataLen * xp2Sum - Math.Pow(xSum,2));
foreach (var x in xyValues.OrderBy(h => h.Key))
{
var pointY = a + b * x.Key;
var rounded = Math.Round(pointY, 2);
trendlinePoints.Add(new ArrayList { x.Key, rounded });
}
return trendlinePoints;
}
And in my HighCharts method like this:
series: [
{
type: 'line',
name: 'Trendlinje',
data: data.RegressionLine,
color: '#444444',
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
enableMouseTracking: false
},

Get the Range of Lat Long with in specified Radius in c#

I am working on a website in which I have the User's Location Lat and Long saved in my Location table. Now I want to use a filter SearchByDistance which have values: 5km, 10km, 15km through which the user can get the results according to the specified Range.
Now what I actually wants to do is to get the input from the user say 5km and get the results from my table which falls with in the range of user's saved LatLong in the Location table and 5km to that LatLong. I google on this and found some links like:
How do I find the lat/long that is x km north of a given lat/long
http://msdn.microsoft.com/en-us/library/system.device.location.geocoordinate.getdistanceto%28v=vs.110%29.aspx
But I am unable to get my requirement from the above. Please help. Thanks
I think your approach can be, first create a circle (your center will be user lat and long) with the given radius say 5KM or 10Km and then find the rows from the Polygon Rings. I wrote it for esri maps. Hope it will solve your problem
Polygon areaOfInterset;
void CreateCircle(double radius)
{
var point = new MapPoint(Your Lat and Long);// This will be user lat and long on which you want to draw a circle
var graphic = new Graphic();
var circle = new ESRI.ArcGIS.Client.Geometry.PointCollection();
int i = 0;
while (i <= 360)
{
double degree = (i * (Math.PI / 180));
double x = point.X + Math.Cos(degree) * radius;
double y = point.Y + Math.Sin(degree) * radius;
circle.Add(new MapPoint(x, y));
i++;
}
var rings = new ObservableCollection<ESRI.ArcGIS.Client.Geometry.PointCollection> { circle };
areaOfInterset = new Polygon { Rings = rings};
}
Now next task is to find the rows. For that you can use below code inside the loop.
foreach(MapPoint selectedRow in DatabaseRowsToBeSearched)
{
var isExist = IsInsideCircle(selectedRow)
}
bool IsInsideCircle(MapPoint location)
{
var isInside = false;
foreach (var shape in areaOfInterset.Rings)
{
for (int i = 0, j = shape.Count - 1; i < shape.Count; j = i++)
{
if ((((shape[i].Y <= location.Y) && (location.Y < shape[j].Y)) ||
((shape[j].Y <= location.Y) && (location.Y < shape[i].Y))) &&
(location.X < (shape[j].X - shape[i].X) * (location.Y - shape[i].Y) / (shape[j].Y - shape[i].Y) + shape[i].X))
{
isInside = !isInside;
}
}
}
return isInside;
}

should i create complex nested structures with Linq or traditional loops?

so out of the following 3 examples that do the same thing i really lean towards the first but is it really overkill and an abuse of linq to do things that way where you can create it all as an expression
var Rand = new Random();
Hosts = "abcdef".Select(x =>
{
return new HostMachineToUpdate(x + "_Host",
Enumerable.Range(1, Rand.Next(3, 8))
.Select(y => new VirtualMachineToUpdate(x + y.ToString() + "_VM")).
ToList()
);
}
)
.ToList();
//traditional
Hosts = new List<HostMachineToUpdate>();
for (int x = (int)'a'; x < (int)'e'; x++)
{
var Guests = new List<VirtualMachineToUpdate>();
for (int y = 1; y < (new Random().Next(3, 8));y++ )
{
Guests.Add(new VirtualMachineToUpdate((char)x + y.ToString() + "_VM"));
}
Hosts.Add(new HostMachineToUpdate((char) x + "Host",Guests));
}
//very traditional.
Hosts = new List<HostMachineToUpdate>();
int lower = (int)'a';
int upper = (int)'e';
for (int x = lower; x < upper; x++)
{
List<VirtualMachineToUpdate> Guests = new List<VirtualMachineToUpdate>();
int randomItemNum = new Random().Next(3, 8);
for (int y = 1; y < randomItemNum; y++)
{
string vmname = (char)x + y.ToString() + "_VM";
VirtualMachineToUpdate vm = new VirtualMachineToUpdate(vmname);
Guests.Add(vm);
}
string hostname = (char)x + "Host";
HostMachineToUpdate host = new HostMachineToUpdate(hostname, Guests);
Hosts.Add(host);
}
I personally don't like the amount of casting used in your traditional solution.
Is all the casting actually needed ?
Wouldn't this (untested) code also do what is required?
// traditional.
Hosts = new List<HostMachineToUpdate>();
foreach (char x in "abcd")
{
List<VirtualMachineToUpdate> Guests = new List<VirtualMachineToUpdate>();
int randomItemNum = new Random().Next(3, 8);
for (int y = 1; y < randomItemNum; y++)
{
Guests.Add(new VirtualMachineToUpdate(x + y.ToString() + "_VM"));
}
Hosts.Add(new HostMachineToUpdate(x + "Host", Guests));
}
I prefer the declarative approach, so something like the first option. But I would rather use the C# syntax. Something vaguely like:
(from x in Enumerable.Range('a', 'e'-'a')
select new HostMachineToUpdate(
(char)x + "_Host",
(from y in Enumerable.Range(1, new Random.Next(3,8))
select new VirtualMachineToUpdate((char)x + y.ToString() + "_VM")).ToList())
.ToList();
It feels close. May be a missing ( or ).
If each of your solutions executes fast enough for your needs, then it is safe to say that the machine cannot tell the difference between these options.
The important consideration devolves down to how expressive or clear is the code to a human reader because in the future someone will have to understand, debug or extend the code. In the above case, try this out. Leave the code alone for two weeks. When you return, decide which of the options is easiest to understand.
For myself this is a reality check. In the past I have been proud of writing some clever code, but in reality a simpler solution was the right solution.

Categories