I am using Google.OrTools version 7.0.
I have built a small interface in order to add constraints to a CpModel:
public interface ISatConstraintWrapper
{
IEnumerable<BoundIntegerExpression> GenerateConstraints();
void BindToModel(CpModel model);
}
The design pattern is fairly simple, here is a dummy example that sets equality to all IntVars in a list:
class MakeAllVarsEqual : ISatConstraintWrapper
{
public MakeAllVarsEqual(List<IntVar> vars)
{
_vars = vars;
}
public IEnumerable<BoundIntegerExpression> GenerateConstraints()
{
for (var i = 0; i < _vars.Count - 1; i++)
{
yield return _vars[i] == _vars[i+1];
}
}
public void BindToModel(CpModel model)
{
foreach (var constraint in GenerateConstraints())
{
model.Add(constraint);
}
}
private readonly List<IntVar> _vars;
}
Next, I would like to use my ISatConstraintWrapper but for minimize/maximize constraints.
Here is an example of what I aim to do:
class MinimizeIntExpression : ISatConstraintWrapper
{
public MinimizeIntExpression(List<IntVar> vars, List<int> coeffs)
{
_vars = vars;
_coeffs = coeffs;
}
public IEnumerable<BoundIntegerExpression> GenerateConstraints()
{
for (var i = 0; i < _vars.Count; i++)
{
yield return _vars[i]*_coeffs[i];
}
}
public void BindToModel(CpModel model)
{
model.Minimize(new SumArray(GenerateConstraints()));
}
private readonly List<IntVar> _vars;
private readonly List<int> _coeffs;
}
But I can't, since _vars[i]*_coeffs[i] returns an IntegerExpression but not a BoundIntegerExpression.
However, even if the latter represents an IntegerExpression in a domain, those two classes seems unrelated and I didn't find a way to downcast a BoundIntegerExpression to an IntegerExpression.
Of course I could make two different interfaces but it wouldn't come as handy, for instance if I want to store my constraint wrappers in a list.
Is it possible to convert a BoundIntegerExpression to an IntegerExpression? If not, how could I modify my wrapper to handle both types of constraints?
You cannot.
I suggest you read:
https://github.com/google/or-tools/blob/stable/ortools/sat/doc/channeling.md
Related
I have interface that defines value and few operations:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
Then i implement class based on that interface
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
Now i want to make universal manipulator that operates on pool of values and uses generics (so i only write it once). Because of the way i want to use this class in the future it cannot be declared static. Moving generic type into methods also doesn't do any good.
The closest i could get is:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
Main problem with this ValueManipulator class is that i need to know T of IValue used in DoubleValue (in this case double). So it looks like this:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
How do i make ValueManipulator so user does not need to know what type was used in value implementation?
Well, if your ValueManipulator<T> has no state, as appears to be your case according to your code snippets, then simply make the methods generic instead of the class, that way you can leverage type inference.
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
Now you can simply do:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
If this is a valid solution then consider making ValueManipulator a static class:
ValueManipulator.Manipulate(ProvideDoubles());
P.D. Please follow advice in commentaries and change ValueType to some other name thats less confusing.
UPDATE After your latest edit to your question, where you clearly state that ValueManipulator<T> does have state, the solution seems to be implementing a static factory class:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
And again you let type inference do its job:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());
I have never programmed in C# in my life but i understand java well enough. I am running this program and everytime it keeps saying count/IEnumerator has not been implemented. I have tried various different ways and have put it in various different locations in file. I understand that this will be an extremely easy thing to do but I don't understand it. I also presume these are some sort of methods so don't ask why they are sitting where the instance variables are.
Can someone explain to me how to use collections? The collection being used here is ireadonlycollection which is implemented by IPackOfCards that is implemented in this class.
Are C# interfaces allowed to have implementation in them?
using System;
using CodedTests.NUnit;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace CodedTests.NUnit
{
public class PackOfCards : IPackOfCards
{
private const int NUMCARDS = 52;
private int cardsInPack;
//private Card[] cards;
private Collection<ICard> pack = new Collection<ICard>();
int Count { get; }
public IEnumerator<ICard> GetEnumerator(){return pack.GetEnumerator();}
//IEnumerator IEnumerable.GetEnumerator(){ return GetEnumerator();}
public Collection<ICard> Create()
{
cards = new Card [NUMCARDS];
String [] values = {"Ace","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King"};
String [] suits = {"Hearts", "Diamonds", "Spades", "Clubs"};
int cardsInPack = 0;
for(int i = 0 ; i<suits.Length; i++){
for(int j = 0; j<values.Length; j++, cardsInPack++){
cards[cardsInPack]= new Card(values[j], suits[i]);
}
}
return new pack;
}
public void Shuffle(){
Random num = new Random();
for(int i = 0; i<NUMCARDS;i++){
int ran = num.Next(NUMCARDS);
Card temp = cards[ran];
cards[ran] = cards[i];
cards[i] = temp;
}
}
public ICard TakeCardFromTopOfPack (){
int topCard = 0;
ICard cardRemoved = cards[topCard];
for(int i = 0;i<NUMCARDS-1;i++){
cards[i]=cards[i+1];
}
cards[cardsInPack] = null;
cardsInPack--;
return cardRemoved;
}
}
}
public class Card : ICard
{
private String value;
private String suit;
public Card(String v, String s)
{
value = v;
suit = s;
}
public String getValue(){
return value;
}
public String getSuit(){
return suit;
}
public String toString(){
return value+" of "+suit;
}
}
}
public interface IPackOfCards : IReadOnlyCollection<ICard>
{
void Shuffle ();
ICard TakeCardFromTopOfPack ();
}
public interface IPackOfCardsCreator
{
IPackOfCards Create ();
}
public class PackOfCardsCreator : IPackOfCardsCreator
{
public IPackOfCards Create()
IPackOfCards implements IReadOnlyCollection. That means you have to implement all members of IReadOnlyCollection in addition to members of IPackOfCards, namely a Count property and a GetEnumerator method, as documented here. All interface members have to be public, but your Count property is private. You didn't specify its accessibility, so it's defaulted to private.
How to define generic class for mapping muti-class?
I asked the question before,but i want like this
public class BaseRepositoryService<T1,T2,T3...Tn> where T:class
{
maplestory2Context mc = new maplestory2Context();
public T AddEntity(params object [] args)
{
for (int i = 0; i < args.Length; i++)
{
object obj = args[i];
}
}
}
but i am not sure the how many params I would use. thanks.
note:i changed my code below,but it is not convenience.
public class BaseRepositoryService<T> where T:class
{
maplestory2Context mc = new maplestory2Context();
public T AddEntity(T entity,int size)
{
if (size == 2)
{
}
return null;
}
}
public class BaseRepositoryService<T,T2>
where T : class
where T2:class
{
maplestory2Context mc = new maplestory2Context();
public T AddEntity(T entity, int size)
{
if (size == 2)
{
}
return null;
}
}
Answer to this question is you can't.
You need to define n no of classes for that even Microsoft has defined Func delegates 15 or 16 times. You can refer to msdn documentation for confirmation.
If you don't want write those classes manually you may opt for t4 templates as code generator.
I would like to be able to present a choice to the user - whether to use 16bit indices (in OpenGL) or 32bit indices. In C++, I'd probably just create an alias for int or short, but I don't seem to have the option in C#. Basically what I'm going for can be summed up in the class below:
using System;
namespace Something
{
public class Conditional
{
public Conditional(Boolean is16Bit)
{
if (is16Bit)
{
SOMETYPE is Int16
}
else
{
SOMETYPE is Int32
}
}
private List<SOMETYPE> _something;
}
}
The aliasing (if it can be done) would be vastly better - I just don't want to force anyone using this code into writing #define statements, is that possible?
Thanks
Seems like you could use a generic for this:
namespace Something
{
public class Conditional<T>
{
private List<T> _something = new List<T>();
private Conditional()
{
// prevents instantiation except through Create method
}
public Conditional<T> Create()
{
// here check if T is int or short
// if it's not, then throw an exception
return new Conditional<T>();
}
}
}
And to create one:
if (is16Bit)
return Conditional<short>.Create();
else
return Conditional<int>.Create();
You can use an interface and a factory, something like this:
public interface IConditional
{
void AddIndex(int i);
}
private class Conditional16 : IConditional
{
List<Int16> _list = new List<Int16>();
public void AddIndex(int i)
{
_list.Add((short)i);
}
}
private class Conditional32 : IConditional
{
List<Int32> _list = new List<Int32>();
public void AddIndex(int i)
{
_list.Add(i);
}
}
public static class ConditionalFactory
{
public static IConditional Create(bool is16Bit)
{
if (is16Bit)
{
return new Conditional16();
}
else
{
return new Conditional32();
}
}
}
Your code (and callers of it) can do everything against IConditional without caring which of the concrete representations it is.
I have a class defined with a generic:
public class GenericDataStore<T>
{
// UnderlyingDataStore is another class that manages a queue, or a linked list
private UnderlyingDataStore<T> dataQueue = new UnderlyingDataStore<T>();
public void addData(T data) { dataQueue.Add(data); }
public T getLastData() { dataQueue.getLastData(); }
}
I then have different derived classes based on this class:
public class ByteDataStore : GenericDataStore<Byte>
{
}
public class DoubleDataStore : GenericDataStore<Double>
{
}
public class PObjDataStore : GenericDataStore<PObj> // PObj is another class declared somewhere
{
}
Then, I have a "Manager" class that looks like:
public class DataManager
{
/* Here, I want to declare a 2 dim array [,] that holds pointers to the
data stores. Depending on some other variables, the array may need
to point to DoubleDataStore, ByteDataStore, etc. The following doesn't work,
since GenericDataStore must be declared with a generic type: */
GenericDataStore [,] ManagedDataStores; // Can not compile
public DataManager() {
for (int i=0; i<numStores; i++) {
for (int j=0; j<numCopies; j++) {
// objType is a utility function that we have that returns a type
if (objType(i,j) == typeof(Byte)) {
ManagedDataStores[i,j] = new ByteDataStore();
} else if (objType(i,j) == typeof(double)) {
ManagedDataStores[i,j] = new DoubleDataStore();
}
}
}
}
void Add(int id, int copyid, Byte data) {
ManagedDataStores[i,j].Add(data);
}
}
There might be other, better ways to do this. Essentially, we want to have different data stores for different object types, which can be managed by a class. We want only this 'manager' class to be exposed to the user (like an API), and no direct access to the underlying classes.
Thanks in advance.
I'm afraid that this is one of those instances where Generic's don't help you one bit. By definition, you must know the generic type at compile time, rather than runtime. For runtime type-indiference, you need to do it the old-fashioned way.
public class DataStore
{
// UnderlyingDataStore is another class that manages a queue, or a linked list
private UnderlyingDataStore dataQueue = new UnderlyingDataStore();
public void addData(object data) { dataQueue.Add(data); }
public object getLastData() { dataQueue.getLastData(); }
}
This, has the obvious drawback of boxing/unboxing- as well as the need for calling-code to know what type's it should be dealing with in order to cast.
However, you could also use the other answer, as long as you're able to cast the managedDataStore to the correct generic type.
If you want to create and initialize the double dimensional array use this:
int numStores = 2;
int numCopies = 3;
//GenericDataStore<object>[,] managedDataStores = new GenericDataStore<object>[numStores,numCopies];
Object[,] managedDataStores = new Object[numStores,numCopies];
for (int i = 0; i < numStores; i++)
{
for (int j = 0; j < numCopies; j++)
{
managedDataStores[i,j] = new GenericDataStore<object>();
}
}
I would add an interface and implement it explicitly to hide it from the class users:
internal interface GeneralDataStore
{
void addData(object data);
object getLastData();
}
public class GenericDataStore<T> : GeneralDataStore
{
// UnderlyingDataStore is another class that manages a queue, or a linked list
private UnderlyingDataStore<T> dataQueue = new UnderlyingDataStore<T>();
public void addData(T data) { dataQueue.Add(data); }
public T getLastData() { dataQueue.getLastData(); }
object GeneralDataStore.getLastData() { return getLastData(); }
void GeneralDataStore.addData(object data) { add((T)data); }
}
GeneralDataStore [,] ManagedDataStores;
This doesn't give you what you want, since it's impossible. But it give you some type safety.