Backpropagation alhorithm: where did I make mistake? - backpropagation

There is my implementation of BP alhorithm. I tested it and found incorrect data after training. So, where did I make mistake?
double OpenNNL::_changeWeightsByBP(double * trainingInputs, double *trainingOutputs, double speed, double sample_weight)
{
double * localGradients = new double[_neuronsCount];
double * outputs = new double[_neuronsCount];
double * derivatives = new double[_neuronsCount];
calculateNeuronsOutputsAndDerivatives(trainingInputs, outputs, derivatives);
for(int j=0;j<_neuronsPerLayerCount[_layersCount-1];j++)
{
localGradients[indexByLayerAndNeuron(_layersCount-1, j)] = trainingOutputs[j] - outputs[indexByLayerAndNeuron(_layersCount-1, j)];
}
if(_layersCount > 1)
{
for(int i=_layersCount-2;i>=0;i--)
{
for(int j=0;j<_neuronsPerLayerCount[i];j++)
{
localGradients[indexByLayerAndNeuron(i, j)] = 0;
for(int k=0;k<_neuronsPerLayerCount[i+1];k++)
{
localGradients[indexByLayerAndNeuron(i, j)] += _neuronsInputsWeights[indexByLayerNeuronAndInput(i+1, k, j)]
* localGradients[indexByLayerAndNeuron(i+1, k)];
}
}
}
}
for(int j=0;j<_neuronsPerLayerCount[0];j++)
{
for(int k=0;k<_inputsCount;k++)
{
_neuronsInputsWeights[indexByLayerNeuronAndInput(0, j, k)] += speed * localGradients[indexByLayerAndNeuron(0, j)]
* derivatives[indexByLayerAndNeuron(0, j)] * trainingInputs[k];
}
}
for(int i=1;i<_layersCount;i++)
{
for(int j=0;j<_neuronsPerLayerCount[i];j++)
{
for(int k=0;k<_neuronsPerLayerCount[i-1];k++)
{
_neuronsInputsWeights[indexByLayerNeuronAndInput(i, j, k)] += speed * localGradients[indexByLayerAndNeuron(i, j)]
* derivatives[indexByLayerAndNeuron(i, j)] * outputs[indexByLayerAndNeuron(i, j)];
}
}
}
delete[] localGradients;
delete[] outputs;
delete[] derivatives;
}
And how to compute error of network's output for stopping training process?
And how to change neurons' biases?
There is my full code: https://github.com/NicholasShatokhin/OpenNNL if you need it.

I found problem. Instead of outputs[indexByLayerAndNeuron(i, j)] in last cycle I must write outputs[indexByLayerAndNeuron(i-1, k)].

Related

Simplex solver - issues with getting it working

I'm trying to write a simple simplex solver for linear optimization problems, but I'm having trouble getting it working. Every time I run it I get a vector subscript out of range (which is quite easy to find), but I think that its probably a core issue somewhere else in my impl.
Here is my simplex solver impl:
bool pivot(vector<vector<double>>& tableau, int row, int col) {
int n = tableau.size();
int m = tableau[0].size();
double pivot_element = tableau[row][col];
if (pivot_element == 0) return false;
for (int j = 0; j < m; j++) {
tableau[row][j] /= pivot_element;
}
for (int i = 0; i < n; i++) {
if (i != row) {
double ratio = tableau[i][col];
for (int j = 0; j < m; j++) {
tableau[i][j] -= ratio * tableau[row][j];
}
}
}
return true;
}
int simplex(vector<vector<double>>& tableau, vector<double>& basic, vector<double>& non_basic) {
int n = tableau.size() - 1;
int m = tableau[0].size() - 1;
while (true) {
int col = -1;
for (int j = 0; j < m; j++) {
if (tableau[n][j] > 0) {
col = j;
break;
}
}
if (col == -1) break;
int row = -1;
double min_ratio = numeric_limits<double>::infinity();
for (int i = 0; i < n; i++) {
if (tableau[i][col] > 0) {
double ratio = tableau[i][m] / tableau[i][col];
if (ratio < min_ratio) {
row = i;
min_ratio = ratio;
}
}
}
if (row == -1) return -1;
if (!pivot(tableau, row, col)) return -1;
double temp = basic[row];
basic[row] = non_basic[col];
non_basic[col] = temp;
}
return 1;
}

