Laguerre interpolation algorithm, something's wrong with my implementation - c++

This is a problem I have been struggling for a week, coming back just to give up after wasted hours...
I am supposed to find coefficents for the following Laguerre polynomial:
P0(x) = 1
P1(x) = 1 - x
Pn(x) = ((2n - 1 - x) / n) * P(n-1) - ((n - 1) / n) * P(n-2)
I believe there is an error in my implementation, because for some reason the coefficents I get seem way too big. This is the output this program generates:
a1 = -190.234
a2 = -295.833
a3 = 378.283
a4 = -939.537
a5 = 774.861
a6 = -400.612
Description of code (given below):
If you scroll the code down a little to the part where I declare array, you'll find given x's and y's.
The function polynomial just fills an array with values of said polynomial for certain x. It's a recursive function. I believe it works well, because I have checked the output values.
The gauss function finds coefficents by performing Gaussian elimination on output array. I think this is where the problems begin. I am wondering, if there's a mistake in this code or perhaps my method of veryfying results is bad? I am trying to verify them like that:
-190.234 * 1.5 ^ 5 - 295.833 * 1.5 ^ 4 ... - 400.612 = -3017,817625 =/= 2
Code:
#include "stdafx.h"
#include <conio.h>
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
double polynomial(int i, int j, double **tab)
{
double n = i;
double **array = tab;
double x = array[j][0];
if (i == 0) {
return 1;
} else if (i == 1) {
return 1 - x;
} else {
double minusone = polynomial(i - 1, j, array);
double minustwo = polynomial(i - 2, j, array);
double result = (((2.0 * n) - 1 - x) / n) * minusone - ((n - 1.0) / n) * minustwo;
return result;
}
}
int gauss(int n, double tab[6][7], double results[7])
{
double multiplier, divider;
for (int m = 0; m <= n; m++)
{
for (int i = m + 1; i <= n; i++)
{
multiplier = tab[i][m];
divider = tab[m][m];
if (divider == 0) {
return 1;
}
for (int j = m; j <= n; j++)
{
if (i == n) {
break;
}
tab[i][j] = (tab[m][j] * multiplier / divider) - tab[i][j];
}
for (int j = m; j <= n; j++) {
tab[i - 1][j] = tab[i - 1][j] / divider;
}
}
}
double s = 0;
results[n - 1] = tab[n - 1][n];
int y = 0;
for (int i = n-2; i >= 0; i--)
{
s = 0;
y++;
for (int x = 0; x < n; x++)
{
s = s + (tab[i][n - 1 - x] * results[n-(x + 1)]);
if (y == x + 1) {
break;
}
}
results[i] = tab[i][n] - s;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int num;
double **array;
array = new double*[5];
for (int i = 0; i <= 5; i++)
{
array[i] = new double[2];
}
//i 0 1 2 3 4 5
array[0][0] = 1.5; //xi 1.5 2 2.5 3.5 3.8 4.1
array[0][1] = 2; //yi 2 5 -1 0.5 3 7
array[1][0] = 2;
array[1][1] = 5;
array[2][0] = 2.5;
array[2][1] = -1;
array[3][0] = 3.5;
array[3][1] = 0.5;
array[4][0] = 3.8;
array[4][1] = 3;
array[5][0] = 4.1;
array[5][1] = 7;
double W[6][7]; //n + 1
for (int i = 0; i <= 5; i++)
{
for (int j = 0; j <= 5; j++)
{
W[i][j] = polynomial(j, i, array);
}
W[i][6] = array[i][1];
}
for (int i = 0; i <= 5; i++)
{
for (int j = 0; j <= 6; j++)
{
cout << W[i][j] << "\t";
}
cout << endl;
}
double results[6];
gauss(6, W, results);
for (int i = 0; i < 6; i++) {
cout << "a" << i + 1 << " = " << results[i] << endl;
}
_getch();
return 0;
}

I believe your interpretation of the recursive polynomial generation either needs revising or is a bit too clever for me.
given P[0][5] = {1,0,0,0,0,...}; P[1][5]={1,-1,0,0,0,...};
then P[2] is a*P[0] + convolution(P[1], { c, d });
where a = -((n - 1) / n)
c = (2n - 1)/n and d= - 1/n
This can be generalized: P[n] == a*P[n-2] + conv(P[n-1], { c,d });
In every step there is involved a polynomial multiplication with (c + d*x), which increases the degree by one (just by one...) and adding to P[n-1] multiplied with a scalar a.
Then most likely the interpolation factor x is in range [0..1].
(convolution means, that you should implement polynomial multiplication, which luckily is easy...)
[a,b,c,d]
* [e,f]
------------------
af,bf,cf,df +
ae,be,ce,de, 0 +
--------------------------
(= coefficients of the final polynomial)

The definition of P1(x) = x - 1 is not implemented as stated. You have 1 - x in the computation.
I did not look any further.

Related

manhattan distance works better than manhattan distance + linear conflict

I try to implement A* algorithm with both manhattan distance and manhattan distance + linear conflict heuristic.
but my manhattan distance works much better and I can't understand why!
manhattan distance + linear conflict in my algorithm expands much more node and i found that it's answer it not even optimal.
#include <iostream>
#include <time.h>
#include <fstream>
#include <set>
#include <vector>
#include <queue>
#include <map>
#include "node.h"
using namespace std;
const int n = 4;
const int hash_base = 23;
const long long hash_mod = 9827870924701019;
set<long long> explored;
set<pair<int , node*> > frontier;
map<string,int> database[3];
void check(int* state){
for(int j = 0 ; j < n ; j++){
for(int i = 0 ; i < n ; i++)
cerr << state[j * n + i] << " ";
cerr << endl;
}
cerr << endl;
}
bool goal_test(int* state){
if(state[n * n - 1] != 0) return 0;
for(int i = 0 ; i < (n * n - 1) ; i++){
if(state[i] != i + 1)
return 0;
}
return 1;
}
vector<node> solution(node* v){
vector<node> ans;
while((v->parent)->hash != v->hash){
ans.push_back(*v);
v = v->parent;
}
return ans;
}
//first heuristic
int manhattanDistance(int* state){
int md = 0;
for(int i = 0 ; i < (n * n) ; i++){
if(state[i] == 0) continue;
//what is the goal row and column of this tile
int gr = (state[i] - 1) / n , gc = (state[i] - 1) % n;
//what is the row and column of this tile
int r = i / n , c = i % n;
md += (max(gr - r , r - gr) + max(gc - c , c - gc));
}
return md;
}
//second heuristic
int linearConflict(int* state){
int lc = 0;
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
//jth tile in ith row = (i * n + j)th in state
int la = i * n + j;
if(state[la] == 0 || (state[la] / n) != i)
continue;
for(int k = j + 1 ; k < n ; k++){
//kth tile in ith row = (i * n + k)th in state
int lb = i * n + k;
if(state[lb] == 0 || (state[lb] / n) != i)
continue;
if(state[la] > state[lb])
lc++;
}
}
}
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
//j the tile of i th column
int la = j * 4 + i;
if(state[la] == 0 || (state[la] % n) != i)
continue;
for(int k = j + 1 ; k < n ; k++){
int lb = k * 4 + i;
if(state[lb] == 0 || (state[lb] % n) != i)
continue;
if(state[la] > state[lb])
lc++;
}
}
}
return lc * 2;
}
long long make_hash(int* v){
long long power = 1LL;
long long hash = 0 * 1LL;
for(int i = 0 ; i < (n * n) ; i++){
hash += (power * v[i] * 1LL) % hash_mod;
hash %= hash_mod;
power = (hash_base * power * 1LL) % hash_mod;
}
return hash;
}
vector<node> successor(node* parent){
vector<node> child;
int parent_empty = parent->empty_cell;
//the row and column of empty cell
int r = parent_empty / n , c = parent_empty % n;
//empty cell go down
if(r + 1 < n){
struct node down;
for(int i = 0 ; i < (n*n) ; i++)
down.state[i] = parent->state[i];
down.state[parent_empty] = parent->state[parent_empty + n];
down.state[parent_empty + n] = 0;
down.hash = make_hash(down.state);
down.empty_cell = parent_empty + n;
down.cost = parent->cost + 1;
down.parent = parent;
//first heuristic -> manhattan Distance
// down.heuristic = manhattanDistance(down.state);
//second heuristic -> manhattan distance + linear conflict
down.heuristic = linearConflict(down.state) + manhattanDistance(down.state);
//third heuristic -> disjoint pattern database
// down.heuristic = DisjointPatternDB(down.state);
child.push_back(down);
}
//empty cell go up
if(r - 1 >= 0){
struct node up;
for(int i = 0 ; i < n * n ; i++)
up.state[i] = parent->state[i];
up.state[parent_empty] = parent->state[parent_empty - n];
up.state[parent_empty - n] = 0;
up.empty_cell = parent_empty - n;
up.hash = make_hash(up.state);
up.cost = parent->cost + 1;
up.parent = parent;
//first heuristic -> manhattan Distance
// up.heuristic = manhattanDistance(up.state);
//second heuristic -> manhattan distance + linear conflict
up.heuristic = linearConflict(up.state) + manhattanDistance(up.state);
//third heuristic -> disjoint pattern database
// up.heuristic = DisjointPatternDB(up.state);
child.push_back(up);
}
//empty cell going right
if(c + 1 < n){
struct node right;
for(int i = 0 ; i < (n * n) ; i++)
right.state[i] = parent->state[i];
right.state[parent_empty] = parent->state[parent_empty + 1];
right.state[parent_empty + 1] = 0;
right.empty_cell = parent_empty + 1;
right.hash = make_hash(right.state);
right.cost = parent->cost + 1;
right.parent = parent;
//first heuristic -> manhattan Distance
// right.heuristic = manhattanDistance(right.state);
//second heuristic -> manhattan distance + linear conflict
right.heuristic = linearConflict(right.state) + manhattanDistance(right.state);
//third heuristic -> disjoint pattern database
// right.heuristic = DisjointPatternDB(right.state);
child.push_back(right);
}
//empty cell going left
if(c - 1 >= 0){
struct node left;
for (int i = 0; i < (n * n) ; i++)
left.state[i] = parent->state[i];
left.state[parent_empty] = parent->state[parent_empty - 1];
left.state[parent_empty - 1] = 0;
left.empty_cell = parent_empty - 1;
left.hash = make_hash(left.state);
left.cost = parent->cost + 1;
left.parent = parent;
//first heuristic -> manhattan Distance
// left.heuristic = manhattanDistance(left.state);
//second heuristic -> manhattan distance + linear conflict
left.heuristic = linearConflict(left.state) + manhattanDistance(left.state);
//third heuristic -> disjoint pattern database
// left.heuristic = DisjointPatternDB(left.state);
child.push_back(left);
}
return child;
}
node* nodeCopy(node child){
node* tmp = new node;
for(int i = 0 ; i < n * n; i++)
tmp->state[i] = child.state[i];
tmp->hash = child.hash;
tmp->empty_cell = child.empty_cell;
tmp->cost = child.cost;
tmp->parent = child.parent;
tmp->heuristic = child.heuristic;
return tmp;
}
vector<node> Astar(node* initNode){
if(goal_test(initNode->state)) return solution(initNode);
frontier.insert(make_pair(initNode->cost + initNode-> heuristic ,initNode));
explored.insert(initNode->hash);
while(!frontier.empty()){
node* v = (*frontier.begin()).second;
if(goal_test(v->state)) return solution(v);
frontier.erase(frontier.begin());
vector<node> childs = successor(v);
for(node child: childs){
if(explored.find(child.hash) == explored.end()){
node* tmp = nodeCopy(child);
frontier.insert(make_pair((child.cost + child.heuristic) , tmp));
explored.insert(child.hash);
}
}
}
return solution(initNode);
}
int main(){
clock_t tStart = clock();
printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
struct node init;// {{1 , 2 , 3 , 4 , 5, 6, 7, 8, 0} , 1 , 9 , 0 , &init , 0};
for(int i = 0 ; i < (n * n) ; i++){
cin >> init.state[i];
if(init.state[i] == 0)
init.empty_cell = i;
}
init.hash = make_hash(init.state);
init.cost = 0;
init.parent = &init;
init.heuristic = manhattanDistance(init.state) ;//+ linearConflict(init.state);
vector <node> ans = Astar(&init);
//cout << 1 << " ";
for(int j = 0 ; j < n * n ; j++){
if(j == n * n - 1) cout << init.state[j];
else cout << init.state[j] << ",";
}
cout << endl;
for(int i = (ans.size() - 1) ; i >= 0 ; i--){
//cout << (ans.size() - i + 1) << " ";
cerr << linearConflict(ans[i].state) << endl;
for(int j = 0 ; j < n * n ; j++){
if(j == n * n - 1) cout << ans[i].state[j];
else cout << ans[i].state[j] << ",";
}
cout << endl;
}
cout << "path size : " << ans.size() << endl;
cout << "number of node expanded : " << explored.size() << endl;
printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}
#include <vector>
using namespace std;
struct node{
int state[16];
long long hash;
int empty_cell;
long cost;
node* parent;
int heuristic;
};
If its answer is not optimal it is because your heuristic is not admissible.
This means that sometimes it is overestimating the cost to reach a node in your graph.
linear conflicts heuristic should always be coupled with a distance estimated heuristic like Manhattan and it is not as simple as giving twice the number of linear conflicts in each row / column.
See Linear Conflict violating admissibility and driving me insane
and
https://cse.sc.edu/~mgv/csce580sp15/gradPres/HanssonMayerYung1992.pdf

