Не видя ошибки, я могу быть уверен на 100%, но я думаю, что имя, которое вы включаете в lpsum, вызывает проблему, попробуйте следующее
alloc_prob = pulp.LpProblem("Supplier Allocation Problem", pulp.LpMinimize)
TPC_func = pulp.lpSum(X[s][p]*procCosts[s][p] for s in supplier for p in
project)
TTC_func = pulp.lpSum(X[s][p]*transCosts[s][p] for s in supplier for p in
project)
TD_func = pulp.lpSum(X_SEP[c][1]*discountFactor['Bonus / ton [€/t]'][c] for
c in company)
# Objective function: TPC + TTC - TD -> min
alloc_prob += TPC_func + TTC_func - TD_func
В то время как Predicate
был представлен в то же самое время, когда List<T>
и Array<T>
, в .net 2.0, различное Func
и Action
варианты прибывают из .net 3.5.
Так они Func
предикаты используются главным образом для непротиворечивости в операторах LINQ. С .net 3.5, об использовании Func<T>
и Action<T>
состояния инструкции :
Действительно используют новые типы
Func<>
иExpression<>
LINQ вместо пользовательских делегатов и предикатов
Я задался вопросом это прежде. Мне нравится эти Predicate<T>
делегат - это является хорошим и описательным. Однако необходимо рассмотреть перегрузки Where
:
Where<T>(IEnumerable<T>, Func<T, bool>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)
, Который позволяет Вам фильтровать на основе индекса записи также. Это хорошо и последовательно, тогда как:
Where<T>(IEnumerable<T>, Predicate<T>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)
не был бы.
Конечно, истинная причина для использования Func
вместо определенного делегата - то, что C# рассматривает отдельно заявленных делегатов как полностью различные типы.
Даже при том, что Func<int, bool>
и Predicate<int>
и имеют идентичный аргумент и типы возврата, они не совместимы с присвоением. Таким образом, если бы каждая библиотека объявила свой собственный тип делегата для каждого шаблона делегата, то те библиотеки не были бы в состоянии взаимодействовать, если пользователь не вводит "образующих мост" делегатов для выполнения преобразований.
// declare two delegate types, completely identical but different names:
public delegate void ExceptionHandler1(Exception x);
public delegate void ExceptionHandler2(Exception x);
// a method that is compatible with either of them:
public static void MyExceptionHandler(Exception x)
{
Console.WriteLine(x.Message);
}
static void Main(string[] args)
{
// can assign any method having the right pattern
ExceptionHandler1 x1 = MyExceptionHandler;
// and yet cannot assign a delegate with identical declaration!
ExceptionHandler2 x2 = x1; // error at compile time
}
, поощряя всех использовать Func, Microsoft надеется, что это облегчит проблему несовместимых типов делегата. Общие делегаты будут играть приятно вместе, потому что они просто подойдутся на основе их типов параметра/возврата.
Это не решает все проблемы, потому что Func
(и Action
) не может иметь out
или ref
параметры, но они реже используются.
Обновление: в комментариях Svish заявляет:
однако, переключая тип параметра от Func до Предиката и назад, кажется, не имеет значения? По крайней мере, это все еще компилирует без любых проблем.
Да, пока Ваша программа только присваивает методы делегатам, как в первой строке моего Main
функция. Компилятор тихо генерирует код к новому, делегат возражает что вперед на методе. Таким образом в моем Main
функция, я мог измениться x1
, чтобы быть типа ExceptionHandler2
, не вызывая проблему.
Однако на второй строке я пытаюсь присвоить первого делегата в другом делегате. Даже мысль, что 2-й тип делегата имеет точно тот же параметр и типы возврата, компилятор, дает ошибку CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'
.
, Возможно, это сделает это более ясным:
public static bool IsNegative(int x)
{
return x < 0;
}
static void Main(string[] args)
{
Predicate<int> p = IsNegative;
Func<int, bool> f = IsNegative;
p = f; // Not allowed
}
Мой метод IsNegative
является совершенно хорошей вещью присвоить p
и f
переменные, пока я делаю так непосредственно. Но тогда я не могу присвоить одну из тех переменных к другому.
Совет (в 3,5 и выше) состоит в том, чтобы использовать Action<...>
и Func<...>
- для "почему?" - одно преимущество состоит в том, что" Predicate<T>
" только значимо, если Вы знаете то, что означает "предикат" - иначе необходимо посмотреть на обозреватель объектов (и т.д.) для нахождения signatute.
С другой стороны Func<T,bool>
следует за стандартным шаблоном; я могу сразу сказать, что это - функция, которая берет T
и возвращается bool
- не должны понимать, что любая терминология - просто применяет мой тест истины.
Для "предиката" это, возможно, было в порядке, но я ценю попытку стандартизировать. Это также позволяет большую четность со связанными методами в той области.