I'm developing a neural network application, but I have a problem when I'm trying to print the output of the feedforward: the console shows this value:
The output is always 1 1 1 1 1
I'm using 3 layers consisting of 2500 input nodes, 1800 hidden nodes, and 5 output nodes.
I'm using sigmoid binary as the activation function, the weight for testing is fixed at 0.5.
When I'm trying to use a very simple architecture (2 input, 3 hidden, 1 output) it works perfectly, but right now with so many nodes I can't manually calculate the output so I don't know if the result is true or false.
Is my code wrong, or can't I give a fixed weight? I only want to do one feedforward, not back-propagation, and the input is random from 0 to 1.
This is network.cpp:
#include <stdio.h>
#include <iostream>
#include "network.h"
#include "neuron.h"
using namespace std;
layer::layer(int numberOfNeuron,int numberOfInput,int numberOfOutput):
neuron_layer(numberOfNeuron)
{
for(int i=0;i<numberOfNeuron;i++)
{
neuron_layer[i] = new neuron(numberOfInput,numberOfOutput);
}
}
layer::~layer()
{
}
int layer::get_number_of_neuron()
{
return neuron_layer.size();
}
network::network(int layerNumber,int hiddenNeuronNumber):
layer_network(layerNumber)
{
this->layer_numbers = layerNumber;
for(int i=0;i<layerNumber;i++)
{
if(i==0)
{
layer_network[i] = new layer(2500,5,hiddenNeuronNumber);
}
else if(i==1)
{
layer_network[i] = new layer(hiddenNeuronNumber,2500,5);
}
else if(i==2)
{
layer_network[i] = new layer(5,hiddenNeuronNumber,1);
}
}
cout<<endl<<"Input layer : "<<layer_network[0]->get_number_of_neuron()<<endl;
cout<<"Hidden layer : "<<layer_network[1]->get_number_of_neuron()<<endl;
cout<<"Output layer : "<<layer_network[2]->get_number_of_neuron()<<endl;
}
network::~network()
{
}
void network::init_input_layer(int inputNeuronNumber,int hiddenNeuronNumber)
{
for(int i=0;i<inputNeuronNumber;i++)
{
for(int j=0;j<hiddenNeuronNumber;j++)
{
layer_network[0]->neuron_layer[i]->outputs[j]->weights = 0.5f;
}
}
}
void network::init_hidden_layer(int inputNeuronNumber,int hiddenNeuronNumber,int outputNeuronNumber)
{
for(int i=0;i<hiddenNeuronNumber;i++)
{
for(int j=0;j<inputNeuronNumber;j++)
{
layer_network[1]->neuron_layer[i]->inputs[j]->weights = layer_network[0]->neuron_layer[j]->outputs[i]->weights;
}
}
for(int k=0;k<hiddenNeuronNumber;k++)
{
for(int l=0;l<outputNeuronNumber;l++)
{
layer_network[1]->neuron_layer[k]->outputs[l]->weights = 0.5f;
}
}
}
void network::init_ouput_layer(int hiddenNeuronNumber,int outputNeuronNumber)
{
for(int i=0;i<outputNeuronNumber;i++)
{
for(int j=0;j<hiddenNeuronNumber;j++)
{
layer_network[2]->neuron_layer[i]->inputs[j]->weights = layer_network[1]->neuron_layer[j]->inputs[i]->weights;
}
}
}
This is neuron.cpp:
#include "neuron.h"
#include <stdio.h>
#include <iostream>
using namespace std;
synapse::synapse()
{
}
synapse::~synapse()
{
}
neuron::neuron(int numberOfInput,int numberOfOutput):
inputs(numberOfInput),outputs(numberOfOutput)
{
for(int i=0;i<numberOfInput;i++)
{
inputs[i] = new synapse();
}
for(int i=0;i<numberOfOutput;i++)
{
outputs[i] = new synapse();
}
}
neuron::~neuron()
{
}
int neuron::get_input_size()
{
int input_length;
input_length=(int) inputs.size();
return input_length;
}
int neuron::get_output_size()
{
int output_length;
output_length=(int) outputs.size();
return output_length;
}
void neuron::input_fire()
{
output_value = inputs[0]->activation_values;
for(int i=0;i<get_output_size();i++)
{
outputs[i]->activation_values = output_value;
}
}
void neuron::fire()
{
output_value = 0.0f;
for(int i=0;i<get_input_size();i++)
{
output_value+=(inputs[i]->activation_values)*(inputs[i]->weights);
}
//cout<<endl<<"Before Sigmoid"<<output_value;
output_value = 1.0f / (1.0f+ exp(-output_value));
//cout<<" After Sigmoid"<<output_value;
for(int i=0;i<get_output_size();i++)
{
outputs[i]->activation_values = output_value;
}
}
I think I don't need to post neuron.h and network.h since both of them only consist of declarations. I define the functions in the .cpp. This is how I created the object:
srand (time(NULL));
float inputTest[2500];
network test(3,1800);
test.init_network(1800);
for(int i=0;i<2500;i++)
{
inputTest[i]=(float)rand()/(float)RAND_MAX;
}
test.feedforward(inputTest);
I didn't check your code but...
No, you can't use fixed weight like that. Each node in your hidden layer will get larger and larger values as you increase the amount of inputs. Sigmoid will scale the large values to 1.
Think about it:
Let's say that you have 100 inputs each having "random" input value of 0.1. For simplicity, let's just forget everything else. Since your weights are constant 0.5, all the nodes in the hidden layer will get a same value that consists of "sigmoided" sum of each input*weight, that is sigm(0.1*0.5*100) = sigm(5) -> ~1
So, the more you have positive inputs with constant positive weights the more close all the hidden layers' outputs will become to 1.
Related
I was trying to solve Reduce String on codechef which says
Give a string s of length l, and a set S of n sample string(s). We do reduce the string s using the set S by this way:
Wherever Si appears as a consecutive substring of the string s, you can delete (or not) it.
After each deletion, you will get a new string s by joining the part to the left and to the right of the deleted substring.
I wrote a recursive function as follows:-
Basically what i am doing in my code is either don't delete the character or delete it if it is part of any substring but it is giving wrong answer.
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
PS:
link to the question
This question is toughest(seen so far) and most beautiful(again seen so far) question based on DP ON INTERVALS.
The initial code would definitely not work since it only considers single pass on the string and would not consider remaining string after deleting the patterns again and again.
There are 3 cases:-
Case 1 Either character is not deleted.
Case 2It is deleted as a part of contiguous substring.
Case 3It is deleted as a part of subsequence that matches any word given in the set of patterns and everything that is not part of that subsequence is deleted first as a substring(which again belongs to set of words).
The third part is the most tricky and requires enough thinking and is even tougher to implement too.
So for every substring we need to check whether this substring can be completely destroyed or not.
The function compute_full_recur() is the function that ensures that whether substring can be deleted either in Case 2 or Case 3.
The function compute_full takes care of Case 1.And finally this code will not run on codechef link since all the function are recursive with memoization but to verify the code is working i Have run it on Problem Reducto of Hackerrank which is exact similar with lower constraints.Download test cases and then run on test cases on your PC for verifying.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define mx 252
#define nx 40
bool full[mx][mx],vis[mx][mx],full_recur[mx][mx][nx][nx];
int ans[mx];
void init()
{
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
full[i][j]=false,vis[i][j]=false;
}
}
for(int i=0;i<mx;i++)
{
ans[i]=-1;
}
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
for(int k=0;k<nx;k++)
{
for(int l=0;l<nx;l++)
{
full_recur[i][j][k][l]=false;
}
}
}
}
}
bool compute_full_recur(string str,int low,int high,vector<string> pat,int idx,int len)
{
if(low>high&&len==pat[idx].length())
{
return true;
}
if(low>high&&len<pat[idx].length())
{
full_recur[low][high][idx][len]=false;
return false;
}
if(str[low]==pat[idx][len]&&compute_full_recur(str,low+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
for(int i=low+1;i<=high;i++)
{
if(str[low]==pat[idx][len]&&full[low+1][i]&&compute_full_recur(str,i+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
}
full_recur[low][high][idx][len]=false;
return false;
}
void compute_full(string str,int low,int high,vector<string> pats)
{
if(low>high)
{
return;
}
if(vis[low][high])
{
return;
}
vis[low][high]=true;
compute_full(str,low+1,high,pats);
compute_full(str,low,high-1,pats);
for(int i=0;i<pats.size();i++)
{
if(!full[low][high])
full[low][high]=compute_full_recur(str,low,high,pats,i,0);
}
}
int compute_ans(string str,int low,int high)
{
if(low>high)
{
return 0;
}
if(ans[low]!=-1)
{
return ans[low];
}
int sol=1+compute_ans(str,low+1,high);
for(int i=low+1;i<=high;i++)
{
if(full[low][i]==true)
{
sol=min(sol,compute_ans(str,i+1,high));
}
}
return ans[low]=sol;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
vector<string> pats;
cin>>n>>str;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
pats.push_back(tem);
}
init();
compute_full(str,0,str.length()-1,pats);
cout<<compute_ans(str,0,str.length()-1)<<endl;
}
return 0;
}
I am passing in a sorted vector that contains a data as such:
Job Details {Start Time, Finish Time, Profit}
Job 1: {1 , 2 , 50 }
Job 2: {3 , 5 , 20 }
Job 3: {6 , 19 , 100 }
Job 4: {2 , 100 , 200 }
The code finds which jobs are the best for profit by checking all paths that don't overlap for example job 1,2,3 or job 1,4 are possible and it determines job 1,4 is the best value. I am trying to build a function that displays the path on how the code got to the best possible solution.
Ex. Job 1 --> Job 4 --> $250.
But am lost on the implementation.
Main.cpp
// Find the latest job (in sorted array) that doesn't
// conflict with the job[i]. If there is no compatible job,
// then it returns -1.
int latestNonConflict(vector<Task>someVector, int i)
{
for (int j = i - 1; j >= 0; j--)
{
if (someVector[j].getEndTime() <= someVector[i - 1].getStartTime())
{
return j;
}
}
return -1;
}
// A recursive function that returns the maximum possible
// profit from given array of jobs. The array of jobs must
// be sorted according to finish time.
int bruteForceMethod(vector<Task>someVector, int n)
{
// Base case
if (n == 1)
{
return someVector[n - 1].getValue();
}
// Find profit when current job is inclueded
int inclProf = someVector[n - 1].getValue();
int i = latestNonConflict(someVector, n);
if (i != -1)
cout << someVector[i].getLabel() << "-->";
inclProf += bruteForceMethod(someVector, i + 1);
// Find profit when current job is excluded
int exclProf = bruteForceMethod(someVector, n - 1);
return max(inclProf, exclProf);
}
// The main function that returns the maximum possible
// profit from given array of jobs
int findMaxProfit(vector<Task>someVector, int n)
{
return bruteForceMethod(someVector, n);
}
int main()
{
cout << "The optimal profit is " << bruteForceMethod(tasksVector,
tasksVector.size()) << endl;
return 0;
}
Task.h
#include <string>
using namespace std;
#ifndef Task_h
#define Task_h
class Task
{
public:
Task();
Task(string, int, int, int);
void setLabel(string);
string getLabel();
void setStartTime(int);
int getStartTime();
void setEndTime(int);
int getEndTime();
void setValue(int);
int getValue();
private:
string label;
int startTime;
int endTime;
int value;
};
#endif
Task.cpp
#include "Task.h"
Task::Task()
{
}
Task::Task(string inLabel, int inStartTime, int inEndTime, int inValue)
{
label = inLabel;
startTime = inStartTime;
endTime = inEndTime;
value = inValue;
}
void Task::setLabel(string inLabel)
{
label = inLabel;
}
string Task::getLabel()
{
return label;
}
void Task::setStartTime(int inStartTime)
{
startTime = inStartTime;
}
int Task::getStartTime()
{
return startTime;
}
void Task::setEndTime(int inEndTime)
{
endTime = inEndTime;
}
int Task::getEndTime()
{
return endTime;
}
void Task::setValue(int inValue)
{
value = inValue;
}
int Task::getValue()
{
return value;
}
You can simply consider a weighted graph G where
a node is a job
a node A is linked to a node B if A.endTime < B.startTime
weight of edge(A,B) is B.profit (taking the path to B means doing job B)
You want to get the path of maximal weight of G.
Usually algorithm want a function to minimize so instead lets take for weight -B.profit.
We can always cite the Floyd–Warshall algorithm , there is even the path reconstruction algorithm provided in link aforementionned.
Home made
But let's do it home-made since it seems to be some homework.
You can do it the bruteforce way (which is less efficient but easier to grasp than Floyd Warshall) and check all the longest paths...
create a root node to which you add for children all the jobs with their respective weight associated then consider the recursive function:
def get_longest_path(node):
if !node.children
return 0
best_all = {
w: weight(node, node.children[0]),
path: [node, get_longest_path(node.children[0])]
}
for node.children as child //starting from 1
best_path_i = get_longest_path(child)
//if we found a path with lower total weight (that is, with maximal profit)
if best_path_i != 0 && best_path_i.weight < best_all.weight
best_all = {
w: weight(node, child),
path:[node, best_path_i]
}
return best_all
get_longest_path(root)
note that you can trivially memoize get_longest_path (to avoid reevalution for an already visited node) without much burden
cache = {}
def get_longest_path(node):
if !node.children
return 0
//node.id is jobId
if node.id in cache
return cache[node.id]
best_all = {
w: weight(node,node.children[0]),
path: [node, get_longest_path(node.children[0])]
}
for node.children as child //starting from 1
best_path_i = get_longest_path(child)
//if we found a path with lower total weight (that is, with maximal profit)
if best_path_i != 0 && best_path_i.weight < best_all.weight
best_all = {
w: weight(node, child),
path:[node, best_path_i]
}
cache[node.id] = best_all
return best_all
get_longest_path(root)
No cycles handled but you don't have a job which reverses time I guess
This algorithm can be approached very similarly to a recursive permutation implementation of say a string ABC which produces ABC, ACB, BAC, BCA, CAB, CBA.
Here is a simple demonstration
You could modify this to "prune" the tree when a condition is not met (eg. the letter after is lower in the alphabet than the previous), so you would get ABC as it is the only one where every succesive letter is lower (A<B<C).
Once you have that, you now understand how to recurse over Task's and prune when comparing the startTime and endTime of jobs...
So here is an implementation of the above in C++:
#include <iostream>
#include <vector>
using namespace std;
struct Task {
// global counter tracking how many instances
static int counter;
int startTime;
int endTime;
int value;
int label;
Task(int inStartTime, int inEndTime, int inValue) {
startTime = inStartTime;
endTime = inEndTime;
value = inValue;
label = Task::counter++;
}
};
// store an index to each Task to keep track
int Task::counter = 1;
// build a search tree of all possible Task sequences
// pruning if next Task and current Task overlap
void jobSearchTree(vector<Task> jobSequence,
vector<Task> possibleJobs,
vector<vector<Task>> &possibleJobSequences) {
for (int i = 0; i < possibleJobs.size(); i++) {
vector<Task> l;
for (int j = 0; j < jobSequence.size(); j++)
{
l.push_back(jobSequence.at(j));
}
l.push_back(possibleJobs[i]);
// initial recursive call
if (!jobSequence.size()) {
vector<Task> searchJobs(possibleJobs);
searchJobs.erase(searchJobs.begin() + i);
jobSearchTree(l, searchJobs, possibleJobSequences);
}
// test if jobs occur sequentially
else if (l.at(l.size()-2).endTime <= l.at(l.size()-1).startTime) {
// add the Task sequence
possibleJobSequences.push_back(l);
vector<Task> searchJobs(possibleJobs);
// remove this Task from the search
searchJobs.erase(searchJobs.begin() + i);
// recursive call with Task sequence as the head
// and the remaining possible jobs as the tail
jobSearchTree(l, searchJobs, possibleJobSequences);
}
}
}
vector<int> getBestJobSequence(vector<vector<Task>> possibleJobSequences) {
int maxProfit = 0;
int totalProfit = 0;
vector<Task> bestJobSequence;
for (auto jobSequence : possibleJobSequences) {
totalProfit = 0;
for (auto Task : jobSequence) {
totalProfit += Task.value;
}
if (totalProfit > maxProfit) {
maxProfit = totalProfit;
bestJobSequence = jobSequence;
}
}
vector<int> jobIds;
for (auto Task : bestJobSequence) {
jobIds.push_back(Task.label);
}
return jobIds;
}
int main()
{
Task s1(1, 2, 50);
Task s2(3, 5, 20);
Task s3(6, 19, 100);
Task s4(2, 100, 200);
vector<Task> allJobs = {s1, s3, s4};
vector<vector<Task>> possibleJobSequences;
vector<Task> currentJobSequence;
jobSearchTree(currentJobSequence, allJobs, possibleJobSequences);
vector<int> bestJobSequence = getBestJobSequence(possibleJobSequences);
for (auto job : bestJobSequence) {
cout << job << endl;
}
return 0;
}
So my problem is the following: I want to program a basic game of life simulation. Therefore I am using std::vector to save the current state and calculate the next state. All put together in a while(). I am doing std::cout for every value, formated as a matrix. The problem is, that I only get one "matrix" as an output, instead of expected multiple.
I've also tried to output text after calculating the next state (so before and after the nextCells=currentCells), which didn't work, while outputting text within the calculating for() loop works.
I don't know what to do anymore. Appreciate any kind of help!
I've tried to output text after calculating the next state (so before and after the nextCells=currentCells), which didn't work, while outputting text within the calculating for() loop works.
#include <iostream>
#include <vector>
#include <unistd.h>
#define DIMX 10
#define DIMY 10
int countCells(std::vector<std::vector<int>> currentGrid, int x, int y);
int main() {
std::vector<std::vector<int>> currentCells(DIMX, std::vector<int>(DIMY));
std::vector<std::vector<int>> nextCells(DIMX, std::vector<int>(DIMY));
int count = 0;
nextCells = currentCells;
while(true) {
count++;
for(int i=0;i<=DIMX-1;i++) {
for(int j=0;j<=DIMY-1;j++) {
std::cout << currentCells[i][j];
std::cout.flush();
}
std::cout << "\n";
}
for(int i=0;i<=DIMX-1;i++) {
for(int j=0;j<=DIMY-1;j++) {
int aliveCells = countCells(currentCells, i, j);
if(currentCells[i][j]==0) {
if(aliveCells==3) {
nextCells[i][j]=1;
} else {
nextCells[i][j]=0;
}
} else {
if(aliveCells>3) {
nextCells[i][j]=0;
} else if(aliveCells<2) {
nextCells[i][j]=0;
} else {
nextCells[i][j]=1;
}
}
}
}
currentCells = nextCells;
if(count>=5) {
return 0;
}
}
}
int countCells(std::vector<std::vector<int>> currentGrid, int x, int y) {
int aliveCounter;
if(x==DIMX || x==0 || y==DIMY || y==0) {
return 0;
}
if(currentGrid[x-1][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x-1][y]==1) {
aliveCounter++;
} else if(currentGrid[x-1][y+1]==1) {
aliveCounter++;
} else if(currentGrid[x][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x][y+1]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y+1]==1) {
aliveCounter++;
}
return aliveCounter;
}
Your code produces an out of vector-range exception, For optimization reasons the exception may not throw in release mode.
When countCells gets called for y = 9 or x = 9
currentGrid[x+1][y+1]
is out of range.
Notice that
v = std::vector<int>(10,0) can be called from v[0] to v[9]; not v[10],
which would be out of range.
How do i swap the elements in a 2D int array according to use input? For example i have a 2x2 matrix with elements
int c[2][2]=
{
{1,2, },
{3,4, }
};
the user inputs which area to swap like: c[0][0] and c[0][1] then display the new results. Thanks
#include <stdio.h>
#include <stdlib.h>
void swap(int c[2][2],int &x1,int &y1,int &x2,int &y2)
{
int temp = c[x1][y1];
c[x1][y1] = c[x2][y2];
c[x2][y2] = temp;
}
int main(void)
{
int c[2][2]=
{
{1,2, },
{3,4, }
};
int x,y;
int x1,x2,x3,x4,x5,y1,y2,y3,y4,y5;
for(x=0;x<2;x++)
{
for(y=0;y<2;y++)
{
printf("\t%d",c[x][y]);
}
printf("\n");
}
printf("\nEnter 1st value to be swapped:\n");
printf("Row\n");
scanf("%d",&x3);
printf("Column\n");
scanf("%d",&y3);
printf("\nEnter 2nd value to be swapped:\n");
printf("Row\n");
scanf("%d",&x4);
printf("Column\n");
scanf("%d",&y4);
if((x3==1&&y3==1)&&(x4==1&&y4==2))
{
swap(c[0][0],c[0][1]);
}
for(x=0;x<2;x++)
{
for(y=0;y<2;y++)
{
printf("\t%d",c[x][y]);
}
printf("\n");
}
system("pause");
return ;
}
It looks like you just want to do this:
swap(c[x3-1][y3-1],c[x4-1][y4-1]);
But before you do that, you'll need to sanitise the variables to ensure they are within the range of the array.
I want to traverse a circular linked list (v1->v2->v3) in a given input order, lets say like
{v1,v3,v2,v2,v1,v3,v2,v1,v1,v3,v2,v2,v1,v2,v3}.
I wrote the below program as test for 3 nodes and would like to scale incrementally for 8, 64, 512, 4096, etc. nodes.
My idea of implementation requires the below program to run solely on an Abstract State Machine which only accepts the below functions as input for processing. I basically want to minimise the loop count of engine_spin_at_gear() while traversing. I may be on a non-blocking mode for using such an insane abstraction to mimic/virtualize process-execution as an engine-spin with unit of measurement as rpm, but I would really like suggestions on debugging the engine_spin_at_gear() function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MILES 15
struct package
{
// ... other members data ...
struct package *next;
}*v1, *v2, *v3;
int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3};
struct package *base(struct package *_vN)
{
if (_vN)
return _vN;
else
return NULL;
}
struct package *deliver(struct package *_vNP)
{
if (_vNP)
return base(_vNP->next);
else
return NULL;
}
void shift_gear(struct package *_feed)
{
_feed->next = NULL;
}
struct package *engine_spin_at_gear(struct package *_init_cycle0, int countSession)
{
while (countSession--) {
shift_gear(_init_cycle0);
return deliver(base(_init_cycle0));
}
return NULL;
}
struct package *journey(struct package *_current_frame, int _start, int _end)
{
int rpm = (_end > _start)?_end-_start:_start-_end;
if (rpm)
return engine_spin_at_gear(_current_frame, rpm);
else
return v1;
}
struct package *ignition_phase(int _batteryS, int _chargedL)
{
return journey(v1, _batteryS, _chargedL);
}
void transmit_in_order(int*input_arr)
{
struct package *v6;
int i;
for (i=0; i<MILES-1; i++) {
v6 = ignition_phase(input_arr[i], input_arr[i+1]);
printf("%p\n", v6);
}
}
int main()
{
v1 = malloc(sizeof(struct package));
v2 = malloc(sizeof(struct package));
v3 = malloc(sizeof(struct package));
v1->next = v2;
v2->next = v3;
v3->next = v1;
printf("v1=%p\tv2=%p\tv3=%p\n", v1, v2, v3);
transmit_in_order(input_arr);
return 0;
}
I am getting the following output when I ran my program's GCC executable on Linux.
v1=0x918b008 v2=0x918b018 v3=0x918b028
(nil)
(nil)
0x918b008
(nil)
(nil)
(nil)
(nil)
0x918b008
(nil)
(nil)
0x918b008
(nil)
(nil)
(nil)
(nil)
Or, do I need to change shift_gear() function? Can I optimise it more while keeping the scalability-factor intact? Thanks in advance. If I want to put all these functions in C++ as Class Engine and Class Gearbox, can you show me a prototype?
You mention scaling to larger number of items, here is some parts that scale to 100,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct package_s
{
// ... other members data ...
struct package_s* next;
} package; //being lazy, I avoid typing struct everywhere...
#define HOWMANY (100)
package* v[HOWMANY];
#define MILES 15
int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3};
package*
journey(package* _current_frame, int _start, int _end)
{
int rpm = (_end > _start) ? (_end-_start) : (_start-_end);
if (rpm)
return engine_spin_at_gear(_current_frame, rpm);
else
return v[0];
}
package*
ignition_phase(int _batteryS, int _chargedL)
{
return journey(v[0], _batteryS, _chargedL);
}
And this fixes the addressing off the end of input_arr (maybe you want to wrap back to zero?)
void
transmit_in_order(int*input_arr)
{
package *v6;
int i;
for (i=0; i<MILES-2; i++) {
v6 = ignition_phase(input_arr[i], input_arr[i+1]);
printf("%p\n", v6);
}
}
And the main for configurable number of v[n],
int main()
{
int ndx;
for(ndx=0; ndx<HOWMANY; ++ndx)
{
v[ndx] = malloc(sizeof(package));
}
for(ndx=0; ndx<HOWMANY; ++ndx)
{
v[ndx]->next = v[(ndx+1)%HOWMANY];
printf("v[%d]=%p\t", ndx, v[ndx]);
}
printf("\n", ndx, v[ndx]);
transmit_in_order(input_arr);
return 0;
}
Optimization aside, you have a problem with input_arr:
int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3}; //has 15 elements
While following loop requires 16:
for (i=0; i<MILES-1; i++) { //[edited] so i goes from 0 to 13
v6 = ignition_phase(input_arr[i], input_arr[i+1]); //otherwise, i goes to 14, +1 == 15 - 1 too big
printf("%p\n", v6);
}
Either create a bigger array, or stop the loop 1 increment earlier.
Regarding this code:
struct package *engine_spin_at_gear(struct package *_init_cycle0, int countSession)
{
while (countSession--) {
shift_gear(_init_cycle0); // }
return deliver(base(_init_cycle0));
}
return NULL;
} //move this one to after shift_gear(_init_cycle0);
Should the closing while loop } be moved to where indicated at comment? (per your's and Charlie's observation) If you keep the return statement in there , you will never make it past the first loop.
Output changes according to minor changes to code:
After changing for for (i=0; i<MILES; i++) { to for (i=0; i<MILES-1; i++) {
After changing
while (countSession--) {
shift_gear(_init_cycle0);
return deliver(base(_init_cycle0));
}
to:
while (countSession--) {
shift_gear(_init_cycle0);}
return deliver(base(_init_cycle0));
// }
So, it appears there is some effect, but I am not sure how to interpret this output. i.e. what significance these changes mean.