Hourglass sum in 2D array

We are given a (6*6) 2D array of which we have to find largest sum of a hourglass in it.
For example, if we create an hourglass using the number 1 within an array full of zeros, it may look like this:
The sum of an hourglass is the sum of all the numbers within it. The sum for the hourglasses above are 7, 4, and 2, respectively.
I had written a code for it as follows.It is basically a competitive programming question and as I am new to the field,I have written the code with a very bad compplexity..perhaps so much that the program could not produce the desired output within the stipulated period of time.Below is my code:
int main(){
vector< vector<int> > arr(6,vector<int>(6));
for(int arr_i = 0;arr_i < 6;arr_i++)
{
for(int arr_j = 0;arr_j < 6;arr_j++)
{
cin >> arr[arr_i][arr_j];
}
} //numbers input
int temp; //temporary sum storing variable
int sum=INT_MIN; //largest sum storing variable
for(int i=0;i+2<6;i++) //check if at least3 exist at bottom
{
int c=0; //starting point of traversing column wise for row
while(c+2<6) //three columns exist ahead from index
{
int f=0; //test case variable
while(f!=1)
{ //if array does not meet requirements,no need of more execution
for(int j=c;j<=j+2;j++)
{ //1st and 3rd row middle element is 0 and 2nd row is non 0.
//condition for hourglass stucture
if((j-c)%2==0 && arr[i+1][j]==0||((j-c)%2==1 && arr[i+1][j]!=0)
//storing 3 dimensional subarray sum column wise
temp+=arr[i][j]+arr[i+1][j]+arr[i+2][j]; //sum storage
else
f=1; //end traversing further on failure
if(sum<temp)
sum=temp;
f=1;//exit condition
}//whiel loop of test variable
temp=0; //reset for next subarray execution
c++; /*begin traversal from one index greater column wise till
condition*/
}// while loop of c
}
}
cout<<sum;
return 0;
}
This is my implementation of the code which failed to process in the time interval.Please suggest a better solution considering the time complexity and feel free to point out any mistakes from my side in understanding the problem.The question is from Hackerrank.
Here is the link if you need it anyways:
https://www.hackerrank.com/challenges/2d-array
The solution for your problem is:
#include <cstdio>
#include <iostream>
#include <climits>
int main() {
int m[6][6];
// Read 2D Matrix-Array
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 6; ++j) {
std:: cin >> m[i][j];
}
}
// Compute the sum of hourglasses
long temp_sum = 0, MaxSum = LONG_MIN;
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 6; ++j) {
if (j + 2 < 6 && i + 2 < 6) {
temp_sum = m[i][j] + m[i][j + 1] + m[i][j + 2] + m[i + 1][j + 1] + m[i + 2][j] + m[i + 2][j + 1] + m[i + 2][j + 2];
if (temp_sum >= MaxSum) {
MaxSum = temp_sum;
}
}
}
}
fprintf(stderr, "Max Sum: %ld\n", MaxSum);
return 0;
}
The algorithm is simple, it sums all the Hourglasses starting of the upper left corner and the last 2 columns and 2 rows are not processed because it can not form hourglasses.
The above code is almost correct, but it does not work for a negative array elements.We should not take max sum as 0 as negative numbers array might not reach their max sum total >=0. In this case, initializing max sum to INT_MIN is a better option.
I have solved in Python 3.0 and passed all test cases in HackerRank:
Idea: in just 3 simple steps:
To extract all 16 3X3 in 6X6 matrix. Get each sub-matrix sum Find
the max of all sub-matrix sum
I have initialized max as -1000 for negative values you can also initialize it with Minimum_Integer value
# Complete the hourglassSum function below.
def hourglassSum(arr):
max = -1000
s= []
sub_array = []
for m in range(4)://Move vertically down the rows like(012,123,234,345 and taking 3 values horizontally)
for col in range(4):
for row in range(3):
sub_array.append(arr[row+m][col:col+3])
s = sub_array//Extracting all 16 3X3 matrices
hour_sum = sum_list(s[0])+s[1][1]+sum_list(s[2])//Mask array for hour_glass index[[1,1,1],[0,1,1],[1,1,1]]
if (max<hour_sum):
max = hour_sum
sub_array = []
return max
def sum_list(list1):
total = 0
for ele in range(0, len(list1)):
total = total + list1[ele]
return total
"""
Extra: Try replacing this in your Spyder for lesser lines of code
Instead of
Existing: without numpy
hour_sum = sum_list(s[0])+s[1][1]+sum_list(s[2])//Mask array for hour_glass index[[1,1,1],[0,1,1],[1,1,1]]
if (max<hour_sum):
max = hour_sum
With numpy:
import numpy as np
import numpy.ma as ma
hour_glass = ma.array(sub_array, mask=mask)
sum = hour_glass.data.sum()
"""
Swift 4 version:
func hourglassSum(arr matrix: [[Int]]) -> Int {
let h = matrix.count
if h < 3 {
return 0
}
let w = matrix[0].count
if w < 3 {
return 0
}
var maxSum: Int?
for i in 0 ..< h - 2 {
for j in 0 ..< w - 2 {
// Considering matrix[i][j] as top left cell of hour glass.
let sum = matrix[i][j] + matrix[i][j+1] + matrix[i][j+2]
+ matrix[i+1][j+1]
+ matrix[i+2][j] + matrix[i+2][j+1] + matrix[i+2][j+2]
// If previous sum is less then current sum then update new sum in maxSum
if let maxValue = maxSum {
maxSum = max(maxValue, sum)
} else {
maxSum = sum
}
}
}
return maxSum ?? 0
}
#JavaScript(Nodejs)
function hourglassSum(arr) {
// Write your code here
let count = -63;
for(let i = 0; i <= 3; i++){
for(let j = 0; j <= 3; j++){
let sum = arr[i][j] + arr[i][j+1] + arr[i][j+2] + arr[i+1][j+1]
+ arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]
if(sum > count){
count = sum
}
}
}
return count;
}
Here is python implementation of this algorithm.
arr = []
for _ in xrange(6):
arr.append(map(int, raw_input().rstrip().split()))
maxSum = -99999999
for row in range(len(arr)):
tempSum = 0
for col in range(len(arr[row])):
if col+2 >= len(arr[row]) or row+2 >= len(arr[col]):
continue
tempSum = arr[row][col] + arr[row][col+1] + arr[row][col+2] + arr[row+1][col+1] + arr[row+2][col] + arr[row+2][col+1] + arr[row+2][col+2]
if maxSum < tempSum:
maxSum = tempSum
print(maxSum)
Basic solution for java;
static int hourglassSum(int[][] arr) {
int sum = 0;
for(int i = 2; i<6; i++){
for(int j = 2; j<6; j++){
int up = arr[i-2][j-2] + arr[i-2][j-1] + arr[i-2][j];
int mid = arr[i-1][j-1];
int down = arr[i][j-2] + arr[i][j-1] + arr[i][j];
if(up+mid+down > sum){
sum = up+mid+down;
}
}
}
return sum;
}
Python clean and fast solution
def hourglassSum(arr):
arr_sum = -5000
tmp_sum = 0
for i in range(0, 6-2):
for j in range (0, 6-2):
tmp_sum = arr[i][j] + arr[i][j+1] + arr[i][j+2] + \
+ arr[i+1][j+1] + \
arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]
if arr_sum < tmp_sum:
arr_sum = tmp_sum
return arr_sum
Just avoided four for loop iterations
int main()
{
int arr[6][6],max=-1,sum;
for(int arr_i = 0; arr_i < 6; arr_i++){
for(int arr_j = 0; arr_j < 6; arr_j++){
scanf("%d",&arr[arr_i][arr_j]);
if(arr[arr_i][arr_j]<-9||arr[arr_i][arr_j]>9)
exit(0);
}
}
for(int arr_i = 0; arr_i <4; arr_i++)
{
sum=0;
for(int arr_j = 0; arr_j < 4; arr_j++){
sum=arr[arr_i][arr_j]+arr[arr_i][arr_j+1]+arr[arr_i][arr_j+2]+arr[arr_i+1][arr_j+1]+arr[arr_i+2][arr_j]+arr[arr_i+2][arr_j+1]+arr[arr_i+2][arr_j+2];
if(sum>max)
max=sum;
}
}
printf("%d",max);
return 0;
}
int main(){
vector< vector<int> > arr(6,vector<int>(6));
for(int arr_i = 0;arr_i < 6;arr_i++){
for(int arr_j = 0;arr_j < 6;arr_j++){
cin >> arr[arr_i][arr_j];
}
}
int sum=-100, temp;
for(int arr_i = 0;arr_i < 4;arr_i++){
for(int arr_j = 0;arr_j < 4;arr_j++){
temp=(arr[arr_i][arr_j]+arr[arr_i][arr_j+1]+arr[arr_i][arr_j+2]+arr[arr_i+1][arr_j+1]+arr[arr_i+2][arr_j]+arr[arr_i+2][arr_j+1]+arr[arr_i+2][arr_j+2]);
if(temp>sum)
sum=temp;
}
}
cout << sum;
return 0;
}
def hourglassSum(arr)
maxHourGlass = -82
counter = 0
for i in 1..4
for j in 1..4
acc = arr[i][j]
counter= counter +1
for x in -1..1
acc = acc + arr[i-1][j+x] + arr[i+1][j+x]
end
maxHourGlass = acc if acc > maxHourGlass
end
end
maxHourGlass
end
This is written in C++14 and passes all nine test cases. I think someone could improve it to use more C++14 features.
int hourglassSum(vector<vector<int>> arr)
{
if(arr.size() < 3 || arr[0].size() < 3 )
return -1;
int rowSize = arr[0].size();
int sum = -9 * 6; // smallest negative sum possible;
for( int i = 1; i < arr.size()-1; i++ )
{
int tmp_sum = 0;
for( int j = 1; j < rowSize-1; j++ )
{
tmp_sum = (arr[i - 1][j - 1] + arr[i - 1][j] + arr[i - 1][j + 1] );
tmp_sum += (arr[i ][j ]);
tmp_sum += (arr[i + 1][j - 1] + arr[i + 1][j] + arr[i + 1][j + 1]);
sum = max(tmp_sum, sum);
}
}
return sum;
}
class Solution {
static void Main(string[] args) {
int[][] arr = new int[6][];
for (int i = 0; i < 6; i++) {
arr[i] = Array.ConvertAll(Console.ReadLine().Split(' '), arrTemp => Convert.ToInt32(arrTemp));
}
int[] sum=new int[16];
int j;
int count=0;
for(int i=0; i<4; i++)
{
for(j=0;j<4;j++)
{
if(count<16)
{
sum[count]=arr[i][j]+arr[i][j+1]+arr[i][j+2]+arr[i+1][j+1]+arr[i+2][j]+arr[i+2][j+1]+arr[i+2][j+2];
count++;
}
}
}
int max=sum.Max();
Console.WriteLine(max);
}
}
Largest (maximum) hourglass sum found in the array will be -63 as the element cannot be greater than -9 i.e. -9*7 = -63
C#
int max_hourglass_sum = -63;
for (int i = 0; i <arr.Length-2; i++) { //row
for (int j = 0 ; j<arr.Length-2; j++) { //column
int current_hourglass_sum = arr[i][j] + arr[i][j+1] + arr[i][j+2] //1st row
+ arr[i+1][j+1] //2nd row
+ arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2] ;//3rd row
max_hourglass_sum = Math.Max(max_hourglass_sum , current_hourglass_sum);
}
}
static int hourglassSum(int[][] arr) {
int result = int.MinValue;
int rowLength = arr.GetLength(0);
int colLength = arr.Length;
for (int i = 0; i < rowLength - 2; i++)
{
for(int j=0; j< colLength - 2; j++)
{
int sum = 0;
sum = arr[i][j] + arr[i][j+1] + arr[i][j+2]+ arr[i+1][j+1]
+ arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2];
result = Math.Max(result,sum);
}
}
return result;
}
function hourglassSum(arr) {
const hourGlass = [];
for (let i = 0; i < 4; i++) {
for (let x = 0; x < 4; x++) {
let hourGlassSumValue = arr[i][x] + arr[i][x + 1] + arr[i][x + 2] + arr[i + 1][x + 1] + arr[i + 2]enter code here[x] + arr[i + 2][x + 1] + arr[i + 2][x + 2];
hourGlass.push(hourGlassSumValue);
}
}
return Math.max(...hourGlass);
}
console.log(hourglassSum(cars));

