|
Prev: Corresponding g77 options for ifort options
Next: Interfacing C routine with CVF routine called from VB
From: axtens on 23 Jan 2008 23:23 G'day everyone, I have a knapsack packing algorithm in C. I've got it working within itself okay. I have figured out how to get the data from VB to Fortran and from Fortran into C. What I can't seem to work out is how to get the data back from C to Fortran. It's probably something profoundly simple ... BTW, the change in argument order (p, w v/v w, p) is deliberate. The code: Fortran: subroutine KnapsackA43( n, p, w, solution, mass, optimal ) !dec$ attributes dllexport, stdcall, alias : "KnapsackA43" :: KnapsackA43 !dec$ attributes reference :: n, p, w, solution, mass, optimal INTEGER N REAL*8 P(N) REAL*8 W(N) REAL*8 SOLUTION(N) REAL*8 MASS REAL*8 OPTIMAL interface subroutine knapsack_A43 [C, Alias:'_knapsack_A43(a)32'] (n, w, p, solution, mass, optimal) ! dec$ attributes reference :: n, w, p, solution, mass, optimal INTEGER n REAL*8 w(n) REAL*8 p(n) REAL*8 solution(n) REAL*8 mass REAL*8 optimal end subroutine knapsack_A43 end interface call knapsack_A43( n, w, p, solution, mass, optimal ) return end subroutine KnapsackA43 C: /* ** knaps2.c */ /* ** September 26, 1997 ** this program implements Algorithm 4.3 ** for solving Problem 4.1 (0,1)-Knapsack ** with simple pruning. */ /* ** Compile with: ** gcc knaps2.c -o knaps2 ** ** Run with: ** knaps2 fname ** or ** knaps2 */ #include <stdlib.h> void __stdcall knapsack_A43( int, double*, double*, double*, double, double ); void Knapsack2( int, double ); double DotProd( int, double*, double* ); int igNodes; int igNumber; double * dgProfits; double * dgWeights; double * dgSolution; double dgCapacity; double dgOptimal; void __stdcall knapsack_A43( int iNumber, double *dWeights, double *dProfits, double *dSolution, double dCapacity, double dOptimal ) { igNodes = 0; igNumber = iNumber; dgProfits = dProfits; dgWeights = dWeights; dgSolution = dSolution; dgCapacity = dCapacity; Knapsack2( 0, 0.0 ); dOptimal = dgOptimal; //dWeights = dgWeights; //dProfits = dgProfits; //dSolution = dgSolution; return; } double DotProd( int n, double* A,double* B) { int i; double ans; ans=0.0; for( i=0; i < n;i++ ) { ans += ( A[ i ] * B[ i ] ); } return( ans ); } void Knapsack2( int ell, double curW ) /* ** Algorithm 4.3 */ { int i; igNodes = igNodes + 1; if ( ell == igNumber ) { if ( DotProd( igNumber, dgProfits, dgSolution ) > dgOptimal ) { dgOptimal = DotProd( igNumber, dgProfits, dgSolution ); for( i = 0; i < igNumber; i++ ) { dgSolution[ i ] = dgSolution[ i ]; } } } else { if( curW + dgWeights[ ell ] <= dgCapacity ) { dgSolution[ ell ] = 1.0; Knapsack2( ell + 1, curW + dgWeights[ ell ] ); } dgSolution[ ell ] = 0.0; Knapsack2( ell + 1, curW ); } } VB6 (more for completeness than anything else as I don't have any problems getting the data out of VB into Fortran): Declare Sub KnapsackA43 Lib "debug\boal0.dll" (n As Integer, p As Double, w As Double, x As Double, mass As Double, profit As Double) .... Dim i As Integer Dim mass As Double Dim profit As Double Const mass_limit As Double = 26# Dim p(4) As Double Dim w(4) As Double Dim x(4) As Double Const n As Integer = 4 p(0) = 24# p(1) = 13# p(2) = 23# p(3) = 15# p(4) = 16# w(0) = 12# w(1) = 7# w(2) = 11# w(3) = 8# w(4) = 9# Debug.Print " " Debug.Print " " Debug.Print "Object", "Profit", "Mass", "Profit Density", "Solution" Debug.Print " " For i = 0 To n Debug.Print i, p(i), w(i), p(i) / w(i), x(i) Next KnapsackA43 n, p(0), w(0), x(0), mass_limit, profit Debug.Print " " Debug.Print " " Debug.Print "Object", "Profit", "Weight", "Profit Density", "Solution" Debug.Print " " For i = 0 To n Debug.Print i, p(i), w(i), p(i) / w(i), x(i) Next Debug.Print " " Debug.Print " Mass Limit " & mass_limit Debug.Print " Profit " & profit Kind regards, Bruce. |