diff --git a/C++/src/maxNetProfit.cpp b/C++/src/maxNetProfit.cpp new file mode 100644 index 0000000..d2629dc --- /dev/null +++ b/C++/src/maxNetProfit.cpp @@ -0,0 +1,89 @@ +#include +using namespace std; +/* +Author: Jiankai Sun +Date: 2014.10.15 +*/ +/* +N jobs are to be scheduled for processing on one machine. Job i, 1 ≤ i ≤ N, +needs ti units of processing time. If job i is finished by time T, where T is a given +deadline, then a profit pi is earned; otherwise, a penalty qi +is imposed. (Both pi and qi are positive integers.) We want to select a subset S of jobs such that +(i) ∑i∈S ti ≤ T, and (ii) f(S) = ∑i∈S pi −∑i /∈S qi is maximum. +Show how to find such a set of jobs using dynamic programming. +*/ +int const N=3; +int const T=6; +//profit +int p[N]={12,3,4}; +//penalty +int q[N]={1,4,2}; +//time consuming +int t[N]={1,4,3}; +//net profit table +int f[N+1][T+1]; +//pointer to index which job should be scheduled +int P[N+1][T+1]; + +void findMaxNetProfit(){ + //non recursive implementation + for(int i=0;il){ + f[k][l]=f[k-1][l]-q[i]; + } + else{ + f[k][l]=max(f[k-1][l]-q[i],f[k-1][l-t[i]]+p[i]); + if(f[k][l]==f[k-1][l-t[i]]+p[i]){ + P[k][l]=1; + } + } + } + } + cout<<"net profit is "<deadline){ + return findMaxNetProfit_rec(job_n-1,deadline)-q[job_n-1]; + } + else{ + int a=findMaxNetProfit_rec(job_n-1,deadline)-q[job_n-1]; + int b=findMaxNetProfit_rec(job_n-1,deadline-t[job_n-1])+p[job_n-1]; + if(b>a) + P[job_n][deadline]=1; + return max(a,b); + } + +} +void printJobSet(){ + int l=T; + for(int i=N;i>=1;i--){ + if(P[i][l]==1){ + cout<<"job "< +using namespace std; +//find the largest j which makes f[j]<=s[i] +int find_opt(double [], double [],int); +//return the maximum sum of the selected intervals +//non recurssive version +double max_select_nonrec(double [],double [],int); +//recurssive version +double max_select_rec(double [],double [],int); +//void print selected intervals +void print_interval(int *,int); + +int find_opt(double s[],double f[],int i){ + for(int j=i-1;j>=0;j--){ + if(f[j]<=s[i]){ + return j; + } + } + return 0; +} + +double max_select_nonrec(double s[], double f[],int n){ + double * T=new double[n]; + int * P=new int[n]; + for(int i=0;i=T[i-1]){ + T[i]=temp; + P[i]=j; + } + else{ + T[i]=T[i-1]; + P[i]=-1; + } + + } + //print + print_interval(P,n); + return T[n-1]; +} +void print_interval(int * P, int n){ + int i=n-1; + while(P[i]!=0){ + if(P[i]>0){ + cout< +using namespace std; +/* +Author: Jiankai Sun +Date: 2014/10/14 +*/ +/* +Let A=a1a2...am and B=b1b2...bn be two strings of characers. we +want to transform A into B using following operations: +delete a character +and a character +change a character +write a dynamic programming algorithm that finds the minimum number +of operations needed to transform A into B +*/ +int min_ope(char * c1,const int m, char *c2,const int n){ + + int F[m+1][n+1];//define operation matrix + + //boundary condition + for(int i=0;i<=m;i++){ + F[i][0]=i; + } + for(int i=0;i<=n;i++){ + F[0][i]=i; + } + for(int i=0;iT(i-1)} + +T[i]=T(p(i))+$f_i$-$s_i$ + +P[i]=p(i) +\Else + +T[i]=T[i-1] + +P[i]=-1 + +\EndIf +\EndFor +\State Return T[n] +\end{algorithmic} +\end{algorithm} +\item we use $P[1,2,...,n]$ to print selected intervals + +\begin{algorithm}[H] +\caption{function printInterval() } +\begin{algorithmic}[1] +\State global $P[1,...,n]$ +\State i=n +\While{P[i] $\neq$ 0} +\If{P[i] $>$ 0} + +print i + + +i=P[i] + +\EndIf +\EndWhile + +\State print i + +\end{algorithmic} +\end{algorithm} +\item We use $O(nlog(n))$ to sort. For each $i$ we need $O(n)$ to scan all the interval list and repeat $n$ times, So the time complexity is $O(n^2)$ +\item source code: max\_selected\_intervals.cpp +\end{enumerate} +\begin{question}{2} +Let $A=a_1a_2...a_m$ and $B=b_1b_2...b_n$ be two strings of characers. we +want to transform $A$ into $B$ using following operations: + +delete a character + +add a character + +change a character + +write a dynamic programming algorithm that finds the minimum number of operations needed to transform $A $into $B$ +\end{question} +\begin{enumerate} +\item Let F[i,j] denotes the minimum number of operations needed to transform $a_1a_2...a_i$ to $b_1b_2...b_j$. +\item Recurrence relation + +$ +F[i,j]=or +\begin{cases} +F[i-1,j-1]; if a_i=b_j\\ +min +\begin{cases} +F[i-1,j-1]+1; change\\ +F[i,j-1]+1; add\\ +F[i-1,j]+1; delete\\ +\end{cases} +otherwise +\end{cases} +$ + +\item Boundary conditions + +$F[0,k]=k$ for k in [0,n] + +$F[k,0]=k$ for k in [0,m] + + \item implement the non recursive algorithm, see algorithm \ref{algminnum} + +\begin{algorithm}[H] +\caption{function MinNumOper() } +\label{algminnum} +\begin{algorithmic}[1] +\State global $F[1...m;1..n]$, A[1...m], B[1...n] +\State Initialize $F[0,k]=k$ for k in [0,n] and $F[k,0]=k$ for k in [0,m] + \For{i $\leftarrow$ 1 to m} + \For {j $\leftarrow$ 1 to n} + \If {A[i]==B[j]} F[i,j]=F[i-1,j-1] + \Else + + $ +F[i,j]=min +\begin{cases} +F[i-1,j-1]+1; change\\ +F[i,j-1]+1; add\\ +F[i-1,j]+1; delete\\ +\end{cases} +$ + \EndIf + \EndFor +\EndFor + \State return F[m,n] +\end{algorithmic} +\end{algorithm} +\item in the main function, we can call the function $MinNumOper()$ to to find the minimum number of operations needed to transform A into B +\item time complexity of this algorithm is $\Theta(mn)$ +\item source code: min\_operation\_dp.cpp +\end{enumerate} +%-------------------------------------------------------------- +% You don't have to mess with anything below this line. +% -------------------------------------------------------------- + +\end{document} \ No newline at end of file