Finding number of pairs, product of whose indices is divisible by another number X

Given an array and some value X, find the number of pairs such that i < j , a[i] = a[j] and (i * j) % X == 0
Array size <= 10^5
I am thinking of this problem for a while but only could come up with the brute force solution(by checking all pairs) which will obviously time-out [O(N^2) time complexity]
Any better approach?
First of all, store separate search structures for each distinct A[i] as we iterate.
i * j = k * X
i = k * X / j
Let X / j be some fraction. Since i is an integer, k would be of the form m * least_common_multiple(X, j) / X, where m is natural.
Example 1: j = 20, X = 60:
lcm(60, 20) = 60
matching `i`s would be of the form:
(m * 60 / 60) * 60 / 20
=> m * q, where q = 3
Example 2: j = 6, X = 2:
lcm(2, 6) = 6
matching `i`s would be of the form:
(m * 6 / 2) * 2 / 6
=> m * q, where q = 1
Next, I would consider how to efficiently query the number of multiples of a number in a sorted list of arbitrary naturals. One way is to hash the frequency of divisors of each i we add to the search structure of A[i]. But first consider i as j and add to the result the count of divisors q that already exist in the hash map.
JavaScript code with brute force testing at the end:
function gcd(a, b){
return b ? gcd(b, a % b) : a;
}
function getQ(X, j){
return X / gcd(X, j);
}
function addDivisors(n, map){
let m = 1;
while (m*m <= n){
if (n % m == 0){
map[m] = -~map[m];
const l = n / m;
if (l != m)
map[l] = -~map[l];
}
m += 1;
}
}
function f(A, X){
const Ais = {};
let result = 0;
for (let j=1; j<A.length; j++){
if (A[j] == A[0])
result += 1;
// Search
if (Ais.hasOwnProperty(A[j])){
const q = getQ(X, j);
result += Ais[A[j]][q] || 0;
// Initialise this value's
// search structure
} else {
Ais[A[j]] = {};
}
// Add divisors for j
addDivisors(j, Ais[A[j]]);
}
return result;
}
function bruteForce(A, X){
let result = 0;
for (let j=1; j<A.length; j++){
for (let i=0; i<j; i++){
if (A[i] == A[j] && (i*j % X) == 0)
result += 1;
}
}
return result;
}
var numTests = 1000;
var n = 100;
var m = 50;
var x = 100;
for (let i=0; i<numTests; i++){
const A = [];
for (let j=0; j<n; j++)
A.push(Math.ceil(Math.random() * m));
const X = Math.ceil(Math.random() * x);
const _brute = bruteForce(A, X);
const _f = f(A, X);
if (_brute != _f){
console.log("Mismatch!");
console.log(X, JSON.stringify(A));
console.log(_brute, _f);
break;
}
}
console.log("Done testing.")
Just in case If someone needed the java version of this answer - https://stackoverflow.com/a/69690416/19325755 explanation has been provided in that answer.
I spent lot of time in understanding the javascript code so I thought the people who are comfortable with java can refer this for better understanding.
import java.util.HashMap;
public class ThisProblem {
public static void main(String[] args) {
int t = 1000;
int n = 100;
int m = 50;
int x = 100;
for(int i = 0; i<t; i++) {
int[] A = new int[n];
for(int j = 0; j<n; j++) {
A[j] = ((int)Math.random()*m)+1;
}
int X = ((int)Math.random()*x)+1;
int optR = createMaps(A, X);
int brute = bruteForce(A, X);
if(optR != brute) {
System.out.println("Wrong Answer");
break;
}
}
System.out.println("Test Completed");
}
public static int bruteForce(int[] A, int X) {
int result = 0;
int n = A.length;
for(int i = 1; i<n; i++) {
for(int j = 0; j<i; j++) {
if(A[i] == A[j] && (i*j)%X == 0)
result++;
}
}
return result;
}
public static int gcd(int a, int b) {
return b==0 ? a : gcd(b, a%b);
}
public static int getQ(int X, int j) {
return X/gcd(X, j);
}
public static void addDivisors(int n, HashMap<Integer, Integer> map) {
int m = 1;
while(m*m <= n) {
if(n%m == 0) {
map.put(m, map.getOrDefault(m, 0)+1);
int l = n/m;
if(l != m) {
map.put(l, map.getOrDefault(l, 0)+1);
}
}
m++;
}
}
public static int createMaps(int[] A, int X) {
int result = 0;
HashMap<Integer, HashMap<Integer, Integer>> contentsOfA = new HashMap<>();
int n = A.length;
for(int i = 1; i<n; i++) {
if(A[i] == A[0])
result++;
if(contentsOfA.containsKey(A[i])) {
int q = getQ(X, i);
result += contentsOfA.get(A[i]).getOrDefault(q, 0);
} else {
contentsOfA.put(A[i], new HashMap<>());
}
addDivisors(i, contentsOfA.get(A[i]));
}
return result;
}
}

