mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
Implement GSCSTableau, GSCSEditInfo, GSCSEditVariableManager (#186)
* Implement GSCSTableau, GSCSEditInfo, GSCSEditVariableManager * Update GSTableau based on feedback * Remove adding expression term variable to external parameteric variables
This commit is contained in:
parent
eb480b7748
commit
305bcd56a3
10 changed files with 1187 additions and 8 deletions
|
@ -365,7 +365,10 @@ GSCSVariable.m \
|
|||
GSCSSolution.m \
|
||||
GSCSFloatComparator.m \
|
||||
GSCSLinearExpression.m \
|
||||
GSCSStrength.m
|
||||
GSCSStrength.m \
|
||||
GSCSEditInfo.m \
|
||||
GSCSEditVariableManager.m \
|
||||
GSCSTableau.m
|
||||
|
||||
# Turn off NSMenuItem warning that NSMenuItem conforms to <NSObject>,
|
||||
# but does not implement <NSObject>'s methods itself (it inherits
|
||||
|
@ -690,7 +693,10 @@ GSCSFloatComparator.h \
|
|||
GSCSSolution.h \
|
||||
GSCSLinearExpression.h \
|
||||
GSCSConstraintOperator.h \
|
||||
GSCSStrength.h
|
||||
GSCSStrength.h \
|
||||
GSCSEditVariableManager.h \
|
||||
GSCSEditInfo.h \
|
||||
GSCSTableau.h
|
||||
|
||||
libgnustep-gui_HEADER_FILES = ${GUI_HEADERS}
|
||||
|
||||
|
|
59
Source/GSCSEditInfo.h
Normal file
59
Source/GSCSEditInfo.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 12-6-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSConstraint.h"
|
||||
#import "GSCSVariable.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef _GS_CS_EDIT_INFO_H
|
||||
#define _GS_CS_EDIT_INFO_H
|
||||
|
||||
@interface GSCSEditInfo : NSObject
|
||||
{
|
||||
GSCSConstraint *_constraint;
|
||||
GSCSVariable *_variable;
|
||||
GSCSVariable *_plusVariable;
|
||||
GSCSVariable *_minusVariable;
|
||||
NSInteger _previousConstant;
|
||||
}
|
||||
|
||||
#if GS_HAS_DECLARED_PROPERTIES
|
||||
@property (nonatomic, readonly) GSCSConstraint *constraint;
|
||||
#else
|
||||
- (GSCSConstraint *) constraint;
|
||||
#endif
|
||||
|
||||
#if GS_HAS_DECLARED_PROPERTIES
|
||||
@property (nonatomic, readonly) GSCSVariable *variable;
|
||||
#else
|
||||
- (GSCSVariable *) variable;
|
||||
#endif
|
||||
|
||||
- (instancetype) initWithVariable: (GSCSVariable *)variable
|
||||
constraint: (GSCSConstraint *)constraint
|
||||
plusVariable: (GSCSVariable *)plusVariable
|
||||
minusVariable: (GSCSVariable *)minusVariable
|
||||
previousConstant: (NSInteger)previousConstant;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
66
Source/GSCSEditInfo.m
Normal file
66
Source/GSCSEditInfo.m
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 12-6-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSEditInfo.h"
|
||||
|
||||
@implementation GSCSEditInfo
|
||||
|
||||
- (instancetype) initWithVariable: (GSCSVariable *)variable
|
||||
constraint: (GSCSConstraint *)constraint
|
||||
plusVariable: (GSCSVariable *)plusVariable
|
||||
minusVariable: (GSCSVariable *)minusVariable
|
||||
previousConstant: (NSInteger)previousConstant
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
_variable = variable;
|
||||
_plusVariable = plusVariable;
|
||||
_minusVariable = minusVariable;
|
||||
_constraint = constraint;
|
||||
_previousConstant = previousConstant;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (GSCSConstraint*) constraint
|
||||
{
|
||||
return _constraint;
|
||||
}
|
||||
|
||||
- (GSCSVariable*) variable
|
||||
{
|
||||
return _variable;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_variable);
|
||||
RELEASE(_plusVariable);
|
||||
RELEASE(_minusVariable);
|
||||
RELEASE(_constraint);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
60
Source/GSCSEditVariableManager.h
Normal file
60
Source/GSCSEditVariableManager.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 12-6-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSEditInfo.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef _GS_CS_EDIT_VARIABLE_MANAGER_H
|
||||
#define _GS_CS_EDIT_VARIABLE_MANAGER_H
|
||||
|
||||
@interface GSCSEditVariableManager : NSObject
|
||||
{
|
||||
NSMutableArray *_editVariablesList;
|
||||
NSMutableArray *_editVariablesStack;
|
||||
NSMapTable *_editVariablesMap;
|
||||
}
|
||||
|
||||
- (NSArray *) editInfos;
|
||||
|
||||
- (BOOL) isEmpty;
|
||||
|
||||
- (void) addEditInfo: (GSCSEditInfo *)editInfo;
|
||||
|
||||
- (void) removeEditInfo: (GSCSEditInfo *)editInfo;
|
||||
|
||||
- (GSCSEditInfo *) editInfoForConstraint: (GSCSConstraint *)constraint;
|
||||
|
||||
- (NSArray *) editInfosForVariable: (GSCSVariable *)editVariable;
|
||||
|
||||
- (void) removeEditInfoForConstraint: (GSCSConstraint *)constraint;
|
||||
|
||||
- (void) pushEditVariableCount;
|
||||
|
||||
- (NSInteger) topEditVariableStack;
|
||||
|
||||
- (NSInteger) editVariableStackCount;
|
||||
|
||||
- (NSArray *) getNextSet;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
141
Source/GSCSEditVariableManager.m
Normal file
141
Source/GSCSEditVariableManager.m
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 12-6-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSEditVariableManager.h"
|
||||
#import "GSFastEnumeration.h"
|
||||
|
||||
@implementation GSCSEditVariableManager
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
ASSIGN(_editVariablesList, [NSMutableArray array]);
|
||||
ASSIGN(_editVariablesStack, [NSMutableArray array]);
|
||||
ASSIGN(_editVariablesMap,
|
||||
[NSMapTable mapTableWithKeyOptions: NSMapTableStrongMemory
|
||||
valueOptions: NSMapTableStrongMemory]);
|
||||
[self pushEditVariableCount];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isEmpty
|
||||
{
|
||||
return [_editVariablesList count] == 0;
|
||||
}
|
||||
|
||||
- (NSArray *) editInfos
|
||||
{
|
||||
return _editVariablesList;
|
||||
}
|
||||
|
||||
- (NSInteger) editVariableStackCount
|
||||
{
|
||||
return [_editVariablesStack count];
|
||||
}
|
||||
|
||||
- (NSInteger) topEditVariableStack
|
||||
{
|
||||
return [[_editVariablesStack lastObject] integerValue];
|
||||
}
|
||||
|
||||
- (void) pushEditVariableCount
|
||||
{
|
||||
[_editVariablesStack
|
||||
addObject: [NSNumber numberWithInteger: [_editVariablesList count]]];
|
||||
}
|
||||
|
||||
- (void) popEditVariableStack
|
||||
{
|
||||
[_editVariablesStack removeLastObject];
|
||||
}
|
||||
|
||||
- (void) addEditInfo: (GSCSEditInfo *)editInfo
|
||||
{
|
||||
[_editVariablesMap setObject: editInfo forKey: [editInfo variable]];
|
||||
[_editVariablesList addObject: editInfo];
|
||||
}
|
||||
|
||||
- (void) removeEditInfo: (GSCSEditInfo *)editInfo
|
||||
{
|
||||
[_editVariablesList removeObject: editInfo];
|
||||
}
|
||||
|
||||
- (void) removeEditInfoForConstraint: (GSCSConstraint *)constraint
|
||||
{
|
||||
GSCSEditInfo *editInfo = [self editInfoForConstraint: constraint];
|
||||
[self removeEditInfo: editInfo];
|
||||
}
|
||||
|
||||
- (GSCSEditInfo *) editInfoForConstraint: (GSCSConstraint *)constraint
|
||||
{
|
||||
FOR_IN(GSCSEditInfo *, editInfo, _editVariablesList)
|
||||
if ([editInfo constraint] == constraint)
|
||||
{
|
||||
return editInfo;
|
||||
}
|
||||
END_FOR_IN(_editVariablesList);
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *) editInfosForVariable: (GSCSVariable *)editVariable
|
||||
{
|
||||
NSMutableArray *editInfos = [NSMutableArray array];
|
||||
FOR_IN(GSCSEditInfo *, editInfo, _editVariablesList)
|
||||
if ([editInfo variable] == editVariable)
|
||||
{
|
||||
[editInfos addObject: editInfo];
|
||||
}
|
||||
END_FOR_IN(_editVariablesList);
|
||||
|
||||
return editInfos;
|
||||
}
|
||||
|
||||
- (NSArray *) getNextSet
|
||||
{
|
||||
[_editVariablesStack removeLastObject];
|
||||
NSInteger index = [self topEditVariableStack];
|
||||
NSInteger count = [_editVariablesList count];
|
||||
NSMutableArray *editableInfosInDescendingOrder = [NSMutableArray array];
|
||||
while (count > index)
|
||||
{
|
||||
GSCSEditInfo *editInfo = [[self editInfos] objectAtIndex: count - 1];
|
||||
[editableInfosInDescendingOrder addObject: editInfo];
|
||||
count--;
|
||||
}
|
||||
|
||||
return editableInfosInDescendingOrder;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_editVariablesList);
|
||||
RELEASE(_editVariablesStack);
|
||||
RELEASE(_editVariablesMap);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
|
@ -32,7 +32,8 @@ const float GSCSStrengthWeak = 250;
|
|||
|
||||
- (instancetype) initWithName: (NSString *)name strength: (double)strength;
|
||||
{
|
||||
if (self = [super init])
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
ASSIGN(_name, name);
|
||||
_strength = strength;
|
||||
|
|
147
Source/GSCSTableau.h
Normal file
147
Source/GSCSTableau.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 12-6-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSLinearExpression.h"
|
||||
#import "GSCSVariable.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef _GS_CS_TABLEAU_H
|
||||
#define _GS_CS_TABLEAU_H
|
||||
|
||||
@interface GSCSTableau : NSObject
|
||||
{
|
||||
NSMutableSet *_externalParametricVariables;
|
||||
|
||||
NSMapTable *_rows;
|
||||
|
||||
NSMapTable *_columns;
|
||||
|
||||
NSMapTable *_externalRows;
|
||||
|
||||
NSMutableArray *_infeasibleRows;
|
||||
|
||||
GSCSVariable *_objective;
|
||||
}
|
||||
|
||||
#if GS_HAS_DECLARED_PROPERTIES
|
||||
@property (nonatomic, assign) GSCSVariable *objective;
|
||||
#else
|
||||
- (GSCSVariable *) objective;
|
||||
- (void) setObjective: (GSCSVariable *)objective;
|
||||
#endif
|
||||
|
||||
#if GS_HAS_DECLARED_PROPERTIES
|
||||
@property (nonatomic, assign) NSMapTable *externalRows;
|
||||
#else
|
||||
- (NSMapTable *) externalRows;
|
||||
- (void) setExternalRows: (NSMapTable *)externalRows;
|
||||
#endif
|
||||
|
||||
#if GS_HAS_DECLARED_PROPERTIES
|
||||
@property (nonatomic, assign) NSMutableArray *infeasibleRows;
|
||||
#else
|
||||
- (NSMutableArray *) infeasibleRows;
|
||||
- (void) setInfeasibleRows: (NSMutableArray *)infeasibleRows;
|
||||
#endif
|
||||
|
||||
- (void) addRowForVariable: (GSCSVariable *)variable
|
||||
equalsExpression: (GSCSLinearExpression *)expression;
|
||||
|
||||
- (void) removeRowForVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (BOOL) hasRowForVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) substituteOutVariable: (GSCSVariable *)variable
|
||||
forExpression: (GSCSLinearExpression *)expression;
|
||||
|
||||
- (void) substituteOutTerm: (GSCSVariable *)term
|
||||
withExpression: (GSCSLinearExpression *)newExpression
|
||||
inExpression: (GSCSLinearExpression *)expression
|
||||
subject: (GSCSVariable *)subject;
|
||||
|
||||
- (BOOL) isBasicVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
toExpression: (GSCSLinearExpression *)expression;
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
toExpression: (GSCSLinearExpression *)expression
|
||||
withCoefficient: (CGFloat)coefficient;
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
toExpression: (GSCSLinearExpression *)expression
|
||||
withCoefficient: (CGFloat)coefficient
|
||||
subject: (GSCSVariable *)subject;
|
||||
|
||||
- (void) setVariable: (GSCSVariable *)variable
|
||||
onExpression: (GSCSLinearExpression *)expression
|
||||
withCoefficient: (CGFloat)coefficient;
|
||||
|
||||
- (void) addNewExpression: (GSCSLinearExpression *)newExpression
|
||||
toExpression: (GSCSLinearExpression *)existingExpression
|
||||
n: (CGFloat)n
|
||||
subject: (GSCSVariable *)subject;
|
||||
|
||||
- (void) addNewExpression: (GSCSLinearExpression *)newExpression
|
||||
toExpression: (GSCSLinearExpression *)existingExpression;
|
||||
|
||||
- (void) addMappingFromExpressionVariable: (GSCSVariable *)columnVariable
|
||||
toRowVariable: (GSCSVariable *)rowVariable;
|
||||
|
||||
- (void) removeColumn: (GSCSVariable *)variable;
|
||||
|
||||
- (BOOL) hasColumnForVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (NSSet *) columnForVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (GSCSLinearExpression *) rowExpressionForVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) changeSubjectOnExpression: (GSCSLinearExpression *)expression
|
||||
existingSubject: (GSCSVariable *)existingSubject
|
||||
newSubject: (GSCSVariable *)newSubject;
|
||||
|
||||
- (void) pivotWithEntryVariable: (GSCSVariable *)entryVariable
|
||||
exitVariable: (GSCSVariable *)exitVariable;
|
||||
|
||||
- (BOOL) hasInfeasibleRows;
|
||||
|
||||
- (BOOL) containsExternalParametricVariableForEveryExternalTerm;
|
||||
|
||||
- (BOOL) containsExternalRowForEachExternalRowVariable;
|
||||
|
||||
- (NSArray *) substitedOutNonBasicPivotableVariables:
|
||||
(GSCSVariable *)objective;
|
||||
|
||||
- (GSCSVariable *) findPivotableExitVariable: (GSCSVariable *)entryVariable;
|
||||
|
||||
- (GSCSVariable *)
|
||||
findExitVariableForEquationWhichMinimizesRatioOfRestrictedVariables:
|
||||
(GSCSVariable *)constraintMarkerVariable;
|
||||
|
||||
- (GSCSVariable *) findNonBasicVariables;
|
||||
|
||||
- (GSCSVariable *) findPivotableExitVariableWithoutCheck:
|
||||
(GSCSVariable *)entryVariable;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
693
Source/GSCSTableau.m
Normal file
693
Source/GSCSTableau.m
Normal file
|
@ -0,0 +1,693 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 12-6-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSTableau.h"
|
||||
#import "GSCSFloatComparator.h"
|
||||
#import "GSFastEnumeration.h"
|
||||
|
||||
@interface GSCSTableau (PrivateMethods)
|
||||
|
||||
- (void) recordUpdatedVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) addTermVariablesForExpression: (GSCSLinearExpression *)expression
|
||||
variable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) substituteOutTermInExpression: (GSCSLinearExpression *)expression
|
||||
newExpression:
|
||||
(GSCSLinearExpression *)newExpression
|
||||
subject: (GSCSVariable *)subject
|
||||
term: (GSCSVariable *)term
|
||||
multiplier: (CGFloat)multiplier;
|
||||
|
||||
- (CGFloat) calculateNewCoefficent: (CGFloat)coefficentInExistingExpression
|
||||
coefficentInNewExpression: (CGFloat)coefficentInNewExpression
|
||||
multiplier: (CGFloat)multiplier;
|
||||
|
||||
- (void) removeColumnVariable: (GSCSVariable *)variable
|
||||
subject: (GSCSVariable *)subject;
|
||||
|
||||
- (void) recordUpdatedVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) addNewExpression: (GSCSLinearExpression *)newExpression
|
||||
toExpression: (GSCSLinearExpression *)existingExpression
|
||||
n: (CGFloat)n
|
||||
subject: (GSCSVariable *)subject;
|
||||
|
||||
- (NSString *) columnsDescription;
|
||||
|
||||
- (NSString *) rowsDescription;
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSCSTableau
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
ASSIGN(_rows,
|
||||
[NSMapTable mapTableWithKeyOptions: NSMapTableStrongMemory
|
||||
valueOptions: NSMapTableStrongMemory]);
|
||||
|
||||
ASSIGN(_columns,
|
||||
[NSMapTable mapTableWithKeyOptions: NSMapTableStrongMemory
|
||||
valueOptions: NSMapTableStrongMemory]);
|
||||
|
||||
ASSIGN(_externalParametricVariables, [NSMutableSet set]);
|
||||
|
||||
ASSIGN(_externalRows,
|
||||
[NSMapTable mapTableWithKeyOptions: NSMapTableStrongMemory
|
||||
valueOptions: NSMapTableStrongMemory]);
|
||||
|
||||
ASSIGN(_infeasibleRows, [NSMutableArray array]);
|
||||
|
||||
ASSIGN(_objective, [GSCSVariable objectiveVariableWithName: @"Z"]);
|
||||
|
||||
GSCSLinearExpression *expression = [[GSCSLinearExpression alloc] init];
|
||||
[self addRowForVariable: _objective equalsExpression: expression];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (GSCSVariable *) objective
|
||||
{
|
||||
return _objective;
|
||||
}
|
||||
|
||||
- (void) setObjective: (GSCSVariable *)objective
|
||||
{
|
||||
ASSIGN(_objective, objective);
|
||||
}
|
||||
|
||||
- (NSMapTable *) externalRows
|
||||
{
|
||||
return _externalRows;
|
||||
}
|
||||
|
||||
- (void) setExternalRows: (NSMapTable *)externalRows
|
||||
{
|
||||
ASSIGN(_externalRows, externalRows);
|
||||
}
|
||||
|
||||
- (NSMutableArray *) infeasibleRows
|
||||
{
|
||||
return _infeasibleRows;
|
||||
}
|
||||
|
||||
- (void) setInfeasibleRows: (NSMutableArray *)infeasibleRows
|
||||
{
|
||||
ASSIGN(_infeasibleRows, infeasibleRows);
|
||||
}
|
||||
|
||||
- (BOOL) shouldPreferPivotableVariable: (GSCSVariable *)lhs
|
||||
overPivotableVariable: (GSCSVariable *)rhs
|
||||
{
|
||||
return [lhs id] < [rhs id];
|
||||
}
|
||||
|
||||
- (BOOL) hasColumnForVariable: (GSCSVariable *)variable
|
||||
{
|
||||
return [_columns objectForKey: variable] != nil;
|
||||
}
|
||||
|
||||
- (NSSet *) columnForVariable: (GSCSVariable *)variable
|
||||
{
|
||||
return [_columns objectForKey: variable];
|
||||
}
|
||||
|
||||
// Add v=expr to the tableau, update column cross indices
|
||||
// v becomes a basic variable
|
||||
- (void) addRowForVariable: (GSCSVariable *)variable
|
||||
equalsExpression: (GSCSLinearExpression *)expression
|
||||
{
|
||||
[_rows setObject: expression forKey: variable];
|
||||
if ([variable isExternal])
|
||||
{
|
||||
[_externalRows setObject: expression forKey: variable];
|
||||
}
|
||||
[self addTermVariablesForExpression: expression variable: variable];
|
||||
}
|
||||
|
||||
- (void) addTermVariablesForExpression: (GSCSLinearExpression *)expression
|
||||
variable: (GSCSVariable *)variable
|
||||
{
|
||||
NSArray *termVariables = [expression termVariables];
|
||||
FOR_IN(GSCSVariable *, expressionTermVariable, termVariables)
|
||||
[self addMappingFromExpressionVariable: expressionTermVariable
|
||||
toRowVariable: variable];
|
||||
if ([expressionTermVariable isExternal])
|
||||
{
|
||||
[_externalParametricVariables addObject: expressionTermVariable];
|
||||
}
|
||||
END_FOR_IN(termVariables);
|
||||
}
|
||||
|
||||
- (void) addMappingFromExpressionVariable: (GSCSVariable *)columnVariable
|
||||
toRowVariable: (GSCSVariable *)rowVariable
|
||||
{
|
||||
NSMutableSet *columnSet = [_columns objectForKey: columnVariable];
|
||||
if (columnSet == nil)
|
||||
{
|
||||
columnSet = [NSMutableSet set];
|
||||
[_columns setObject: columnSet forKey: columnVariable];
|
||||
}
|
||||
[columnSet addObject: rowVariable];
|
||||
}
|
||||
|
||||
- (void) removeMappingFromExpressionVariable: (GSCSVariable *)columnVariable
|
||||
toRowVariable: (GSCSVariable *)rowVariable
|
||||
{
|
||||
NSMutableSet *columnSet = [_columns objectForKey: columnVariable];
|
||||
if (columnSet == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
[columnSet removeObject: rowVariable];
|
||||
}
|
||||
|
||||
- (void) removeColumn: (GSCSVariable *)variable
|
||||
{
|
||||
NSSet *crows = [_columns objectForKey: variable];
|
||||
if (_rows != nil)
|
||||
{
|
||||
FOR_IN(GSCSVariable *, clv, crows)
|
||||
GSCSLinearExpression *expression = [_rows objectForKey: clv];
|
||||
[expression removeVariable: variable];
|
||||
END_FOR_IN(crows);
|
||||
[_columns removeObjectForKey: variable];
|
||||
}
|
||||
|
||||
if ([variable isExternal])
|
||||
{
|
||||
[_externalRows removeObjectForKey: variable];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) removeRowForVariable: (GSCSVariable *)variable
|
||||
{
|
||||
GSCSLinearExpression *expression = [_rows objectForKey: variable];
|
||||
if (expression == nil)
|
||||
{
|
||||
NSException *missingExpressionException = [NSException
|
||||
exceptionWithName: NSInvalidArgumentException
|
||||
reason: @"No expression exists for the provided variable"
|
||||
userInfo: nil];
|
||||
[missingExpressionException raise];
|
||||
}
|
||||
[_rows removeObjectForKey: variable];
|
||||
if ([variable isExternal])
|
||||
{
|
||||
[_externalRows removeObjectForKey: variable];
|
||||
}
|
||||
NSArray *expressionTermVariables = [expression termVariables];
|
||||
FOR_IN(GSCSVariable *, expressionTermVariable, expressionTermVariables)
|
||||
[self removeMappingFromExpressionVariable: expressionTermVariable
|
||||
toRowVariable: variable];
|
||||
END_FOR_IN(expressionTermVariables);
|
||||
}
|
||||
|
||||
- (BOOL) hasRowForVariable: (GSCSVariable *)variable
|
||||
{
|
||||
return [_rows objectForKey: variable] != nil;
|
||||
}
|
||||
|
||||
- (void) substituteOutVariable: (GSCSVariable *)variable
|
||||
forExpression: (GSCSLinearExpression *)expression
|
||||
{
|
||||
NSSet *variableSet = [[_columns objectForKey: variable] copy];
|
||||
FOR_IN(GSCSVariable *, columnVariable, variableSet)
|
||||
GSCSLinearExpression *row = [_rows objectForKey: columnVariable];
|
||||
[self substituteOutTerm: variable
|
||||
withExpression: expression
|
||||
inExpression: row
|
||||
subject: columnVariable];
|
||||
if ([columnVariable isRestricted] && [row constant] < 0.0)
|
||||
{
|
||||
[_infeasibleRows addObject: columnVariable];
|
||||
}
|
||||
END_FOR_IN(variableSet);
|
||||
RELEASE(variableSet);
|
||||
|
||||
if ([variable isExternal])
|
||||
{
|
||||
[_externalRows setObject: expression forKey: variable];
|
||||
[_externalParametricVariables removeObject: variable];
|
||||
}
|
||||
[_columns removeObjectForKey: variable];
|
||||
}
|
||||
|
||||
- (void) substituteOutTerm: (GSCSVariable *)term
|
||||
withExpression: (GSCSLinearExpression *)newExpression
|
||||
inExpression: (GSCSLinearExpression *)expression
|
||||
subject: (GSCSVariable *)subject
|
||||
{
|
||||
CGFloat coefficieint = [expression coefficientForTerm: term];
|
||||
[expression removeVariable: term];
|
||||
[expression setConstant: (coefficieint * [newExpression constant]) +
|
||||
[expression constant]];
|
||||
NSArray *termVariables = [expression termVariables];
|
||||
FOR_IN(GSCSVariable *, newExpressionTerm, termVariables)
|
||||
[self substituteOutTermInExpression: expression
|
||||
newExpression: newExpression
|
||||
subject: subject
|
||||
term: newExpressionTerm
|
||||
multiplier: coefficieint];
|
||||
END_FOR_IN(termVariables);
|
||||
}
|
||||
|
||||
- (void) substituteOutTermInExpression: (GSCSLinearExpression *)expression
|
||||
newExpression:
|
||||
(GSCSLinearExpression *)newExpression
|
||||
subject: (GSCSVariable *)subject
|
||||
term: (GSCSVariable *)term
|
||||
multiplier: (CGFloat)multiplier
|
||||
{
|
||||
NSNumber *coefficentInNewExpression =
|
||||
[newExpression multiplierForTerm: term];
|
||||
NSNumber *coefficentInExistingExpression =
|
||||
[expression multiplierForTerm: term];
|
||||
|
||||
if (coefficentInExistingExpression != nil)
|
||||
{
|
||||
CGFloat newCoefficent = [self
|
||||
calculateNewCoefficent: [coefficentInExistingExpression floatValue]
|
||||
coefficentInNewExpression: [coefficentInNewExpression floatValue]
|
||||
multiplier: multiplier];
|
||||
|
||||
if ([GSCSFloatComparator isApproxiatelyZero: newCoefficent])
|
||||
{
|
||||
[expression removeVariable: term];
|
||||
[self removeMappingFromExpressionVariable: term
|
||||
toRowVariable: subject];
|
||||
}
|
||||
else
|
||||
{
|
||||
[expression addVariable: term coefficient: newCoefficent];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CGFloat updatedCoefficent
|
||||
= multiplier * [coefficentInNewExpression floatValue];
|
||||
[expression addVariable: term coefficient: updatedCoefficent];
|
||||
[self addMappingFromExpressionVariable: term toRowVariable: subject];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat) calculateNewCoefficent: (CGFloat)coefficentInExistingExpression
|
||||
coefficentInNewExpression: (CGFloat)coefficentInNewExpression
|
||||
multiplier: (CGFloat)multiplier
|
||||
{
|
||||
return coefficentInExistingExpression + multiplier * coefficentInNewExpression;
|
||||
}
|
||||
|
||||
- (BOOL) isBasicVariable: (GSCSVariable *)variable
|
||||
{
|
||||
return [_rows objectForKey: variable] != nil;
|
||||
}
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
toExpression: (GSCSLinearExpression *)expression
|
||||
{
|
||||
[self addVariable: variable
|
||||
toExpression: expression
|
||||
withCoefficient: 1.0
|
||||
subject: nil];
|
||||
}
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
toExpression: (GSCSLinearExpression *)expression
|
||||
withCoefficient: (CGFloat)coefficient;
|
||||
{
|
||||
[self addVariable: variable
|
||||
toExpression: expression
|
||||
withCoefficient: coefficient
|
||||
subject: nil];
|
||||
}
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
toExpression: (GSCSLinearExpression *)expression
|
||||
withCoefficient: (CGFloat)coefficient
|
||||
subject: (GSCSVariable *)subject
|
||||
{
|
||||
if ([expression isTermForVariable: variable])
|
||||
{
|
||||
CGFloat newCoefficient =
|
||||
[expression coefficientForTerm: variable] + coefficient;
|
||||
if (newCoefficient == 0 ||
|
||||
[GSCSFloatComparator isApproxiatelyZero: newCoefficient])
|
||||
{
|
||||
[expression removeVariable: variable];
|
||||
[self removeColumnVariable: variable subject: subject];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setVariable: variable
|
||||
onExpression: expression
|
||||
withCoefficient: newCoefficient];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (![GSCSFloatComparator isApproxiatelyZero: coefficient])
|
||||
{
|
||||
[self setVariable: variable
|
||||
onExpression: expression
|
||||
withCoefficient: coefficient];
|
||||
if (subject)
|
||||
{
|
||||
[self addMappingFromExpressionVariable: variable
|
||||
toRowVariable: subject];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) removeColumnVariable: (GSCSVariable *)variable
|
||||
subject: (GSCSVariable *)subject
|
||||
{
|
||||
NSMutableSet *column = [_columns objectForKey: variable];
|
||||
if (subject != nil && column != nil)
|
||||
{
|
||||
[column removeObject: subject];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) addNewExpression: (GSCSLinearExpression *)newExpression
|
||||
toExpression: (GSCSLinearExpression *)existingExpression
|
||||
{
|
||||
[self addNewExpression: newExpression
|
||||
toExpression: existingExpression
|
||||
n: 1
|
||||
subject: nil];
|
||||
}
|
||||
|
||||
- (void) addNewExpression: (GSCSLinearExpression *)newExpression
|
||||
toExpression: (GSCSLinearExpression *)existingExpression
|
||||
n: (CGFloat)n
|
||||
subject: (GSCSVariable *)subject
|
||||
{
|
||||
[existingExpression setConstant: [existingExpression constant]
|
||||
+ (n * [newExpression constant])];
|
||||
NSArray *newExpressionTermVariables = [newExpression termVariables];
|
||||
FOR_IN(GSCSVariable *, term, newExpressionTermVariables)
|
||||
CGFloat newCoefficient = [newExpression coefficientForTerm: term] * n;
|
||||
[self addVariable: term
|
||||
toExpression: existingExpression
|
||||
withCoefficient: newCoefficient
|
||||
subject: subject];
|
||||
|
||||
[self recordUpdatedVariable: term];
|
||||
END_FOR_IN(newExpressionTermVariables);
|
||||
}
|
||||
|
||||
- (void) recordUpdatedVariable: (GSCSVariable *)variable
|
||||
{
|
||||
if ([variable isExternal])
|
||||
{
|
||||
[_externalParametricVariables addObject: variable];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setVariable: (GSCSVariable *)variable
|
||||
onExpression: (GSCSLinearExpression *)expression
|
||||
withCoefficient: (CGFloat)coefficient
|
||||
{
|
||||
[expression addVariable: variable coefficient: coefficient];
|
||||
[self recordUpdatedVariable: variable];
|
||||
}
|
||||
|
||||
- (void) changeSubjectOnExpression: (GSCSLinearExpression *)expression
|
||||
existingSubject: (GSCSVariable *)existingSubject
|
||||
newSubject: (GSCSVariable *)newSubject
|
||||
{
|
||||
[self setVariable: existingSubject
|
||||
onExpression: expression
|
||||
withCoefficient: [expression newSubject: newSubject]];
|
||||
}
|
||||
|
||||
- (GSCSLinearExpression *) rowExpressionForVariable: (GSCSVariable *)variable
|
||||
{
|
||||
return [_rows objectForKey: variable];
|
||||
}
|
||||
|
||||
- (void) pivotWithEntryVariable: (GSCSVariable *)entryVariable
|
||||
exitVariable: (GSCSVariable *)exitVariable
|
||||
{
|
||||
// The expression represents the exit variable, which is about to be removed from the basis.
|
||||
// This means that the old tableau should contain the equation: exitVar = expr.
|
||||
GSCSLinearExpression *expression =
|
||||
[self rowExpressionForVariable: exitVariable];
|
||||
[self removeRowForVariable: exitVariable];
|
||||
|
||||
// Calculate an expression for the entry variable.
|
||||
// As "expression" has been removed from the tableau,
|
||||
// we can make destructive modifications to it in order to construct this expression.
|
||||
[self changeSubjectOnExpression: expression
|
||||
existingSubject: exitVariable
|
||||
newSubject: entryVariable];
|
||||
[self substituteOutVariable: entryVariable forExpression: expression];
|
||||
|
||||
if ([entryVariable isExternal])
|
||||
{
|
||||
[_externalParametricVariables removeObject: entryVariable];
|
||||
}
|
||||
|
||||
[self addRowForVariable: entryVariable equalsExpression: expression];
|
||||
}
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
NSMutableString *description =
|
||||
[NSMutableString stringWithString: @"Tableau Information\n"];
|
||||
[description appendFormat: @"Rows: %ld (%ld constraints)\n", [_rows count],
|
||||
[_rows count] - 1];
|
||||
[description appendFormat: @"Columns: %ld\n", [_columns count]];
|
||||
[description appendFormat: @"Infeasible rows: %ld\n", [_infeasibleRows count]];
|
||||
[description
|
||||
appendFormat: @"External basic variables: %ld\n", [_externalRows count]];
|
||||
[description appendFormat: @"External parametric variables: %ld\n\n",
|
||||
[_externalParametricVariables count]];
|
||||
|
||||
[description appendString: @"Columns: \n"];
|
||||
[description appendString: [self columnsDescription]];
|
||||
|
||||
[description appendString: @"\nRows:\n"];
|
||||
[description appendString: [self rowsDescription]];
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
- (NSString *) columnsDescription
|
||||
{
|
||||
NSMutableString *description = [NSMutableString string];
|
||||
FOR_IN(GSCSVariable *, columnVariable, _columns)
|
||||
[description appendFormat: @"%@ : %@", columnVariable,
|
||||
[_columns objectForKey: columnVariable]];
|
||||
END_FOR_IN(_columns);
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
- (NSString *) rowsDescription
|
||||
{
|
||||
NSMutableString *description = [NSMutableString string];
|
||||
FOR_IN(GSCSVariable *, variable, _rows)
|
||||
[description
|
||||
appendFormat: @"%@ : %@\n", variable, [_rows objectForKey: variable]];
|
||||
END_FOR_IN(_rows);
|
||||
return description;
|
||||
}
|
||||
|
||||
- (BOOL) hasInfeasibleRows
|
||||
{
|
||||
return [_infeasibleRows count] > 0;
|
||||
}
|
||||
|
||||
- (BOOL) containsExternalParametricVariableForEveryExternalTerm
|
||||
{
|
||||
FOR_IN(GSCSVariable *, rowVariable, _rows)
|
||||
GSCSLinearExpression *expression = [_rows objectForKey: rowVariable];
|
||||
NSArray *termVariables = [expression termVariables];
|
||||
FOR_IN(GSCSVariable *, variable, termVariables)
|
||||
if ([variable isExternal])
|
||||
{
|
||||
if (![_externalParametricVariables containsObject: variable])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
END_FOR_IN(termVariables);
|
||||
END_FOR_IN(_rows);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) containsExternalRowForEachExternalRowVariable
|
||||
{
|
||||
FOR_IN(GSCSVariable *, rowVariable, _rows)
|
||||
if ([rowVariable isExternal] &&
|
||||
[_externalRows objectForKey: rowVariable] == nil)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
END_FOR_IN(_rows);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray *) substitedOutNonBasicPivotableVariables: (GSCSVariable *)objective
|
||||
{
|
||||
GSCSLinearExpression *objectiveRowExpression =
|
||||
[self rowExpressionForVariable: objective];
|
||||
|
||||
NSMutableArray *substitutedOutVariables = [NSMutableArray array];
|
||||
FOR_IN(GSCSVariable *, columnVariable, _columns)
|
||||
if ([columnVariable isPivotable] && ![self isBasicVariable: columnVariable]
|
||||
&& ![objectiveRowExpression isTermForVariable: columnVariable])
|
||||
{
|
||||
[substitutedOutVariables addObject: columnVariable];
|
||||
}
|
||||
END_FOR_IN(_columns);
|
||||
|
||||
return substitutedOutVariables;
|
||||
}
|
||||
|
||||
- (GSCSVariable *) findPivotableExitVariable: (GSCSVariable *)entryVariable
|
||||
{
|
||||
CGFloat minRatio = DBL_MAX;
|
||||
CGFloat r = 0;
|
||||
GSCSVariable *exitVariable = nil;
|
||||
NSSet *column = [self columnForVariable: entryVariable];
|
||||
FOR_IN(GSCSVariable *, variable, column)
|
||||
if ([variable isPivotable])
|
||||
{
|
||||
GSCSLinearExpression *expression =
|
||||
[self rowExpressionForVariable: variable];
|
||||
CGFloat coefficient = [expression coefficientForTerm: entryVariable];
|
||||
|
||||
if (coefficient < 0)
|
||||
{
|
||||
r = -[expression constant] / coefficient;
|
||||
|
||||
// Bland's anti-cycling rule:
|
||||
// if multiple variables are about the same,
|
||||
// always pick the lowest via some total
|
||||
// ordering -- in this implementation we preferred the variable
|
||||
// created first
|
||||
if (r < minRatio
|
||||
|| ([GSCSFloatComparator isApproxiatelyEqual: r b: minRatio] &&
|
||||
[self shouldPreferPivotableVariable: variable
|
||||
overPivotableVariable: exitVariable]))
|
||||
{
|
||||
minRatio = r;
|
||||
exitVariable = variable;
|
||||
}
|
||||
}
|
||||
}
|
||||
END_FOR_IN(column);
|
||||
|
||||
return exitVariable;
|
||||
}
|
||||
|
||||
- (GSCSVariable *) findPivotableExitVariableWithoutCheck:
|
||||
(GSCSVariable *)entryVariable
|
||||
{
|
||||
CGFloat minRatio = DBL_MAX;
|
||||
CGFloat r = 0;
|
||||
GSCSVariable *exitVariable = nil;
|
||||
NSSet *column = [self columnForVariable: entryVariable];
|
||||
FOR_IN(GSCSVariable *, variable, column)
|
||||
GSCSLinearExpression *expression =
|
||||
[self rowExpressionForVariable: variable];
|
||||
CGFloat coefficient = [expression coefficientForTerm: entryVariable];
|
||||
|
||||
r = -[expression constant] / coefficient;
|
||||
|
||||
// Bland's anti-cycling rule
|
||||
if (r < minRatio
|
||||
|| ([GSCSFloatComparator isApproxiatelyEqual: r b: minRatio] &&
|
||||
[self shouldPreferPivotableVariable: variable
|
||||
overPivotableVariable: exitVariable]))
|
||||
{
|
||||
minRatio = r;
|
||||
exitVariable = variable;
|
||||
}
|
||||
END_FOR_IN(column);
|
||||
|
||||
return exitVariable;
|
||||
}
|
||||
|
||||
- (GSCSVariable *)
|
||||
findExitVariableForEquationWhichMinimizesRatioOfRestrictedVariables:
|
||||
(GSCSVariable *)constraintMarkerVariable
|
||||
{
|
||||
GSCSVariable *exitVariable = nil;
|
||||
CGFloat minRatio = 0;
|
||||
|
||||
NSSet *column = [self columnForVariable: constraintMarkerVariable];
|
||||
FOR_IN(GSCSVariable *, variable, column)
|
||||
if ([variable isRestricted])
|
||||
{
|
||||
GSCSLinearExpression *expression =
|
||||
[self rowExpressionForVariable: variable];
|
||||
CGFloat coefficient =
|
||||
[expression coefficientForTerm: constraintMarkerVariable];
|
||||
CGFloat r = [expression constant] / coefficient;
|
||||
|
||||
if (exitVariable == nil || r < minRatio)
|
||||
{
|
||||
minRatio = r;
|
||||
exitVariable = variable;
|
||||
}
|
||||
}
|
||||
END_FOR_IN(column);
|
||||
|
||||
return exitVariable;
|
||||
}
|
||||
|
||||
- (GSCSVariable *) findNonBasicVariables
|
||||
{
|
||||
FOR_IN(GSCSVariable *, variable, _externalParametricVariables)
|
||||
if (![self isBasicVariable: variable])
|
||||
{
|
||||
return variable;
|
||||
}
|
||||
END_FOR_IN(_externalParametricVariables);
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_rows);
|
||||
RELEASE(_columns);
|
||||
RELEASE(_externalParametricVariables);
|
||||
RELEASE(_externalRows);
|
||||
RELEASE(_infeasibleRows);
|
||||
RELEASE(_objective);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
|
@ -69,6 +69,12 @@ typedef enum GSCSVariableType GSCSVariableType;
|
|||
|
||||
+ (instancetype) variableWithValue: (CGFloat)value name: (NSString *)name;
|
||||
|
||||
+ (instancetype) dummyVariableWithName: (NSString*)name;
|
||||
|
||||
+ (instancetype) slackVariableWithName: (NSString*)name;
|
||||
|
||||
+ (instancetype) objectiveVariableWithName: (NSString*)name;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,11 +24,6 @@
|
|||
|
||||
@implementation GSCSVariable
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
return [self initWithName: nil type: GSCSVaraibleTypeVariable];
|
||||
}
|
||||
|
||||
- (instancetype) initWithName: (NSString *)name
|
||||
{
|
||||
self = [super init];
|
||||
|
@ -53,6 +48,11 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
return [self initWithName: nil type: GSCSVaraibleTypeVariable];
|
||||
}
|
||||
|
||||
+ (instancetype) dummyVariableWithName: (NSString *)name
|
||||
{
|
||||
return AUTORELEASE([[GSCSVariable alloc] initWithName: name type: GSCSVariableTypeDummy]);
|
||||
|
|
Loading…
Reference in a new issue