Gradient descent converging towards the wrong value

I'm trying to implement a gradient descent algorithm in C++. Here's the code I have so far :
#include <iostream>
double X[] {163,169,158,158,161,172,156,161,154,145};
double Y[] {52, 68, 49, 73, 71, 99, 50, 82, 56, 46 };
double m, p;
int n = sizeof(X)/sizeof(X[0]);
int main(void) {
double alpha = 0.00004; // 0.00007;
m = (Y[1] - Y[0]) / (X[1] - X[0]);
p = Y[0] - m * X[0];
for (int i = 1; i <= 8; i++) {
gradientStep(alpha);
}
return 0;
}
double Loss_function(void) {
double res = 0;
double tmp;
for (int i = 0; i < n; i++) {
tmp = Y[i] - m * X[i] - p;
res += tmp * tmp;
}
return res / 2.0 / (double)n;
}
void gradientStep(double alpha) {
double pg = 0, mg = 0;
for (int i = 0; i < n; i++) {
pg += Y[i] - m * X[i] - p;
mg += X[i] * (Y[i] - m * X[i] - p);
}
p += alpha * pg / n;
m += alpha * mg / n;
}
This code converges towards m = 2.79822, p = -382.666, and an error of 102.88. But if I use my calculator to find out the correct linear regression model, I find that the correct values of m and p should respectively be 1.601 and -191.1.
I also noticed that the algorithm won't converge for alpha > 0.00007, which seems quite low, and the value of p barely changes during the 8 iterations (or even after 2000 iterations).
What's wrong with my code?
Here's a good overview of the algorithm I'm trying to implement. The values of theta0 and theta1 are called p and m in my program.
Other implementation in python
More about the algorithm
This link gives a comprehensive view of the algorithm; it turns out I was following a completely wrong approach.
The following code does not work properly (and I have no plans to work on it further), but should put on track anyone who's confronted to the same problem as me :
#include <vector>
#include <iostream>
typedef std::vector<double> vect;
std::vector<double> y, omega(2, 0), omega2(2, 0);;
std::vector<std::vector<double>> X;
int n = 10;
int main(void) {
/* Initialize x so that each members contains (1, x_i) */
/* Initialize x so that each members contains y_i */
double alpha = 0.00001;
display();
for (int i = 1; i <= 8; i++) {
gradientStep(alpha);
display();
}
return 0;
}
double f_function(const std::vector<double> &x) {
double c;
for (unsigned int i = 0; i < omega.size(); i++) {
c += omega[i] * x[i];
}
return c;
}
void gradientStep(double alpha) {
for (int i = 0; i < n; i++) {
for (unsigned int j = 0; j < X[0].size(); j++) {
omega2[j] -= alpha/(double)n * (f_function(X[i]) - y[i]) * X[i][j];
}
}
omega = omega2;
}
void display(void) {
double res = 0, tmp = 0;
for (int i = 0; i < n; i++) {
tmp = y[i] - f_function(X[i]);
res += tmp * tmp; // Loss functionn
}
std::cout << "omega = ";
for (unsigned int i = 0; i < omega.size(); i++) {
std::cout << "[" << omega[i] << "] ";
}
std::cout << "\tError : " << res * .5/(double)n << std::endl;
}