Return a subset of integers that maximizes its (mean - median)

A set of integers is given as input. You have to return the subset of that set so that the mean - median is maximum for that subset.
Example 1
Input
{1,2,3,4}
Output
{1,2,4}
Example 2
Input
{1,2,2,3,3}
Output
{2,2,3}
package subsetMean_Median;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MySolution {
public static void main(String[] args) {
int[] arr=
{2,3,2,1,3};
// {1,3,2,4};
Arrays.sort(arr);
int[] outp=meanMedian(arr);
for(int e:outp) {
System.out.print(e+"\t");
}
}
protected static int[] meanMedian(int[] arr) {
double median=findMedian(arr);
double mean=findMean(arr);
double diff=median-mean;
int MAXINDEX=0;
int n=arr.length;
double sets=(1<<n);
System.out.println("sets:"+sets);
for(int i=1;i<=sets;i++) {
int[] subset=findSubset(i,arr);
mean=findMean(subset);
median=findMedian(subset);
if(mean -median>diff) {
diff=mean-median;MAXINDEX=i;
}
}
System.out.println("mean: "+mean+"\tmedian: "+median+"\tdiff: "+diff);
return findSubset(MAXINDEX,arr);
}
protected static int[] findSubset(int counter, int[] arr) {
int n=arr.length;
List<Integer> ls=new ArrayList<Integer>();
for(int j=0;j<n;j++) {
if((counter & (1<<j))>0) {
ls.add(arr[j]);
}
}
int[] output= new int[ls.size()];
for(int j=0;j<ls.size();j++) {
output[j]=ls.get(j);
}
return output;
}
protected static double findMean(int[] arr) {
int n=arr.length;
double sum=0;
if(n==0) return 0;
for(int i=0;i<n;i++)
sum +=arr[i];
return (sum/n);
}
protected static double findMedian(int[] arr) {
int n=arr.length;
if(n%2==1)
return arr[(n/2)];
else if(n>=2)
return 0.5*(arr[((n-2)/2)]+arr[n/2]);
else return 0;
}
}
For every possible median:
lllllmrrrrr
Sort both parts L and R, then start choosing in pair lr maximal elements from both parts and with addition of every next element recompute mean, store arrangement with the best difference. Then the same for minimal elements.
There are about N possible medians, sorting takes O(N*lgN), on every iteration you need to compute up to N means, you can do it in O(N). So, overall complexity is O(N^3*LgN), but most likely you can avoid sorting on every iteration, instead sort whole array only once and update parts in O(1) on every iteration. With such an improvements it is O(N^2).
The most important thing in this problem is to find the Subset.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MeanMedian {
public static void main(String[] args) {
int[] arr = { 1, 2, 3 };// { 1, 2, 2, 3, 3 };// { 1, 2, 3, 4 };
returnMaxMeanMedian(arr);
}
private static void returnMaxMeanMedian(int[] arr) {
double max = -999.9;
List<Integer[]> subArr = subSet(arr);
Integer[] maxArr = new Integer[1];
for (Integer[] sub : subArr) {
double newMax = calcDiff(sub);
if (max <= newMax) {
max = newMax;
maxArr = sub;
}
}
System.out.println(Arrays.toString(maxArr));
}
private static double calcDiff(Integer[] sub) {
// calc. mean
double sum = 0;
for (int i = 0; i < sub.length; i++) {
sum += sub[i];
}
sum = sum / sub.length;
// calc. median
double median = 0;
if (sub.length % 2 == 0)
median = (double) (sub[(sub.length / 2) - 1] + sub[sub.length / 2]) / 2;
else
median = sub[sub.length / 2];
double diff = sum - median;
return diff;
}
private static List<Integer[]> subSet(int[] arr) {
List<Integer[]> subArr = new ArrayList<Integer[]>();
int n = arr.length;
// Run a loop until 2^n
// subsets one by one
for (int i = 0; i < (1 << n); i++) {
String subSet = "";
// Print current subset
for (int j = 0; j < n; j++)
if ((i & (1 << j)) > 0)
subSet += arr[j] + " ";
subArr.add(convertToInt(subSet.trim().split(" ")));
}
return subArr;
}
private static Integer[] convertToInt(String[] arr) {
if (arr[0] == "")
return new Integer[] { 0 };
Integer[] intArr = new Integer[arr.length];
for (int i = 0; i < arr.length; i++) {
intArr[i] = Integer.parseInt(arr[i].trim());
}
return intArr;
}
}
Sort the list in O(n log n).
Deleting any element to the left of the median (center element or pair) has the same effect on the median, but affect the mean differently. Ditto for elements to the right.
That means that if anything will improve (mean - median), one of these will improve it the most:
the smallest element in the array
the smallest element to the right of the median
one of the element(s) that comprises the median
I.e., for each possible new median, how can we achieve the largest mean?
Repeatedly check these 3-4 for improving mean-median, deleting whatever improves the most. Each operation is O(1), as is recalculating the mean and median. You have to do this at most O(n) times.
The running time is O(n log n) if the list is unsorted, otherwise O(n).
Is this question only for a positive sequence of numbers? If yes, there's this efficient piece of code I wrote:
import java.util.Scanner;
public class MeanMedian {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int i;
int j;
int k;
int in_length;
int mid_loc;
int sum_arr;
float median = 0.0f;
float mean = 0.0f;
float delta = 0.0f;
float incremental_delta = 0.0f;
float MEDIAN_FOR_MAX_DELTA = 0.0f;
float MEAN_FOR_MAX_DELTA = 0.0f;
float MAX_DELTA = -1.0f;
int MAX_SEQ_LENGTH = 0;
System.out.print("Enter the length of input: ");
in_length = sc.nextInt();
int in_arr[]= new int [in_length+1];
int out_arr[] = new int [in_length+1]; //This is the maximum size of the output array.
int MAX_DELTA_ARR[] = new int [in_length+1];
// STAGE-1: Accept the input sequence
for (i = 1; i <= in_length; i++) {
System.out.print("Enter the input #" + i + ": ");
in_arr[i] = sc.nextInt();
}
// STAGE-1 completed.
// STAGE-2: Sort the array (Bubble sort in Ascending order)
for (j = 1; j < in_length; j++) {
for (i = in_length; i > j; i--) {
if (in_arr[i-1] > in_arr[i]) {
k = in_arr[i];
in_arr[i] = in_arr[i-1];
in_arr[i-1] = k;
}
}
}
// STAGE-2 completed.
// STAGE-3: Compute Max Delta
MAX_DELTA = -99999; //Store as large -ve number as float data type can hold.
for (i = in_length; i > 2; i--) {
// STAGE-3a: Optional - Clear the out_arr[]
for (j = 1; j <= in_length; j++) {
out_arr [j] = 0;
}
// STAGE-3a completed.
// STAGE-3b: Determine the index of the median for the sequence of length i
if (i % 2 == 1) {
mid_loc = (i + 1)/2;
}
else {
mid_loc = (i / 2) + 1;
}
// STAGE-3b completed.
// STAGE-3c: Create the selection that gives the min median and max mean.
// STAGE-3c1: Create left side of mid point.
for (j = mid_loc; j > 0; j--) {
out_arr[j] = in_arr[j];
}
// STAGE-3c1 completed.
// STAGE-3c2: Create right side of mid point.
k = in_length;
for (j = i; j > mid_loc; j--) {
out_arr[j] = in_arr[k];
k = k - 1;
}
// STAGE-3c2 completed.
// STAGE-3c3: Do the SHIFT TEST.
//for (; k <= mid_loc + in_length - i; k++) {
for (k = mid_loc + 1; k <= mid_loc + in_length - i; k++) {
if (i % 2 == 1) {
incremental_delta = ((float)in_arr[k] - (float)out_arr[1])/i - ((float)in_arr[k] - (float)out_arr[mid_loc]);
}
else {
incremental_delta = ((float)in_arr[k] - (float)out_arr[1])/i - (((float)in_arr[k] - (float)out_arr[mid_loc]/2));
}
if (incremental_delta >= 0 ) {
//Insert this new element
for(j = 1; j < mid_loc; j++) {
out_arr[j] = out_arr[j+1];
}
out_arr[mid_loc] = in_arr[k];
}
}
// STAGE-3c3 completed.
// STAGE-3d: Find the median of the present sequence.
if(i % 2 == 1) {
median = out_arr[mid_loc];
}
else {
median = ((float)out_arr[mid_loc] + (float)out_arr[mid_loc - 1])/2;
}
// STAGE-3d completed.
// STAGE-3e: Find the mean of the present sequence.
sum_arr = 0;
for(j=1; j <= i ; j++) {
sum_arr = sum_arr + out_arr[j];
}
mean = (float)sum_arr / i;
// STAGE-3e completed.
// STAGE-3f: Find the delta for the present sequence and compare with previous MAX_DELTA. Store the result.
delta = mean - median;
if(delta > MAX_DELTA) {
MAX_DELTA = delta;
MEAN_FOR_MAX_DELTA = mean;
MEDIAN_FOR_MAX_DELTA = median;
MAX_SEQ_LENGTH = i;
for (j = 1; j <= MAX_SEQ_LENGTH; j++) {
MAX_DELTA_ARR[j] = out_arr[j];
}
}
// STAGE-3f completed.
}
// STAGE-4: Print the result.
System.out.println("--- RESULT ---");
System.out.print("The given input sequence is: ");
System.out.print("{ ");
for(i=1; i <= in_length; i++) {
System.out.print(in_arr[i]);
System.out.print(" ");
}
System.out.print("}");
System.out.println("");
System.out.print("The sequence with maximum difference between mean and median is: ");
System.out.print("{ ");
for(i=1; i <= MAX_SEQ_LENGTH; i++) {
System.out.print(MAX_DELTA_ARR[i]);
System.out.print(" ");
}
System.out.print("}");
System.out.println("");
System.out.println("The mean for this sequence is: " + MEAN_FOR_MAX_DELTA);
System.out.println("The median for this sequence is: " + MEDIAN_FOR_MAX_DELTA);
System.out.println("The maximum difference between mean and median for this sequence is: " + MAX_DELTA);
}
}
This code has order O(n) (if we ignore the necessity to sort the input array).
In case, -ve inputs are also expected - the only way out is by evaluating each subset. The downside to this approach is that the algorithm has exponential order: O(2^n).
As a compromise you could use both types of algorithm in your code and switch between the two by evaluating the input sequence. By the way, where did you come across this question?
from itertools import combinations
[Verfication of the code][1]
# function to generate all subsets possible, there will be 2^n - 1 subsets(combinations)
def subsets(arr):
temp = []
for i in range(1, len(arr)+1):
comb = combinations(arr, i)
for j in comb:
temp.append(j)
return temp
# function to calculate median
def median(arr):
mid = len(arr)//2
if(len(arr)%2==0):
median = (arr[mid] + arr[mid-1])/2
else:`
median = arr[mid]
return median
# function to calculate median
def mean(arr):
temp = 0
for i in arr:
temp = temp + i
return temp/len(arr)
# function to solve given problem
def meanMedian(arr):
sets = subsets(arr)
max_value = 0
for i in sets:
mean_median = mean(i)-median(i)
if(mean_median>max_value):
max_value = mean_median
needed_set = i
return needed_set
[1]: https://i.stack.imgur.com/Mx4pc.png
So I tried a little on the problem and here is a code that might help you. Its written in a way that should be easy to read, and if not, do let me know. Maybe you need to take array input from the user as I have taken a fixed array. That shouldn't be much of a problem I am sure.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class MeanMinusMedian
{
private static float mean = 0;
private static float median = 0;
private static float meanMinusMedian = 0;
private static List<Integer> meanMinusMedianList = null;
private static void formMeanMinusMedianArr(int data[], int sumOfData)
{
findMean(data, sumOfData);
findMedian(data);
if ((mean - median) > meanMinusMedian) {
meanMinusMedian = mean - median;
meanMinusMedianList = new ArrayList<Integer>();
Arrays.stream(data)
.forEach(e->meanMinusMedianList.add(e));
}
}
/**
* #param data
*/
private static void findMedian(int[] data) {
int dataLen = data.length;
median = data.length % 2 == 0 ? ((float)data[dataLen / 2] + (float)data[dataLen / 2 - 1]) / 2 : data[dataLen / 2];
}
/**
* #param data
* #param sumOfData
*/
private static void findMean(int[] data, int sumOfData) {
mean = ((float)sumOfData /(float) data.length);
}
/**
*
* #param arr
* #param data
* #param start
* #param end
* #param index
* #param runningVal
*/
private static void combinationUtil(int arr[], int data[], int start, int end, int index, int runningVal) {
// Current combination is ready to be printed, print it
if (index == runningVal) {
formMeanMinusMedianArr(data, Arrays.stream(data) // Step 1
.sum());
return;
}
// replace index with all possible elements. The condition
// "end-i+1 >= r-index" makes sure that including one element
// at index will make a combination with remaining elements
// at remaining positions
for (int i = start; i <= end && end - i + 1 >= runningVal - index; i++) {
data[index] = arr[i];
combinationUtil(arr, data, i + 1, end, index + 1, runningVal);
}
}
/**
*
* #param arr
* #param n
* #param runningVal
*/
private static void printCombination(int arr[], int n, int runningVal) {
int data[] = new int[runningVal];
// Print all combination using temporary array 'data[]'
combinationUtil(arr, data, 0, n - 1, 0, runningVal);
}
public static void main(String[] args) {
int arr[] = { 1, 2, 2, 3, 3 };
int runningVal = 1;//Running value
int len = arr.length;
for (int i = 1; i < arr.length; i++) {
printCombination(arr, len, runningVal + i);
}
System.out.println(meanMinusMedianList);
}
}
Taking reference of answer of Bhaskar13 https://stackoverflow.com/a/59386801/3509609 , I solved it without using the bit shift operators, to add more readability.
package array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class MeanMinusMedianMax {
public static void main(String[] args) {
System.out.println(Arrays.toString(maxDiffrenceSubSet(4, new int[] { 4, 2, 3, 1 })));
System.out.println(Arrays.toString(maxDiffrenceSubSet(4, new int[] { 1, 2, 2, 3, 3 })));
}
public static int[] maxDiffrenceSubSet(int n, int[] input2) {
int totalSubsets = (int) Math.pow(2, n);
Map<Integer, ArrayList<Integer>> subsetsMap = new HashMap<Integer, ArrayList<Integer>>();
Integer maxKey = null;
double maxDiff = 0;
for (int i = 0; i < totalSubsets; i++) {
String binaryString = Integer.toBinaryString(i);
while (binaryString.length() < 4) {
binaryString = "0" + binaryString;
}
char[] currentPick = binaryString.toCharArray();
ArrayList<Integer> currentList = new ArrayList<Integer>();
for (int x = 0; x < currentPick.length; x++) {
if ((currentPick[x]) == '1') {
currentList.add(input2[x]);
}
}
Collections.sort(currentList);
subsetsMap.put(i, currentList);
double mean = findMean(currentList);
double median = findMedian(currentList);
double currentDifference = mean - median;
if (currentDifference > maxDiff) {
maxDiff = currentDifference;
maxKey = i;
}
}
return subsetsMap.get(maxKey).stream().mapToInt(i -> i).toArray();
}
static double findMean(ArrayList<Integer> arr) {
int n = arr.size();
double sum = 0;
if (n == 0)
return 0;
for (int i = 0; i < n; i++)
sum += arr.get(i);
return (sum / n);
}
static double findMedian(ArrayList<Integer> arr) {
int n = arr.size();
if (n % 2 == 1)
return arr.get((n / 2));
else if (n >= 2)
return 0.5 * (arr.get(((n - 2) / 2)) + arr.get(n / 2));
else
return 0;
}
}
class UserMainCode (object):
def meanmedian(cls,ip1,ip2=[]):
s = []
s = ip2
lst = []
final = []
op = []
max_val = 0
diff = 0
for i in range(1,ip1+1):
n=i
lst = list(itertools.combinations(s,n))
final = final +lst
for i in range(len(final)):
men = statistics.mean(final[i])
med = statistics.median(final[i])
diff = men - med
if max_val < diff:
op = final[i]
max_val = diff
return op

Invalid accelerator data region: branching into or out of region is not allowed?

pgcc is showing "Invalid accelerator data region: branching into or out of region is not allowed" for the lines that I put my acc pragmas, but I don't understand why.
I'm using copy, copyin, and create for all arrays that the loops would utilize.
What am I missing? Thanks!
#pragma acc data copy(graph->pagerank), copyin(graph->indegree, graph->outdegree), create(pagerankNew)
while (1) {
#pragma acc kernels
{
for (i = 0; i < n; ++i) {
double sum = 0;
for (k = 0; k < graph->indegree[i]; ++k) {
//int j = graph->inlinks[i][k];
int j = 0;
sum += (1.0 / graph->outdegree[j]) * graph->pagerank[j];
}
pagerankNew[i] = firstterm + damping * sum;
double diff = fabs(graph->pagerank[i] - pagerankNew[i]);
// if(iterations > 50) {
if (diff != 0.000000 && diff < epsilon) {
return iterations;
}
}
for (k = 0; k < n; ++k) {
graph->pagerank[k] = pagerankNew[k];
}
}
++iterations;
}

Knapsack 0-1 path reconstruction (which items to take) [duplicate]

This question already has answers here:
How to find which elements are in the bag, using Knapsack Algorithm [and not only the bag's value]?
(4 answers)
Closed 2 years ago.
I know how to solve knapsack 0-1 problem with dynamic programming approach, but I am having troubles figuring out which items to take without compromising the complexity of O(N * C) (N items, C capacity).
Any ideas (I would prefer a bottom-up approach)?
Suppose, right now you're storing results in array bool[] a, where a[i] is true when sum i can be achieved.
You'll need another array int[] b, where b[i] is a last element you've placed into knapsack to achieve sum i.
So, where you had
a[i] = true;
you'll need
a[i] = true;
b[i] = current_item;
Then, finding which items can be taken to achieve sum i is a simple loop.
PS I use two arrays for simplicity, but obviously array a can be removed.
Here is a modification to reconstruct path in O(n) times
int knapsack(int weight[], int profit[], int no_of_items, int capacity) {
for (int var = 0; var <= capacity; ++var) {
dp[0][var] = 0;
}
for (int var = 0; var <= no_of_items; ++var) {
path[var] = false;
}
int using_item_i, without_using_item_i;
for (int i = 1; i <= no_of_items; ++i) {
for (int j = 1; j <= capacity; ++j) {
without_using_item_i = dp[i - 1][j];
using_item_i = 0;
if ((weight[i]) <= j) {
using_item_i = dp[i - 1][j - weight[i]] + profit[i];
}
if (using_item_i >= without_using_item_i) {
taken[i][j] = true;
dp[i][j] = using_item_i;
} else {
taken[i][j] = false;
dp[i][j] = without_using_item_i;
}
}
}
//Reconstructing back the path
int j = capacity;
for (int i = no_of_items; i >= 0; --i) {
if (taken[i][j]) {
path[i] = true;
cnt++;
}
j = j - weight[i];
}
return dp[no_of_items][capacity];
}
boolean[] solution = new boolean[nItems];
for (int i = nItems, c = maxCapacity; i > 0 && c > 0; i--) {
int iThItemAddedValue = value[i - 1][c - weights[i - 1]] + values[i - 1];
int iThItemInheritedValue = value[i - 1][c];
if (iThItemAddedValue > iThItemInheritedValue) {
solution[i - 1] = true;
c = c - weights[i - 1];
} else {
solution[i - 1] = false;
}
}
Check the sol in the attached image
public class Knapsackproblem {
private static int[][] cache;
public static void main(String[] args) {
int val[] = new int[]{60, 100, 120};
int wt[] = new int[]{10, 20, 30};
int W = 50;
int n = val.length;
System.out.println(knapSack(W, wt, val, n));
printValues(wt,val);
}
/**
* This method will find the result with
* more value with weight less than or equal
* to given weight
* #param w given weight
* #param wt arrays of weights
* #param val array of values
* #param n length of the array
* #return max value we can obtain
*/
private static int knapSack(int w, int[] wt, int[] val, int n) {
cache = new int[n+1][w+1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= w; j++) {
if(j < wt[i-1]){
cache[i][j] = cache[i-1][j];
}else {
cache[i][j] = Math.max(cache[i-1][j],(cache[i-1][j-wt[i-1]])+val[i-1]);
}
}
}
for (int[] aCache : cache) {
System.out.println(Arrays.toString(aCache));
}
return cache[n][w];
}
private static void printValues(int[] wt, int[] val) {
int m = cache.length-1;
int n = cache[0].length-1;
util(wt,val,m,n);
}
private static void util(int[] wt, int[] val, int m, int n) {
if(m <=0 || n<=0) return;
if((cache[m][n] != cache[m-1][n]) && (cache[m][n] != cache[m][n-1])){
System.out.println(val[m-1]+"-->"+wt[m-1]);
util(wt, val, m-1, (n - wt[m - 1] + 1));
}else
if(cache[m][n] == cache[m-1][n]){
util(wt,val,m-1,n);
}
else if(cache[m][n] == cache[m][n-1])
util(wt,val,m,n-1);
else
util(wt,val,m,(n-val[m-1]+1));
}
}
https://www.dropbox.com/s/ish7t5vgy91fovt/Screenshot%202017-01-01%2015.16.31.png?dl=0
Print the tmpList in the caller and you will get the answer

Resources