MaxDoubleSliceSum Codility Algorithm

I stumbled upon this problem on Codility Lessons, here is the description:
A non-empty zero-indexed array A consisting of N integers is given.
A triplet (X, Y, Z), such that 0 ≤ X < Y < Z < N, is called a double slice.
The sum of double slice (X, Y, Z) is the total of A[X + 1] + A[X + 2] + ... + A[Y − 1] + A[Y + 1] + A[Y + 2] + ... + A[Z − 1].
For example, array A such that:
A[0] = 3
A[1] = 2
A[2] = 6
A[3] = -1
A[4] = 4
A[5] = 5
A[6] = -1
A[7] = 2
contains the following example double slices:
double slice (0, 3, 6), sum is 2 + 6 + 4 + 5 = 17,
double slice (0, 3, 7), sum is 2 + 6 + 4 + 5 − 1 = 16,
double slice (3, 4, 5), sum is 0.
The goal is to find the maximal sum of any double slice.
Write a function:
int solution(vector &A);
that, given a non-empty zero-indexed array A consisting of N integers, returns the maximal sum of any double slice.
For example, given:
A[0] = 3
A[1] = 2
A[2] = 6
A[3] = -1
A[4] = 4
A[5] = 5
A[6] = -1
A[7] = 2
the function should return 17, because no double slice of array A has a sum of greater than 17.
Assume that:
N is an integer within the range [3..100,000];
each element of array A is an integer within the range [−10,000..10,000].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting >the storage required for input arguments).
Elements of input arrays can be modified.
I have already read about the algorithm with counting MaxSum starting at index i and ending at index i, but I don't know why my approach sometimes gives bad results. The idea is to compute MaxSum ending at index i, ommiting the minimum value at range 0..i. And here is my code:
int solution(vector<int> &A) {
int n = A.size();
int end = 2;
int ret = 0;
int sum = 0;
int min = A[1];
while (end < n-1)
{
if (A[end] < min)
{
sum = max(0, sum + min);
ret = max(ret, sum);
min = A[end];
++end;
continue;
}
sum = max(0, sum + A[end]);
ret = max(ret, sum);
++end;
}
return ret;
}
I would be glad if you could help me point out the loophole!
My solution based on bidirectional Kadane's algorithm. More details on my blog here. Scores 100/100.
public int solution(int[] A) {
int N = A.length;
int[] K1 = new int[N];
int[] K2 = new int[N];
for(int i = 1; i < N-1; i++){
K1[i] = Math.max(K1[i-1] + A[i], 0);
}
for(int i = N-2; i > 0; i--){
K2[i] = Math.max(K2[i+1]+A[i], 0);
}
int max = 0;
for(int i = 1; i < N-1; i++){
max = Math.max(max, K1[i-1]+K2[i+1]);
}
return max;
}
Here is my code:
int get_max_sum(const vector<int>& a) {
int n = a.size();
vector<int> best_pref(n);
vector<int> best_suf(n);
//Compute the best sum among all x values assuming that y = i.
int min_pref = 0;
int cur_pref = 0;
for (int i = 1; i < n - 1; i++) {
best_pref[i] = max(0, cur_pref - min_pref);
cur_pref += a[i];
min_pref = min(min_pref, cur_pref);
}
//Compute the best sum among all z values assuming that y = i.
int min_suf = 0;
int cur_suf = 0;
for (int i = n - 2; i > 0; i--) {
best_suf[i] = max(0, cur_suf - min_suf);
cur_suf += a[i];
min_suf = min(min_suf, cur_suf);
}
//Check all y values(y = i) and return the answer.
int res = 0;
for (int i = 1; i < n - 1; i++)
res = max(res, best_pref[i] + best_suf[i]);
return res;
}
int get_max_sum_dummy(const vector<int>& a) {
//Try all possible values of x, y and z.
int res = 0;
int n = a.size();
for (int x = 0; x < n; x++)
for (int y = x + 1; y < n; y++)
for (int z = y + 1; z < n; z++) {
int cur = 0;
for (int i = x + 1; i < z; i++)
if (i != y)
cur += a[i];
res = max(res, cur);
}
return res;
}
bool test() {
//Generate a lot of small test cases and compare the output of
//a brute force and the actual solution.
bool ok = true;
for (int test = 0; test < 10000; test++) {
int size = rand() % 20 + 3;
vector<int> a(size);
for (int i = 0; i < size; i++)
a[i] = rand() % 20 - 10;
if (get_max_sum(a) != get_max_sum_dummy(a))
ok = false;
}
for (int test = 0; test < 10000; test++) {
int size = rand() % 20 + 3;
vector<int> a(size);
for (int i = 0; i < size; i++)
a[i] = rand() % 20;
if (get_max_sum(a) != get_max_sum_dummy(a))
ok = false;
}
return ok;
}
The actual solution is get_max_sum function(the other two are a brute force solution and a tester functions that generates a random array and compares the output of a brute force and actual solution, I used them for testing purposes only).
The idea behind my solution is to compute the maximum sum in a sub array that that starts somewhere before i and ends in i - 1, then do the same thing for suffices(best_pref[i] and best_suf[i], respectively). After that I just iterate over all i and return the best value of best_pref[i] + best_suf[i]. It works correctly because best_pref[y] finds the best x for a fixed y, best_suf[y] finds the best z for a fixed y and all possible values of y are checked.
def solution(A):
n = len(A)
K1 = [0] * n
K2 = [0] * n
for i in range(1,n-1,1):
K1[i] = max(K1[i-1] + A[i], 0)
for i in range(n-2,0,-1):
K2[i] = max(K2[i+1]+A[i], 0)
maximum = 0;
for i in range(1,n-1,1):
maximum = max(maximum, K1[i-1]+K2[i+1])
return maximum
def main():
A = [3,2,6,-1,4,5,-1,2]
print(solution(A))
if __name__ == '__main__': main()
Ruby 100%
def solution(a)
max_starting =(a.length - 2).downto(0).each.inject([[],0]) do |(acc,max), i|
[acc, acc[i]= [0, a[i] + max].max ]
end.first
max_ending =1.upto(a.length - 3).each.inject([[],0]) do |(acc,max), i|
[acc, acc[i]= [0, a[i] + max].max ]
end.first
max_ending.each_with_index.inject(0) do |acc, (el,i)|
[acc, el.to_i + max_starting[i+2].to_i].max
end
end

How to implement midpoint displacement

I'm trying to implement procedural generation in my game. I want to really grasp and understand all of the algorithms nessecary rather than simply copying/pasting existing code. In order to do this I've attempted to implement 1D midpoint displacement on my own. I've used the information here to write and guide my code. Below is my completed code, it doesn't throw an error but that results don't appear correct.
srand(time(NULL));
const int lineLength = 65;
float range = 1.0;
float displacedLine[lineLength];
for (int i = 0; i < lineLength; i++)
{
displacedLine[i] = 0.0;
}
for (int p = 0; p < 100; p++)
{
int segments = 1;
for (int i = 0; i < (lineLength / pow(2, 2)); i++)
{
int segs = segments;
for (int j = 0; j < segs; j++)
{
int x = floor(lineLength / segs);
int start = (j * x) + 1;
int end = start + x;
if (i == 0)
{
end--;
}
float lo = -range;
float hi = +range;
float change = lo + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (hi - lo)));
int center = ((end - start) / 2) + start;
displacedLine[center - 1] += change;
segments++;
}
range /= 2;
}
}
Where exactly have I made mistakes and how might I correct them?
I'm getting results like this:
But I was expecting results like this:
The answer is very simple and by the way I'm impressed you managed to debug all the potential off-by-one errors in your code. The following line is wrong:
displacedLine[center - 1] += change;
You correctly compute the center index and change amount but you missed that the change should be applied to the midpoint in terms of height. That is:
displacedLine[center - 1] = (displacedLine[start] + displacedLine[end]) / 2;
displacedLine[center - 1] += change;
I'm sure you get the idea.
The problem seems to be that you are changing only the midpoint of each line segment, rather than changing the rest of the line segment in proportion to its distance from each end to the midpoint. The following code appears to give you something more like what you're looking for:
#include <iostream>
#include <cstdlib>
#include <math.h>
#include <algorithm>
using namespace std;
void displaceMidPt (float dline[], int len, float disp) {
int midPt = len/2;
float fmidPt = float(midPt);
for (int i = 1; i <= midPt; i++) {
float ptDisp = disp * float(i)/fmidPt;
dline[i] += ptDisp;
dline[len-i] += ptDisp;
}
}
void displace (float displacedLine[], int lineLength, float range) {
for (int p = 0; p < 100; p++) {
int segs = pow(p, 2);
for (int j = 0; j < segs; j++) {
float lo = -range;
float hi = +range;
float change = lo + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (hi - lo)));
int start = int(float(j)/float(segs)*float(lineLength));
int end = int(float(j+1)/float(segs)*float(lineLength));
displaceMidPt (displacedLine+start,end-start,change);
}
range /= 2;
}
}
void plot1D (float x[], int len, int ht = 10) {
float minX = *min_element(x,x+len);
float maxX = *max_element(x,x+len);
int xi[len];
for (int i = 0; i < len; i++) {
xi[i] = int(ht*(x[i] - minX)/(maxX - minX) + 0.5);
}
char s[len+1];
s[len] = '\0';
for (int j = ht; j >= 0; j--) {
for (int i = 0; i < len; i++) {
if (xi[i] == j) {
s[i] = '*';
} else {
s[i] = ' ';
}
}
cout << s << endl;
}
}
int main () {
srand(time(NULL));
const int lineLength = 65;
float range = 1.0;
float displacedLine[lineLength];
for (int i = 0; i < lineLength; i++) {
displacedLine[i] = 0.0;
}
displace (displacedLine,lineLength,range);
plot1D (displacedLine,lineLength);
return 0;
}
When run this way, it produces the following result:
$ c++ -lm displace.cpp
$ ./a
*
* *
* ***
* * * *
* ** **** * **
* *** **** * * * ** *
* * ** ** *** * * * *
** ** *
* * * ***
** ***
*